Overview
OWASP CSRFGuard implements a variant of the synchronizer token pattern to mitigate the risk of CSRF attacks. In order to implement this pattern, CSRFGuard must offer the capability to place the CSRF prevention token within the HTML produced by the protected web application. CSRFGuard 3 provides developers more fine grain control over the injection of the token. Developers can inject the token in their HTML using either dynamic JavaScript DOM manipulation or a JSP tag library. CSRFGuard no longer intercepts and modifies the HttpServletResponse object as was done in previous releases. The currently available token injection strategies are designed to make the integration of CSRFGuard more feasible and scalable within current enterprise web applications. Developers are encouraged to make use of both the JavaScript DOM Manipulation and the JSP tag library strategies for a complete token injection strategy. The JavaScript DOM Manipulation strategy is ideal as it is automated and requires minimal effort on behalf of the developer. In the event the JavaScript solution is insufficient within a particular application context, developers should leverage the JSP tag library. The purpose of this article is to describe the token injection strategies offered by OWASP CSRFGuard 3.
JavaScript DOM Manipulation
OWASP CSRFGuard 3 supports the ability to dynamically inject CSRF prevention tokens throughout the DOM currently loaded in the user's browser. This strategy is extremely valuable with regards to server-side performance as it simply requires the serving of a dynamic JavaScript file. There is little to no performance hit when the fetched dynamic JavaScript updates the browser's DOM. Making use of the JavaScript token injection solution requires the developer map a Servlet and place a JavaScript HTML tag within all pages sending requests to protected application resources. Developers are strongly encouraged to leverage the JavaScript token injection strategy by default. This strategy requires minimal effort on behalf of the developer as most of the token injection logic is automated. In the event that the JavaScript automated solution may be insufficient for a specific application context, developers should leverage the OWASP CSRFGuard JSP tag library.
Note: Use of JavaScript DOM Manipulation is required for Ajax support.
Declare and Configure JavaScriptServlet
The JavaScript file used for token injection is dynamically generated by the JavaScriptServlet class using a template file. Ensure that the Owasp.CsrfGuard.jar file is found within the target application's classpath. Copy the Owasp.CsrfGuard.js template file from the OWASP CSRFGuard distribution folder to a non-publicly accessible directory within the target application. For the remainder of this section, we assume the Owasp.CsrfGuard.js template file was placed in the application's WEB-INF folder. Edit the deployment descriptor (web.xml) to declare the JavaScriptServlet class along with any associated initialization parameters. Consider the following configuration snippet taken from theOwasp.CsrfGuard.Test application:
<servlet> <servlet-name>JavaScriptServlet</servlet-name> <servlet-class>org.owasp.csrfguard.servlet.JavaScriptServlet</servlet-class> <init-param> <param-name>source-file</param-name> <param-value>WEB-INF/Owasp.CsrfGuard.js</param-value> </init-param> <init-param> <param-name>inject-into-forms</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>inject-into-attributes</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>domain-strict</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>referer-pattern</param-name> <param-value>.*localhost.*</param-value> </init-param> </servlet>
The aforementioned configuration snippet declares the JavaScriptServlet class using the name "JavaScriptServlet". JavaScriptServlet accepts various initialization parameters augmenting the behavior of the class at runtime. The provided configuration snippet instructs JavaScriptServlet to...
- Leverage the template JavaScript file at WEB-INF/Owasp.CsrfGuard.js
- Inject the token into all HTML forms
- Inject the token into all src and href attributes
- Leverage loose same origin matching criteria when placing the token in URL resources
Consider the following for a more detailed listing of the initialization parameters supported by JavaScriptServlet:
source-file
Denotes the location of the JavaScript template file that should be consumed and dynamically augmented by the JavaScriptServlet class. The default value is WEB-INF/Owasp.CsrfGuard.js. Use of this property and the existence of the specified template file is required.
domain-strict
Boolean value that determines whether or not the dynamic JavaScript code should be strict with regards to what links it should inject the CSRF prevention token. With a value of true, the JavaScript code will only place the token in links that point to the same exact domain from which the HTML originated. With a value of false, the JavaScript code will place the token in links that not only point to the same exact domain from which the HTML originated, but sub-domains as well.
referer-pattern
Allows the developer to specify a regular expression describing the required value of the Referer header. Any attempts to access the servlet with a Referer header that does not match the captured expression is discarded. Inclusion of referer header checking is to help minimize the risk of JavaScript Hijacking attacks that attempt to steal tokens from the dynamically generated JavaScript. While the primary defenses against JavaScript Hijacking attacks are implemented within the dynamic JavaScript itself, referer header checking is implemented to achieve defense in depth.
cache-control
Allows the developer to specify the value of the Cache-Control header in the HTTP response when serving the dynamic JavaScript file. The default value is private, maxage=28800. Caching of the dynamic JavaScript file is intended to minimize traffic and improve performance. Note that the Cache-Control header is always set to "no-store" when either the "Rotate" "TokenPerPage" options is set to true in Owasp.CsrfGuard.properties.
inject-into-forms
Boolean value that determines whether or not the dynamic JavaScript code should inject the CSRF prevention token as a hidden field into HTML forms. The default value is true. Developers are strongly discouraged from disabling this property as most server-side state changing actions are triggered via a POST request.
inject-into-attributes
Boolean value that determines whether or not the dynamic JavaScript code should inject the CSRF prevention token in the query string of src and href attributes. Injecting the CSRF prevention token in a URL resource increases its general risk of exposure to unauthorized parties. However, most JavaEE web applications respond in the exact same manner to HTTP requests and their associated parameters regardless of the HTTP method. The risk associated with not protecting GET requests in this situation is perceived greater than the risk of exposing the token in protected GET requests. As a result, the default value of this attribute is set to true. Developers that are confident their server-side state changing controllers will only respond to POST requests (i.e. discarding GET requests) are strongly encouraged to disable this property.
Map JavaScriptServlet
Developers must map the JavaScriptServlet to a URI space such that the Servlet class can be remotely accessed by the dynamic JavaScript code. Consider the following configuration snippet taken directly from the [hhttps://github.com/esheri3/OWASP-CSRFGuard/tree/master/Owasp.CsrfGuard.Test Owasp.CsrfGuard.Test] application:
<servlet-mapping> <servlet-name>JavaScriptServlet</servlet-name> <url-pattern>/JavaScriptServlet</url-pattern> </servlet-mapping>
The aforementioned configuration snippet maps the Servlet referenced by the name "JavaScriptServlet" to the URI space "/JavaScriptServlet". Any request sent to the /JavaScriptServlet URI will produce a dynamically generated CSRFGuard JavaScript file specific to the user's current session.
Inject Dynamic JavaScript
Developers are required to place an HTML script tag within all pages that are known to send requests to CSRF protected resources. All requests within the current HTML page are augmented to ensure they submit the correct CSRF token for the user's current session. Note that inclusion of the dynamic JavaScript does not protect the current page. Rather, the script ensures the CSRF token is transmitted within all requests generated by the current page. Consider the following code snippet taken directly from the Owasp.CsrfGuard.Test application:
<script src="/Owasp.CsrfGuard.Test/JavaScriptServlet"></script>
The script tag retrieves and executes the dynamically generated JavaScript from the Servlet mapped at /Owasp.CsrfGuard.Test/JavaScriptServlet. This JavaScript code will register an event handler with window.onload. Once triggered, the code will iterate over every HTML element within the DOM looking for either form tags and or tags containing href or src attributes as configured by the JavaScriptServlet initialization parameters. Forms are dynamically updated to include the CSRFGuard token via a hidden field and tags using src and href attributes are updated to include the CSRFGuard token via a query string parameter.
JSP Tag Library
OWASP CSRFGuard 3 exposes a JSP tag library providing developers more fine grain control over token injection. The library exposes JSP tags that allow access to the token name, the token value, and the token name value pair delimited by an equals (=) sign. In order to make use of the tag library, ensure the Owasp.CsrfGuard.jar file is found within the target application's classpath. For example, the Owasp.CsrfGuard.Test application places the OWASP CSRFGuard jar file within the WebContent/WEB-INF/lib directory. After placing the library in the classpath, developers can reference the tags in JSP pages using predefined URI reference. The following JSP code snippet imports the tag library and makes it available using the prefix "csrf":
<%@ taglib uri="http://www.owasp.org/index.php/Category:OWASP_CSRFGuard_Project/Owasp.CsrfGuard.tld" prefix="csrf" %>
The benefit of using the JSP tag library to inject the CSRF prevention token is the fine grain level of control. Developers can place the token in all the correct locations within the context of their applications. This strategy is useful in application contexts where the JavaScript DOM Manipulation strategy is insufficient.
Display Token Name
The OWASP CSRFGuard token name can be obtained through the token-name tag. The token-name tag is useful when injecting the CSRFGuard token name in a non-query string context. Consider the following code snippet taken from theOwasp.CsrfGuard.Test application. This code makes use of the token-name tag to reference the token name in the name attribute of a hidden input field:
<form name="test1" action="protect.html"> <input type="text" name="text" value="text"/> <input type="submit" name="submit" value="submit"/> <input type="hidden" name="<csrf:token-name/>" value="<csrf:token-value/>"/> </form>
Display Token Value
The OWASP CSRFGuard token value can be obtained through the token-value tag. The token-value tag is useful when injecting the CSRFGuard token value in a non-query string context. Consider the following code snippet taken from theOwasp.CsrfGuard.Test application. This code makes use of the token-value tag to reference the token value in the value attribute of a hidden input field:
<form name="test1" action="protect.html"> <input type="text" name="text" value="text"/> <input type="submit" name="submit" value="submit"/> <input type="hidden" name="<csrf:token-name/>" value="<csrf:token-value/>"/> </form>
The token value tag must be used in conjunction with the URI attribute when using the unique token per page model (org.owasp.csrfguard.TokenPerPage). The value of the uri attribute is the URI for which the token value will be posted. Consider the following example which sets the URI to the destination of the form, "protect.html":
<form id="formTest1" name="formTest1" action="protect.html"> <input type="text" name="text" value="text"/> <input type="submit" name="submit" value="submit"/> <input type="hidden" name="<csrf:token-name/>" value="<csrf:token-value uri="protect.html"/>"/> </form>
Display Token Name Value Pair
The OWASP CSRFGuard token name value pair, delimited by an equals sign (=), can be obtained though the token tag. The token tag is useful when injecting the CSRFGuard token value in a query string context. Consider the following code snippet taken from the Owasp.CsrfGuard.Test application. This code makes use of the token tag to reference the token name value pair in the href attribute of an anchor tag:
<a href="protect.html?<csrf:token/>">protect.html</a>
The token name value pair tag must be used in conjunction with the URI attribute when using the unique token per page model (org.owasp.csrfguard.TokenPerPage). The value of the uri attribute is the URI for which the token value will be posted. Consider the following example which sets the URI to the destination of the link, "protect.html":
<a href="protect.html?<csrf:token uri="protect.html"/>">protect.html</a>
Generate Form with Prevention Token
The OWASP CSRFGuard JSP library implements a tag library designed specifically to generate HTML forms with the CSRF prevention token automatically embedded as a hidden field. This strategy simplifies the integration of the CSRF token, especially when using the unique token per page model (org.owasp.csrfguard.TokenPerPage). The tag accepts dynamic attribute name value pairs and simply outputs them to the page. As a result, you are free to use the same attribute values made available in a standard HTML form. There is no special output encoding performed on these dynamic attributes. Take care to perform the appropriate validation and output encoding for all dynamic attributes used in conjunction with untrusted data. Consider the following code snippet which will produce a HTML form with an embedded CSRF token. No special care must be taken when using this flag in conjunction with the unique token per uri model:
<csrf:form id="formTest2" name="formTest2" action="protect.html"> <input type="text" name="text" value="text"/> <input type="submit" name="submit" value="submit"/> </csrf:form>
Generate Link with Prevention Token
The OWASP CSRFGuard JSP library implements a tag library designed specifically to generate HTML anchor tags with the CSRF prevention token automatically embedded as a query string parameter. This strategy simplifies the integration of the CSRF token, especially when using the unique token per page model (org.owasp.csrfguard.TokenPerPage). The tag accepts dynamic attribute name value pairs and simply outputs them to the page. As a result, you are free to use the same attribute values made available in a standard HTML anchor. There is no special output encoding performed on these dynamic attributes. Take care to perform the appropriate validation and output encoding for all dynamic attributes used in conjunction with untrusted data. Consider the following code snippet which will produce a HTML anchor tag with an embedded CSRF token. No special care must be taken when using this flag in conjunction with the unique token per uri model:
<csrf:a href="protect.html">protect.html</csrf:a>