I’ve made a bit of a bad habit of looking for / finding security bugs in other people’s software. The things I start with before looking through requests and front-end code in more detail I’ve distilled down to a few algorithmic bits of grepping and analysis based on a few simple rules.
- Consider all user-input dirty – this doesn’t just include in form fields, but:
- Any previously saved data loading back from your server;
- Data that may be sent to your server even if it’s invalid;
- Any communication between frames.
- If it’s not over HTTPS, even if you’re getting data from your own service, it could be dirty.
- Even if it’s over HTTPS, trust no-one to do the right thing.
And all these rules basically come down to one: sanitize everything.
- $.html(foo), $(foo);: you almost never want to use this except for hard-coded values. If an API is returning HTML for your front-end to use it’s doing it wrong. Construct it yourself out of the other fields when possible.
- $.html(‘<a href=”/?foo=’ + myVar + ‘”>Link</a>’);
- $(‘<div class=”‘ + myVar + ‘”>’);
- All of the above apply to a number of jQuery methods that construct HTML including append, insertBefore, $ itself and many others.
- When using Backbone or similar, consider that someone may abuse your routing by sending users to a URL which routes to a view with side-effects. Views with side-effects should either not have routes, or should not be available to route to on initialization.
- Window.postMessage / onmessage: if your site can be framed by others (no X-Frame-Options protection) or itself contains frames, any messages passed by other frames should be untrusted. What’s more, any data posted to other frames should be protected with a targetOrigin parameter.
Things to watch out for in application design:
- Ensure your app URLs do not include sensitive data which may be passed to other sites by the Referer [sic] header. This is preferable to relying on browsers respecting rel=”noreferrer”
- Make sure all requests with side-effects don’t just include, but require a CSRF token either in the request data or as a request header. Cookies do not count.
- Avoid JSONP when designing APIs.
Ways to safely incorporate user data in the DOM:
- For parameters or paths in links: $.html(‘<a href=”/?foo=’ + encodeURIComponent(myVar) + ‘”>Link</a>’);.
- For domains in links where user data will be sent, whitelist the domains.
. Do not construct HTML by just concatenating strings.
var $tmp = $('<div>');
These are just a few quick things to look out for – this isn’t a black and white checklist, some of these things are safe in the right circumstances. And if you want to find more perverse flaws, more detailed analysis of the code is needed.