Last updated on: September 6, 2020
Adopting third-party libraries to encode user input in the development phase and using a web application firewall in the deployment phase could fool web security managers into thinking their web applications are completely safe from Cross-Site Scripting (XSS) attacks. While it’s a good idea to employ these techniques, the illusion of safety could prove costly. These protection methods do not guarantee that your web applications are 100% free of XSS vulnerabilities, and XSS attacks that use more sophisticated techniques still occur, so care should still be taken.
As I have observed from my work experience and as a bug bounty hunter, XSS vulnerabilities are definitely not going away — and many attacks are getting more sophisticated. The golden age of penetration testing, when pen testers could discover XSS vulnerabilities simply by inputting malicious code into a search box, is over. It often takes more skill and effort for webmasters to discover the XSS vulnerabilities they need to protect against.
XSS Hidden by Web Application Firewalls
Web application firewalls (WAFs) are commonly used to protect web applications. They are indeed effective in blocking a large number of web attacks. Some pen testers give up immediately when they determine the web application is deployed behind a web application firewall. However, a WAF is just like a cast that by itself does not fix the broken limb. And like a cast, a WAF is best used as a temporary protection until the underlying issue, in this case a coding error, is fixed and redeployed.
Instead of fixing the issue, WAFs just hide XSS vulnerabilities and makes it harder for attackers to exploit them, which is their purpose; but WAFs also makes it more difficult for penetration testers or automatic scanners to discover these vulnerabilities. According to the research, over 70% of existing WAF rulesets can be bypassed through XSS obfuscation techniques. As a rule-based tool, WAFs trap the main cases for which rules are defined, but not all of the corner cases — the development effort spent to make the perfect ruleset would be better spent fixing the underlying coding error.
Recommendation: When running a security audit, e.g. via automated tools or penetration tests, always disable your WAF so that the XSS vulnerabilities can be discovered to the greatest extent. You want to make it easy on yourself to find XSS vulnerabilities, so you can fix them in your code.
In my work, I have seen many examples where customers claimed that Qualys Web Application Scanning (WAS) had generated false positives, when in fact they were true positives but the customer didn’t see the exploit because they were protected by a WAF. In these cases, I could often exploit the XSS anyway by coding exploits that bypassed the WAF protection.
Example: Methods to bypass WAF could be found on the Internet: Using escape sequences (%00onload%00=%00) instead of regular text; or an alternative XSS method, such as, payload document.body.outerHTML=maliciouscodes could be used to break some WAFs.
More Sophisticated XSS Attacks
Three types of sophisticated XSS attacks are difficult for pen testers and tools to discover. It is not easy to propose new techniques to combat these, except enhancing security implementation during web development and employing a DAST (dynamic application security testing) tool for regular security audits to make sure you catch any that were inadvertently included in your code.
Example: Here is the normal format of a DOM-based XSS attack vector
Multiple Step XSS
Example: Qualys WAS reported a XSS vulnerability in a customer’s application. The customer’s security team claimed they could not find the injection point and wanted to flag it as a false positive. After investigation, we found the injection point was from a different subdomain and the malicious code was invoked by making a search with a keyword matching with the malicious code injected in the response.
Targets for Path-Based XSS attacks are applications where the request URLs are rendered directly in the response body without proper encoding or input validation. The following source code snippet is a model demonstrating how path-based XSS vulnerabilities reside in your web applications.
<a href=" <?php echo $_SERVER['REQUEST_URI'];?>">Click Here</a>
While WAFs are a great protection measure against attacks on vulnerabilities resulting from coding errors that you have not yet fixed and deployed, you should always disable WAFs for internal testing. This helps ensure you don’t inadvertently overlook any simple XSS vulnerabilities in your code. It’s always safer to fix the underlying vulnerability than to rely on a WAF for long-term protection.
In addition, developers should take care in their coding to look for the more subtle XSS vulnerabilities, since we are regularly finding attacks that try to exploit these.