Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restrict Javascript execution via HTTP header

I want to restrict the execution of Javascript on my website to prevent the execution of malicious code in the browser. Presuming, my HTML website is accessible via the URI http://a.com/, I want to make sure that only the script in http://a.com/script.js is executed by the browser. The browser should NOT:

  • execute other scripts, even if they are referenced in the HTML code via a <script> tag
  • execute any Javascript code that is embedded in the HTML file

Is there a way to realize that? Google didn't really help me out.

My preferred solution is via an HTTP header, similar to the one for Cross-origin resource sharing, but I am also happy about other suggestions.

like image 501
Stefan Dollase Avatar asked Mar 22 '15 22:03

Stefan Dollase


2 Answers

Contrary to what the commentaries above say, this is a valid concern. The vulnerability is cross-site scripting (XSS), and it's potentially present any time a site allows users to upload content. Even, for example, comments :)

The traditional way to protect against XSS is by sanitizing all user-supplied input, but that can be tedious and error-prone. The HTTP header that is designed to prevent XSS is Content Security Policy. The major problem with relying strictly on CSP for XSS protection is that Internet Explorer (even version 11) does not support any version of the CSP header (unless that's changed since the last time I checked).

So, for today, CSP is a good practice to enable on your server if you can, but you'll still have to sanitize inputs to deal with IE users (or users with really old browsers). Also, keep in mind that CSP (in the strictest implementation) will prevent even your own web site code from executing embedded JavaScript. The recommended practice is to enable CSP in "warn only" mode first and check your logs to make sure you aren't shooting yourself in the foot.

like image 97
Stephen Thomas Avatar answered Oct 01 '22 06:10

Stephen Thomas


What you're looking for is Content Security Policy. This is implemented by output of a HTTP response header:

Content-Security-Policy: default-src https://cdn.example.net; frame-src 'none'; object-src 'none'

This is definitely worthwhile including on your website, particularly in cases where you are allowing user authored HTML content. Yes, strip out as much script content as you can using a sanitizer such as Google Caja, but as the languages of the web are constantly evolving so do the XSS attacks to exploit it. This is why you should always implement a Content Security Policy to protect against this threat. Google implement this on Gmail to prevent emails that have a new way of evading their XSS filters from doing any damage.

Note that if you are not allowing HTML content from untrusted sources then you should be encoding on output (it is not tedious if it is properly done as a site is developed). The CSP in this case is a backup for any coding mistakes - if you do a good vulnerability assessment on your website it will still pick up potential XSS flaws, even if it is protected by a CSP. The CSP will give you time to fix it without it being exploited in the meantime. For example, in HTML you would HTML encode (e.g. convert < to &lt;). Please see the OWASP XSS (Cross Site Scripting) Prevention Cheat Sheet for further details. Input validation can also be done as a second line of defense. This is where you would, for example, prevent letters from being accepted if a field was asking for a phone number. You should do this via whitelisting - only accept the characters you are expecting rather than rejecting ones you think are bad. So rather than adding all letters to a blacklist, you would add numbers and possibly the -+#() characters to a whitelist.

Always make sure to correctly encode depending on output context. Output to JavaScript requires completely different encoding than HTML. My recommendation is to always output to HTML and then retrieve the values using the DOM if you require server set variables to be used in client side script. The possible exception to this would be output to JSON where a tried and tested JSON encoder is used.

Note that Internet Explorer does have partial support for CSP. Please see this page for a full breakdown of browser support.

like image 39
SilverlightFox Avatar answered Oct 01 '22 05:10

SilverlightFox