Tags:
To address security defects developers typically resort to fixing design flaws and security bugs directly in their code. Finding and fixing security defects can be a slow, painstaking, and expensive process. While development teams work to incorporate security into their development processes, issues like Cross-Site Scripting (XSS) continue to plague many commonly used applications.
In this post we'll discuss two HTTP header related protections that can be used to mitigate the risk of XSS without having to make large code changes.
HttpOnly
One of the most common XSS attacks is the theft of cookies (especially session ids). The HttpOnly flag was created to mitigate this threat by ensuring that Cookie values cannot be accessed by client side scripts like JavaScript. This is accomplished by simply appending "; HttpOnly
" to a cookie value. All modern browsers support this flag and will enforce that the cookie cannot be accessed by JavaScript, thereby preventing session hijacking attacks.
Older versions of the Java Servlet specification did not provide a standard way to define the JSESSIONID as "HttpOnly". As of Servlet 3.0, the HttpOnly flag can be enabled in web.xml as follows:
<session-config> <cookie-config> <http-only>true</http-only> </cookie-config> </session-config>
Aside from this approach in Servlet 3.0, older versions of Tomcat allowed the HttpOnly flag to be set with the vendor-specific "useHttpOnly" attribute in server.xml. This attribute was disabled by default in Tomcat 5.5 and 6. But, starting with Tomcat 7, the "useHttpOnly" attribute is enabled by default. So, even if you configure web.xml to be "false" in Tomcat 7, your JSESSIONID will still be HttpOnly unless you change the default behavior in server.xml as well.
Alternatively, you can programmatically add an HttpOnly cookie directly to the request using the following code:
<pre>String cookie = "mycookie=test; Secure; HttpOnly";<br>response.addHeader("Set-Cookie", cookie);</pre>
Fortunately, the Servlet 3.0 API was also updated to with a convenience method called setHttpOnly
for adding the HttpOnly flag:
String cookie = "mycookie=test; Secure; HttpOnly"; response.addHeader("Set-Cookie", cookie);
Content Security Policy
Content Security Policy (CSP) is a mechanism to help mitigate injection vulnerabilities like XSS by defining a list of approved sources of content. For example, approved sources of JavaScript can be defined to be from certain origins and any other JavaScript would not be allowed to execute. The official HTTP header used to define CSP policies is Content-Security-Policy
and can be used like this:
Content-Security-Policy: default-src 'none'; script-src https://*.sanscdn.org https://ssl.google-analytics.com; style-src" class="redactor-autoparser-object">https://*.sanscdn.org ... 'self' img-src https://*.sanscdn.org font-src" class="redactor-autoparser-object">https://*.sanscdn.org font-... https://*.sanscdn.org
In this example you can see that CSP can be used to define a whitelist of allowable content sources using default-src 'none'
and the following directives:
-
script-src
- scripts can only be loaded from a specfic content delivery network (CDN) or from Google Analytics style-src
- Styles can only be loaded from the current originimg-src
andfont-src
- images and fonts can only be loaded from the CDN
By using the Content-Security-Policy header with directives like this you can easily harden your application against XSS. It sounds easy enough but there are some important limitations. CSP requires that there are no inline scripts or styles in your application. This means that all JavaScript in your application has to be externalized into .js files. Basically, you can't have inline <script>
tags or call any functions which allow JavaScript execution from strings (e.g. eval
, setTimeout
, setInterval
). This can be a problem for legacy applications that need to be refactored.
As a result, the CSP specification also provides a Content-Security-Policy-Report-Only
header that does not block any scripts in your application from running but simply sends JSON formatted reports so that you can be alerted when something might have broken as a result of CSP. By enabling this header, you can test and update your app slowly over time while gaining visibility into areas that need to be refactored.