XSS is the most common publicly reported security vulnerability, and part of every hacker’s toolkit.
DOM-based XSS attacks have all the risks associated with the other types of XSS attack, with the added bonus that they are impossible to detect from the server side. Any page that uses URI fragments is potentially at risk from XSS attacks.
Frameworks like Ember, AngularJS and React use templates that makes construction of ad-hoc HTML an explicit (and rare) action. This will push your development team towards best practices, and make unsafe operations easier to detect.
Audit Your Code Carefully
In that case, you will need to regularly conduct code reviews to spot locations
window.location.hash. Consider coming up with agreed coding
standards on how URI fragments are to be written and interpreted, and centralize
this logic in a core library.
If you use JQuery, carefully check any code that uses the
html(...) function. If you are
constructing raw HTML on the client-side on the back of untrusted input, you may
have a problem, whether the input comes from a URI fragment or not. Use the
text(...) function whenever possible.
If you are using direct the native DOM APIs, avoid using the following properties and functions:
Instead, set text content within tags wherever possible:
Parse JSON Carefully
for example, by using the
eval(...) function. Instead use
Detect Unsafe Code Using Development Tools
Google has released a Chrome plug-in that can identify insecure practices commonly found in client-side code.
Don’t Use URI Fragments At All!
The most secure code is the code that isn’t there. If you don’t need to use URI
window.location.hash, and have it fail if the pattern is found. When there is
a need to use URI fragments, then you can discuss how to ensure their safe use.
Implement a Content-Security Policy
Modern browsers support Content-Security Policies
can be loaded and executed from. XSS attacks rely on the attacker being
able to run malicious scripts on a user’s web page - either by
<script> tags somewhere within the
<html> tag of a
malicious third-party domain.
|Content-Security-Policy: script-src 'self' https://apis.google.com|
The content security policy can also be set in a
<meta> tag in the
element of the page:
<meta http-equiv="Content-Security-Policy" content="script-src 'self' https://apis.google.com">
This approach will protect your users very effectively! However, it may take a considerable amount of discipline to make your site ready for such a header. Inline scripts tags are considered bad practice in modern web-development - mixing content and code makes web-applications difficult to maintain - but are common in older, legacy sites.
To migrate away from inline scripts incrementally, consider makings use of
CSP Violation Reports.
By adding a
report-uri directive in your policy header, the browser will
|Content-Security-Policy-Report-Only: script-src 'self'; report-uri http://example.com/csr-reports|
This will give you reassurance that there are no lingering inline scripts, before you ban them outright.