Cross-Site Scripting (XSS)
Bare Minimum Application Security04 January 2013
In Part 1 of this series I began by explaining the background to the series, my aims and goals in producing this, and kicked things off with some core concepts. Here on out, we’ll focus on specific threats for the next few posts.
XSS - Cross-Site Scripting
Consider this superbly designed, aesthetically pleasing page on your site:
Being all lean and data-driven, we’re doing some A|B testing. Imagine, for the
sake of simplicity, that
window.isTest is being set by whatever A|B testing
solution we are using, and that the
_gaq array is from the Google Analytics
tracking code. We’ve got a feeling that attractive links are the way forward
for driving user engagement, so we’re testing that by writing an attractive link
to the page for users in our test group.
We want to track how many people click on this attractive link we’ve set up. We are going to put it on a few pages to determine where it performs best, so our final value sent to the Google Analytics event tracking array here is the page URL.
We like using templates to avoid shared code, so we use window.location.href to populate the page URL easily. Great! Check out our efficiency.
When a user visits our homepage, on which we have placed this code:
We see this behavior when the user clicks the attractive link:
However, we have a problem. window.location.href contains whatever is in the browser’s address bar - which is editable by the user directly and via a link in an email, Facebook message, etc. Uh oh!
Imagine a l33t hacker targets your site (for this, and future examples, we’re imagining our new start up Insta-SPAM, which pulls photos of food from Instagram’s API and overlays a picture of a can of SPAM on the food item - it’s going to be massive) and sends an email to a bunch of people linking to:
This causes the
gaq.push() argument to be:
Why you should care
How to detect if someone is trying to attack you
It’s important to understand that there are two distinct types of XSS - reflected and stored.
A reflected XSS vulnerability is one that can be triggered with access to the victim - a vulnerability that exploits unescaped use of location.href, or of a URL parameter, for example - that the attacker must get in front of the victim.
So, detecting these attacks is done in one of two ways.
To detect reflected XSS attacks/attempts, check your access logs often. Automate this looking for strange patterns (you know your app inside out - alert on URL patterns that don’t fit your design). A quick and dirty solution that gets the job done is achievable in an hour or two. Contact me if you want my help in creating one.
Before long, you’ll likely be monitoring failing URLs for operational reasons anyway - oftentimes XSS attempts will crop up in the list of URLs that tripped up.
For stored XSS attacks/attempts, you can detect at multiple layers of your stack: periodically querying your data store for fields that accept user modifiable input, logging any matched patterns on the way out in your view logic, or on the controller that processes incoming form data.
Why bother detecting attacks if we’re validating, sanitizing and escaping? Good question, I’m glad you asked. Taking measures to detect attacks puts you ahead of the game:
- You may detect something that your validation/sanitization/escaping efforts will not catch, allowing you to improve them proactively.
- Being aware of failed attack attempts allows you to be braced for further attacks, determine attack sources and enlist further help when needed to ensure any follow up attack(s) are not successful.
Non-security benefits of protecting yourself from this threat
I like to tell developers that taking the time to stay abreast of security best practices benefits them beyond the scope of being secure. I figured I should back up that bold statement with examples.
By validating all data input in your app, you become acutely aware of the data types you’re using. That will at the very least give you a better understanding of your app and the ability to better design data structures, and may even extend you opportunities to identify inefficiencies in your tech stack, which you can then address.
End of Part 2
So, that’s XSS in a nutshell and a few ways to protect yourself. In Part 3, we’ll look at Cross-Site Request Forgery (CSRF).
And, as a reminder - I will continue to repeat a disclaimer throughout: This is a barebones, do this rather than do nothing set of suggested approaches. THIS DOES NOT CONSTITUTE ROBUST, COMPLETE AND FOOLPROOF SECURITY. The goal of this effort is to provide non-security aware founders/hackers/developers/etc with a modicum of protection at a stage in the company’s growth where there are no budgets, let alone one for Information Security. The caveat is that as soon as the company experiences growth, one of their top priorities should be to mature in to a properly developed, professionally and thoroughly provisioned Information Security program, specific to their application, industry and environment.
Just as you scaffold certain items while doing rapid coding development, this is your scaffolded application security program. Think of it as the Twitter Bootstrap of web application security.
Your Feedback / Dissent
In creating this, my aim is to improve Application Security in the early stage companies that will often consider the topic "something we'll get to when we scale". As such, critiques, comments, dissenting opinions and any other type of feedback is welcomed and indeed, heartily encouraged.
Constructive feedback will be reflected in the posts themselves at the most relevant points.
If you've got feedback for me, or you have questions about how to apply this to your own startup / project, you can get in touch:
Email: [email protected]