blob: bd8b35942c9a4da6fbb3b35b24f56ba4c29d82ab [file] [log] [blame]
_CryptoMapper_ helps preventing CSRF attacks by making the urls impossible to be guessed by an attacker but still there is some theoretical chance this to happen.
To further help against this kind of vulnerability Wicket provides _ResourceIsolationRequestCycleListener_ - a _IRequestCycleListener_ that uses __IResourceIsolationPolicy__ objects to decide whether to allow or reject cross-origin requests.
Just like any RequestCycle listener _ResourceIsolationRequestCycleListener_ must be registered on application initialization:
[source,java]
----
@Override
protected void init() {
super.init();
getRequestCycleListeners().add(new ResourceIsolationRequestCycleListener());
// ...
}
----
By default _ResourceIsolationRequestCycleListener_ checks only event handlers requests, i.e. a cross-origin requests cannot execute _Link.onClick()_ or submit forms (_Form.onSubmit()_). Any request to render pages are still allowed so Wicket pages could be easily embedded in other applications. To extend CSRF protection to pages we can simply override _isChecked(IRequestHandler handler)_ method to make it return always _true_:
[source,java]
----
@Override
protected void init() {
super.init();
getRequestCycleListeners().add(new ResourceIsolationRequestCycleListener() {
@Override
protected boolean isChecked(IRequestHandler handler) {
//check everything
return true;
}
});
// ...
}
----
_ResourceIsolationRequestCycleListener_ is highly configurable. It allows to add exempted paths that will not be checked with the __addExemptedPath__ method. It can also be configured with multiple _ResourceIsolationPolicy_ objects to be checked in order.
An __IResourceIsolationPolicy__ returns a __ResourceIsolationOutcome__ after processing a request, which can be one of 3 values (__ALLOWED__, __DISALLOWED__, __UNKNOWN__). The __ResourceIsolationRequestCycleListener__ checks the __IResourceIsolationPolicy__ objects in order and uses the first outcome that is not __UNKNOWN__ to trigger the appropriate action. If all return __UNKNOWN__ __unknownOutcomeAction__ is applied. The actions can be configured through the listener.
The default constructor uses the __FetchMetadataResourceIsolationPolicy__, which checks Fetch Metadata headers, and the __OriginResourceIsolationPolicy__ which uses the Origin and Referer headers to forbid requests made from a different origin, in order. The __OriginResourceIsolationPolicy__ contains the refactored logic of the now deprecated __CsrfPreventionRequestCycleListener__.
The listener can be configured to include custom __IResourceIsolationPolicy__ objects.
For example:
[source,java]
----
@Override
protected void init() {
super.init();
getRequestCycleListeners().add(
new ResourseIsolationRequestCycleListener(
new FetchMetadataResourceIsolationPolicy(),
new OriginResourceIsolationPolicy(),
new MyCustomResourceIsolationPolicy()
));
// ...
}
----
_ResourceIsolationRequestCycleListener_ is not an alternative to _CryptoMapper_! Both of them could be used separately or in tandem to prevent CSRF attacks depending on the application requirements.
NOTE: In the next chapter we will cover unit testing with Wicket. If your application is protected with _ResourceIsolationRequestCycleListener_ you have to properly set request header _"sec-fetch-site"_ to make you unit tests pass. In <<testing.adoc#_setting_request_headers,paragraph 23.1.10>> you will learn how to do it.
Wicket also provides the deprecated (since version 9.1.0) _CsrfPreventionRequestCycleListener_ - a _IRequestCycleListener_ that forbids requests made from a different origin. Similar to the __ResourceIsolationRequestCycleListener__ by default only actions are forbidden, i.e. a request coming from different origin cannot execute _Link.onClick()_ or submit forms (_Form.onSubmit()_). Any request to render pages are still allowed so Wicket pages could be easily embedded in other applications.
MyApplication.java
[source,java]
----
@Override
protected void init() {
super.init();
getRequestCycleListeners().add(new CsrfPreventionRequestCycleListener());
// ...
}
----
_CsrfPreventionRequestCycleListener_ is highly configurable. It allows to define a whitelist of allowed origins via _addAcceptedOrigin(String acceptedOrigin)_, to enable/disable it dynamically by overriding _isEnabled()_, to define different kind of actions when a request is rejected or allowed, to set custom error message and code for the rejected requests.
_CsrfPreventionRequestCycleListener_ is not an alternative to _CryptoMapper_! Both of them could be used separately or in tandem to prevent CSRF attacks depending on the application requirements.