Class CsrfPreventionFilter
- java.lang.Object
-
- org.camunda.bpm.webapp.impl.security.filter.CsrfPreventionFilter
-
- All Implemented Interfaces:
javax.servlet.Filter
public class CsrfPreventionFilter extends java.lang.Object implements javax.servlet.Filter
Provides basic CSRF protection implementing a Same Origin Standard Header verification (step 1) and a Synchronization Token with a cookie-stored token on the front-end.Positive scenario: Client Server | | | GET Fetch Request \| JSESSIONID |---------------------------------| X-CSRF-Token | /| pair generation |/Response to Fetch Request | |---------------------------------| JSESSIONID |\ | X-CSRF-Token | | pair cached | POST Request with valid token \| JSESSIONID | header | |---------------------------------| X-CSRF-Token | /| pair validation |/ Response to POST Request | |---------------------------------| |\ | Negative scenario: Client Server | | | POST Request without token | JSESSIONID | header \| X-CSRF-Token |---------------------------------| pair validation | /| |/Request is rejected | |---------------------------------| |\ | Client Server | | | POST Request with invalid token\| JSESSIONID |---------------------------------| X-CSRF-Token | /| pair validation |/Request is rejected | |---------------------------------| |\ |
Parts of this code were ported from theCsrfPreventionFilter
class of Apache Tomcat. Furthermore, theRestCsrfPreventionFilter
class from the same codebase was used as a guideline.- Author:
- Nikola Koevski
-
-
Field Summary
Fields Modifier and Type Field Description protected CookieConfigurator
cookieConfigurator
protected java.util.Set<java.lang.String>
entryPoints
-
Constructor Summary
Constructors Constructor Description CsrfPreventionFilter()
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
destroy()
void
doFilter(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse, javax.servlet.FilterChain filterChain)
protected boolean
doSameOriginStandardHeadersVerification(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
Validates if the Origin/Referer header matches the provided target origin.protected boolean
doTokenValidation(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
Validates the provided CSRF token value from the request with the session CSRF token value.protected java.lang.String
generateCSRFToken()
Generate a one-time token for authenticating subsequent requests.protected java.lang.String
getCookiePath(javax.servlet.http.HttpServletRequest request)
int
getDenyStatus()
java.lang.String
getRandomClass()
java.net.URL
getTargetOrigin()
void
init(javax.servlet.FilterConfig filterConfig)
protected boolean
isNonModifyingRequest(javax.servlet.http.HttpServletRequest request)
Determine if the request a non-modifying request.protected void
setCSRFToken(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
Generates a new CSRF Token which is persisted in the session.void
setDenyStatus(int denyStatus)
Sets the response status code that is used to reject denied request.void
setEntryPoints(java.lang.String entryPoints)
Entry points are URLs that will not be tested for the presence of a valid token.void
setRandomClass(java.lang.String randomClass)
Sets the name of the class to use to generate tokens.void
setTargetOrigin(java.lang.String targetOrigin)
Target origin is the application expected deployment domain, i.e.
-
-
-
Field Detail
-
entryPoints
protected final java.util.Set<java.lang.String> entryPoints
-
cookieConfigurator
protected CookieConfigurator cookieConfigurator
-
-
Method Detail
-
init
public void init(javax.servlet.FilterConfig filterConfig) throws javax.servlet.ServletException
- Specified by:
init
in interfacejavax.servlet.Filter
- Throws:
javax.servlet.ServletException
-
doFilter
public void doFilter(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse, javax.servlet.FilterChain filterChain) throws java.io.IOException, javax.servlet.ServletException
- Specified by:
doFilter
in interfacejavax.servlet.Filter
- Throws:
java.io.IOException
javax.servlet.ServletException
-
doTokenValidation
protected boolean doTokenValidation(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws java.io.IOException
Validates the provided CSRF token value from the request with the session CSRF token value.- Parameters:
request
-response
-- Returns:
- true if the token is valid
- Throws:
java.io.IOException
-
doSameOriginStandardHeadersVerification
protected boolean doSameOriginStandardHeadersVerification(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws java.io.IOException
Validates if the Origin/Referer header matches the provided target origin.- Parameters:
request
-response
-- Returns:
- true if the values match
- Throws:
java.io.IOException
-
setCSRFToken
protected void setCSRFToken(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
Generates a new CSRF Token which is persisted in the session. How the token is forwarded to the client and how it will be persisted there is not covered by this method.- Parameters:
request
-
-
getCookiePath
protected java.lang.String getCookiePath(javax.servlet.http.HttpServletRequest request)
-
getTargetOrigin
public java.net.URL getTargetOrigin()
-
setTargetOrigin
public void setTargetOrigin(java.lang.String targetOrigin) throws java.net.MalformedURLException
Target origin is the application expected deployment domain, i.e. the domain name through which the webapps are accessed. If nothing is set, the "Same Origin with Standard Headers" verification is not performed.- Parameters:
targetOrigin
- The application's domain name together with the protocol and port (ex. http://example.com:8080)- Throws:
java.net.MalformedURLException
-
setEntryPoints
public void setEntryPoints(java.lang.String entryPoints)
Entry points are URLs that will not be tested for the presence of a valid token. They are used to provide a way to navigate back to a protected application after navigating away from it. Entry points will be limited to HTTP GET requests and should not trigger any security sensitive actions.- Parameters:
entryPoints
- Comma separated list of URLs to be configured as entry points.
-
getDenyStatus
public int getDenyStatus()
- Returns:
- the response status code that is used to reject a denied request.
-
setDenyStatus
public void setDenyStatus(int denyStatus)
Sets the response status code that is used to reject denied request. If none is set, the default value of 403 will be used.- Parameters:
denyStatus
- HTTP status code
-
getRandomClass
public java.lang.String getRandomClass()
-
setRandomClass
public void setRandomClass(java.lang.String randomClass)
Sets the name of the class to use to generate tokens. The class must be an instance of `java.util.Random`. If not set, the default value of `java.security.SecureRandom` will be used.- Parameters:
randomClass
- The name of the class
-
destroy
public void destroy()
- Specified by:
destroy
in interfacejavax.servlet.Filter
-
isNonModifyingRequest
protected boolean isNonModifyingRequest(javax.servlet.http.HttpServletRequest request)
Determine if the request a non-modifying request. A non-modifying request is one that is either a 'HTTP GET/OPTIONS/HEAD' request, or is allowed explicitly through the 'entryPoints' parameter in the web.xml- Returns:
- true if the request is a non-modifying request
-
generateCSRFToken
protected java.lang.String generateCSRFToken()
Generate a one-time token for authenticating subsequent requests.- Returns:
- the generated token
-
-