2017 OWASP Top 10 for PHP Developers Part 7: Cross-Site Scripting (XSS)
We have all seen search forms, haven’t we? Take a look at mine:
The above search form is pretty basic – when a search query is provided, the page will respond with “You’ve searched for …” and display the results.
This search form does not have anything unusual compared to the other search forms out there – except that it does not sanitize the input..
What happened here is we have entered a different search term. Here’s what was provided:
<script>alert(“2017 OWASP Top 10 for PHP Developers Part 7: Cross-Site Scripting (XSS)”);</script>
Because we did not sanitize the input, the browser thought that the code was a part of a web application and executed it. If you have a website that contains an input field (the input field does not necessarily have to be a search form), provide a basic payload (such as the one above) and see an alert box, be afraid, be very afraid – it means that your website is vulnerable to a vulnerability known as Cross-Site Scripting (XSS).
Cross-Site Scripting was almost always included in the OWASP list: in 2017 though, it was much further down the list than in previous OWASP releases – the 2010 release labeled XSS as the number two risk, three years after, XSS was number three. In the 2017 list, XSS occupied the seventh place. That means developers are better equipped at mitigating this flaw. That’s great news! However, such a risk is still very prevalent and serious, so let’s dive into it.
What is Cross-Site Scripting?
Cross-Site Scripting (XSS) is such a vulnerability that could allow an attacker to insert malicious client-side scripts into a web application. Here’s how XSS is defined by OWASP:
|Threat Agents / Attack Vectors||Security Weakness||Impacts|
|App Specific||Exploitability: 3
|Automated tools can detect and exploit all three forms of XSS, and there are freely available exploitation frameworks.||XSS is the second most prevalent issue in the OWASP Top 10, and is found in around two thirds of all applications.
Automated tools can find some XSS problems automatically, particularly in mature technologies such as PHP, J2EE / JSP, and ASP.NET.
|The impact of XSS is moderate for reflected and DOM XSS, and severe for stored XSS, with remote code execution on the victim’s browser, such as stealing credentials, sessions, or delivering malware to the victim.|
Is it really that bad?
Imagine a search form does not validate the input and upon search, a parameter called “query” is displayed in the URL. A potential attacker wants to redirect users to a malicious website. What are his options?
Then, upon creating such a payload, a nefarious party could provide the victim a URL that looks like this:
Mitigating Cross-Site Scripting
Have a look at the source code of my search form:
In this particular case, the vulnerability resides at the 27th line: when a button called “SearchButton” is clicked, the search query is printed to the screen. No validations, nothing. This means that we can also perform HTML injection (HTMLi) by searching for a query like so:
By exploiting HTML injection, an attacker could modify page content seen by a user.
Remember how I said that my search form does not sanitize the input then popped an alert box to demonstrate the flaw? I did this because both Cross-Site Scripting (XSS) and HTML Injection (HTMLi) are made possible when a developer fails to validate the input – such flaws exploit the trust a user has for a website. Validating user input is called sanitization and there are all kinds of sanitization techniques available for PHP alone, but I will only cover the techniques that have to do with mitigating the two vulnerabilities in question.
Both Cross-Site Scripting and HTML Injection can be mitigated by validating all untrusted input against a whitelist of allowed values or by utilizing built-in functions provided by PHP. Whitelist input validation is easy – make a list of allowed values and block all values that are not in the list. I mitigated Cross-Site Scripting a bit differently though – have a look:
This time, arbitrary code did not execute because I made a small change to the code – I used an internal function to get rid of XSS. Take a look at line 26: a function called htmlentities was used. Provided such a function is used, all characters that have an HTML entity equivalent will be encoded. In this case, both “<” and “>” characters were converted to their equivalents in HTML entities: “<” (less than) and “>” (greater than). Cross-Site Scripting can also be mitigated by using a function called htmlspecialchars, but it only encodes a small amount of HTML characters, while htmlentities encodes all of them.
Cross-Site Scripting is such a vulnerability that can be easily introduced into a web application. The ramifications of such a vulnerability being exploited could involve users being infected with malware, redirected to malicious websites or having their cookies stolen. With that being said, such a flaw is easy to prevent too – for more insights on how XSS vulnerabilities should be tackled, check the OWASP XSS (Cross-Site Scripting) Prevention Cheat Sheet.