public class CsrfPreventionRequestCycleListener extends AbstractRequestCycleListener implements IRequestCycleListener
Origin
and Referer
HTTP headers for cross domain requests. By default only checks requests that try to perform an
action on a component, such as a form submit, or link click.
You can enable this CSRF prevention filter by adding it to the request cycle listeners in your
application's init method
:
@Override protected void init() { // ... getRequestCycleListeners().add(new CsrfPreventionRequestCycleListener()); // ... }
When the Origin
or Referer
HTTP header is present but doesn't match the requested
URL this listener will by default throw a HTTP error ( 400 BAD REQUEST
) and abort the
request. You can configure
this specific action.
A missing Origin
and Referer
HTTP header is handled as if it were a bad request
and rejected. You can configure the specific action
to a
different value, suppressing or allowing the request when the HTTP headers are missing.
When the Origin
HTTP header is present and has the value null
it is considered to
be from a "privacy-sensitive" context and will trigger the no origin action. You can customize
what happens in those actions by overriding the respective onXXXX
methods.
When you want to accept certain cross domain request from a range of hosts, you can
whitelist those domains
.
You can enable or disable
this listener by overriding isEnabled()
.
You can customize
whether a particular page should be
checked for CSRF requests. For example you can skip checking pages that have a
@NoCsrfCheck
annotation, or only those pages that extend your base secure page class. For
example:
@Override protected boolean isChecked(IRequestablePage requestedPage) { return requestedPage.getPage() instanceof SecurePage; }
You can also tweak the request handlers that are checked. The CSRF prevention request cycle
listener checks only action handlers, not render handlers. Override
isChecked(IRequestHandler)
to customize this behavior.
You can customize the default actions that are performed by overriding the event handlers for them:
onWhitelisted(HttpServletRequest, String, IRequestablePage)
when an origin was
whitelistedonMatchingOrigin(HttpServletRequest, String, IRequestablePage)
when an origin was
matchingonAborted(HttpServletRequest, String, IRequestablePage)
when an origin was in
conflict and the request should be abortedonAllowed(HttpServletRequest, String, IRequestablePage)
when an origin was in
conflict and the request should be allowedonSuppressed(HttpServletRequest, String, IRequestablePage)
when an origin was in
conflict and the request should be suppressedModifier and Type | Class and Description |
---|---|
static class |
CsrfPreventionRequestCycleListener.CsrfAction
The action to perform when a missing or conflicting source URI is detected.
|
Constructor and Description |
---|
CsrfPreventionRequestCycleListener() |
Modifier and Type | Method and Description |
---|---|
protected void |
abortHandler(javax.servlet.http.HttpServletRequest request,
String origin,
IRequestablePage page)
Handles the case where an Origin HTTP header was not present or did not match the request
origin, and the corresponding action (
noOriginAction or
conflictingOriginAction ) is set to ABORT . |
CsrfPreventionRequestCycleListener |
addAcceptedOrigin(String acceptedOrigin)
Adds an origin (host name/domain name) to the white list.
|
protected void |
allowHandler(javax.servlet.http.HttpServletRequest request,
String origin,
IRequestablePage page)
Handles the case where an Origin HTTP header was not present or did not match the request
origin, and the corresponding action (
noOriginAction or
conflictingOriginAction ) is set to ALLOW . |
protected void |
checkRequest(javax.servlet.http.HttpServletRequest request,
String sourceUri,
IRequestablePage page)
Performs the check of the
Origin or Referer header that is targeted at the
page . |
protected String |
getSourceUri(javax.servlet.http.HttpServletRequest containerRequest)
Resolves the source URI from the request headers (
Origin or Referer ). |
protected String |
getTargetUriFromRequest(javax.servlet.http.HttpServletRequest request)
Creates a RFC-6454 comparable URI from the
request requested resource. |
protected boolean |
isChecked(IRequestablePage targetedPage)
Override to limit whether the request to the specific page should be checked for a possible
CSRF attack.
|
protected boolean |
isChecked(IRequestHandler handler)
Override to change the request handler types that are checked.
|
protected boolean |
isEnabled()
Dynamic override for enabling/disabling the CSRF detection.
|
protected boolean |
isLocalOrigin(javax.servlet.http.HttpServletRequest containerRequest,
String originHeader)
Checks whether the
Origin HTTP header of the request matches where the request came
from. |
protected boolean |
isWhitelistedHost(String sourceUri)
Checks whether the domain part of the
sourceUri (Origin or Referer
header) is whitelisted. |
protected void |
matchingOrigin(javax.servlet.http.HttpServletRequest request,
String origin,
IRequestablePage page)
Handles the case where an origin was checked and matched the request origin.
|
protected String |
normalizeUri(String uri)
Creates a RFC-6454 comparable URI from the
uri string. |
protected void |
onAborted(javax.servlet.http.HttpServletRequest request,
String origin,
IRequestablePage page)
Override this method to customize the case where an Origin HTTP header was not present or did
not match the request origin, and the corresponding action (
noOriginAction or
conflictingOriginAction ) is set to ABORTED . |
protected void |
onAllowed(javax.servlet.http.HttpServletRequest request,
String origin,
IRequestablePage page)
Override this method to customize the case where an Origin HTTP header was not present or did
not match the request origin, and the corresponding action (
noOriginAction or
conflictingOriginAction ) is set to ALLOW . |
void |
onBeginRequest(RequestCycle cycle)
Called when the request cycle object is beginning its response
|
protected void |
onMatchingOrigin(javax.servlet.http.HttpServletRequest request,
String origin,
IRequestablePage page)
Called when the origin HTTP header matched the request.
|
void |
onRequestHandlerResolved(RequestCycle cycle,
IRequestHandler handler)
Called when an
IRequestHandler is resolved and will be executed. |
protected void |
onSuppressed(javax.servlet.http.HttpServletRequest request,
String origin,
IRequestablePage page)
Override this method to customize the case where an Origin HTTP header was not present or did
not match the request origin, and the corresponding action (
noOriginAction or
conflictingOriginAction ) is set to SUPPRESSED . |
protected void |
onWhitelisted(javax.servlet.http.HttpServletRequest request,
String origin,
IRequestablePage page)
Called when the origin was available in the whitelist.
|
CsrfPreventionRequestCycleListener |
setConflictingOriginAction(CsrfPreventionRequestCycleListener.CsrfAction action)
Sets the action when a conflicting Origin header is detected.
|
CsrfPreventionRequestCycleListener |
setErrorCode(int errorCode)
Modifies the HTTP error code in the exception when a conflicting Origin header is detected.
|
CsrfPreventionRequestCycleListener |
setErrorMessage(String errorMessage)
Modifies the HTTP message in the exception when a conflicting Origin header is detected.
|
CsrfPreventionRequestCycleListener |
setNoOriginAction(CsrfPreventionRequestCycleListener.CsrfAction action)
Sets the action when no Origin header is present in the request.
|
protected void |
suppressHandler(javax.servlet.http.HttpServletRequest request,
String origin,
IRequestablePage page)
Handles the case where an Origin HTTP header was not present or did not match the request
origin, and the corresponding action (
noOriginAction or
conflictingOriginAction ) is set to SUPPRESS . |
protected IRequestHandler |
unwrap(IRequestHandler handler)
Unwraps the handler if it is a
IRequestHandlerDelegate down to the deepest nested
handler. |
protected void |
whitelistedHandler(javax.servlet.http.HttpServletRequest request,
String origin,
IRequestablePage page)
Handles the case where an origin is in the whitelist.
|
onDetach, onEndRequest, onException, onExceptionRequestHandlerResolved, onRequestHandlerExecuted, onRequestHandlerScheduled, onUrlMapped
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
onDetach, onEndRequest, onException, onExceptionRequestHandlerResolved, onRequestHandlerExecuted, onRequestHandlerScheduled, onUrlMapped
public CsrfPreventionRequestCycleListener setNoOriginAction(CsrfPreventionRequestCycleListener.CsrfAction action)
ALLOW
.action
- the alternate actionpublic CsrfPreventionRequestCycleListener setConflictingOriginAction(CsrfPreventionRequestCycleListener.CsrfAction action)
ERROR
.action
- the alternate actionpublic CsrfPreventionRequestCycleListener setErrorCode(int errorCode)
errorCode
- the alternate HTTP error code, default 400 BAD REQUEST
public CsrfPreventionRequestCycleListener setErrorMessage(String errorMessage)
errorMessage
- the alternate messagepublic CsrfPreventionRequestCycleListener addAcceptedOrigin(String acceptedOrigin)
example.com
is in the white list, this allows requests from (i.e. with an
Origin:
header containing) example.com
and blabla.example.com
but
rejects requests from blablaexample.com
and example2.com
.acceptedOrigin
- the acceptable originpublic void onBeginRequest(RequestCycle cycle)
IRequestCycleListener
onBeginRequest
in interface IRequestCycleListener
onBeginRequest
in class AbstractRequestCycleListener
protected boolean isEnabled()
true
true
when the CSRF checks need to be performed.protected boolean isChecked(IRequestablePage targetedPage)
targetedPage
- the page that is the target for the actiontrue
when the request to the page should be checked for CSRF issues.protected boolean isChecked(IRequestHandler handler)
handler
- the handler that is currently processinghandler
protected IRequestHandler unwrap(IRequestHandler handler)
IRequestHandlerDelegate
down to the deepest nested
handler.handler
- The handler to unwrapIRequestHandlerDelegate
public void onRequestHandlerResolved(RequestCycle cycle, IRequestHandler handler)
IRequestCycleListener
IRequestHandler
is resolved and will be executed.onRequestHandlerResolved
in interface IRequestCycleListener
onRequestHandlerResolved
in class AbstractRequestCycleListener
protected String getSourceUri(javax.servlet.http.HttpServletRequest containerRequest)
Origin
or Referer
).containerRequest
- the current container requestprotected void checkRequest(javax.servlet.http.HttpServletRequest request, String sourceUri, IRequestablePage page)
Origin
or Referer
header that is targeted at the
page
.request
- the current container requestsourceUri
- the source URIpage
- the page that is the target of the requestprotected boolean isWhitelistedHost(String sourceUri)
sourceUri
(Origin
or Referer
header) is whitelisted.sourceUri
- the contents of the Origin
or Referer
HTTP headertrue
when the source domain was whitelistedprotected boolean isLocalOrigin(javax.servlet.http.HttpServletRequest containerRequest, String originHeader)
Origin
HTTP header of the request matches where the request came
from.containerRequest
- the current container requestoriginHeader
- the contents of the Origin
HTTP headertrue
when the origin of the request matches the Origin
HTTP headerprotected final String normalizeUri(String uri)
uri
string.uri
- the contents of the Origin or Referer HTTP headernull
when the URI string is not
compliantprotected final String getTargetUriFromRequest(javax.servlet.http.HttpServletRequest request)
request
requested resource.request
- the incoming requestnull
when the origin string is not
compliantprotected void whitelistedHandler(javax.servlet.http.HttpServletRequest request, String origin, IRequestablePage page)
request
- the requestorigin
- the contents of the Origin
HTTP headerpage
- the page that is targeted with this requestprotected void onWhitelisted(javax.servlet.http.HttpServletRequest request, String origin, IRequestablePage page)
request
- the requestorigin
- the contents of the Origin
HTTP headerpage
- the page that is targeted with this requestprotected void matchingOrigin(javax.servlet.http.HttpServletRequest request, String origin, IRequestablePage page)
request
- the requestorigin
- the contents of the Origin
HTTP headerpage
- the page that is targeted with this requestprotected void onMatchingOrigin(javax.servlet.http.HttpServletRequest request, String origin, IRequestablePage page)
request
- the requestorigin
- the contents of the Origin
HTTP headerpage
- the page that is targeted with this requestprotected void allowHandler(javax.servlet.http.HttpServletRequest request, String origin, IRequestablePage page)
noOriginAction
or
conflictingOriginAction
) is set to ALLOW
.request
- the requestorigin
- the contents of the Origin
HTTP header, may be null
or emptypage
- the page that is targeted with this requestprotected void onAllowed(javax.servlet.http.HttpServletRequest request, String origin, IRequestablePage page)
noOriginAction
or
conflictingOriginAction
) is set to ALLOW
.request
- the requestorigin
- the contents of the Origin
HTTP header, may be null
or emptypage
- the page that is targeted with this requestprotected void suppressHandler(javax.servlet.http.HttpServletRequest request, String origin, IRequestablePage page)
noOriginAction
or
conflictingOriginAction
) is set to SUPPRESS
.request
- the requestorigin
- the contents of the Origin
HTTP header, may be null
or emptypage
- the page that is targeted with this requestprotected void onSuppressed(javax.servlet.http.HttpServletRequest request, String origin, IRequestablePage page)
noOriginAction
or
conflictingOriginAction
) is set to SUPPRESSED
.request
- the requestorigin
- the contents of the Origin
HTTP header, may be null
or emptypage
- the page that is targeted with this requestprotected void abortHandler(javax.servlet.http.HttpServletRequest request, String origin, IRequestablePage page)
noOriginAction
or
conflictingOriginAction
) is set to ABORT
.request
- the requestorigin
- the contents of the Origin
HTTP header, may be null
or emptypage
- the page that is targeted with this requestprotected void onAborted(javax.servlet.http.HttpServletRequest request, String origin, IRequestablePage page)
noOriginAction
or
conflictingOriginAction
) is set to ABORTED
.request
- the requestorigin
- the contents of the Origin
HTTP header, may be null
or emptypage
- the page that is targeted with this requestCopyright © 2006–2019 Apache Software Foundation. All rights reserved.