CAS security filter
This project provides blunt generic Java Servlet filters suitable for patching-in-place Java CAS server and Java CAS client deployments vulnerable to certain request parameter based bad-CAS-protocol-input attacks.
Build
AddResponseHeadersFilter for patching CAS client usages
This filter allows you to inject custom header names into the response. Design the headers as init params shown below:
<filter>
<filter-name>requestParameterFilter</filter-name>
<filter-class>org.apereo.cas.security.AddResponseHeadersFilter</filter-class>
<init-param>
<param-name>headerName1</param-name>
<param-value>headerValue1</param-value>
</init-param>
<init-param>
<param-name>headerName2</param-name>
<param-value>headerValue2</param-value>
</init-param>
</filter>
...
<filter-mapping>
<filter-name>requestParameterFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
ResponseHeadersEnforcementFilter for patching CAS client usages
This is a Java Servlet Filter to be used to inject default security headers into the respose: See this guide for reference. It has no dependencies.
Configuration options
This Filter is optionally configured via Filter init-param
in web.xml
.
In general the Filter is very persnickety about init-params, such that if you give it a configuration that the Filter is not totally sure it understands, it will fail Filter initialization. Note that all configuration knobs are turned off by default.
enableCacheControl init-param
When true
, will inject the following headers into the response for non-static resources:
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
enableXContentTypeOptions init-param
When true
, will inject the following headers into the response:
X-Content-Type-Options: nosniff
enableStrictTransportSecurity init-param
When true
, will inject the following headers into the response:
Strict-Transport-Security: max-age=15768000 ; includeSubDomains
enableXFrameOptions init-param
When true
, will inject the following headers into the response:
X-Frame-Options: DENY
enableXSSProtection init-param
When true
, will inject the following headers into the response:
X-XSS-Protection: 1; mode=block
contentSecurityPolicy init-param
When defined, injects the Content-Security-Policy
header into the response with the value given.
RequestParameterPolicyEnforcementFilter for patching CAS client usages
This is a Java Servlet Filter for use in fronting potentially bugged Java CAS Client usages.
It is optionally configurable as to what parameters it checks, what characters it forbids in those checked parameters, and whether it allows those checked parameters to be multi-valued.
It has no dependencies.
Configuration options
This Filter is optionally configured via Filter init-param
in web.xml
.
In general the Filter is very persnickety about init-params, such that if you give it a configuration that the Filter is not totally sure it understands, it will log an exception.
WARNING: By default bad filter configuration will NOT fail filter initialization, and so it is possible to inadvertently configure the filter to e.g. have no effect. You SHOULD either be sure to monitor the logs for the SEVERE messages that will be logged if this filter believes its configuration is problematic, or set FilterUtils.throwOnErrors
to true so that bad filter config fails Filter init and so fails context init, guaranteeing that you do not bring up an application intending to protect it with this filter but not successfully doing so due to configuration errors the filter is aware of.
parametersToCheck init-param
The optional init-param parametersToCheck
is a whitespace-delimited set of the names of request parameters the Filter will check.
The special value *
instructs the Filter to check all parameters, and is the default behavior.
charactersToForbid init-param
The optional init-param charactersToForbid
is a whitespace-delimited set of the individual characters the Filter will forbid.
The special magic value of exactly none
instructs the Filter not to forbid any characters. (This is useful for using the Filter to block multi-valued-ness of parameters without sniffing on any characters.)
If not present, the Filter will default to forbidding the characters ? # & %
.
allowMultiValuedParameters init-param
The optional init-param allowMultiValuedParameters
indicates whether the Filter should allow multi-valued parameters.
If present the value of this parameter must be exactly true
or false
, with false
as the default.
onlyPostParameters init-param
The optional init-param onlyPostParameters
is a whitespace-delimited set of the names of request parameters the filter will allow only on POST type requests. The Filter will throw an exception when any of these parameters are present on requests of any other type.
Configuration Examples
The default configuration
<filter>
<filter-name>requestParameterFilter</filter-name>
<filter-class>org.apereo.cas.security.RequestParameterPolicyEnforcementFilter</filter-class>
</filter>
...
<filter-mapping>
<filter-name>requestParameterFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
In this configuration, the Filter will scrutinize all request parameters, requiring that they not be multi-valued, requiring that they not contain any of % ? # &
, and allowing request parameters regardless of whether the request is of type POST or not.
Configuring to fail safely
<filter>
<filter-name>requestParameterFilter</filter-name>
<filter-class>org.apereo.cas.security.RequestParameterPolicyEnforcementFilter</filter-class>
<init-param>
<param-name>failSafe</param-name>
<param-value>true</param-value>
</init-param>
</filter>
...
<filter-mapping>
<filter-name>requestParameterFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
In this configuration, the Filter will fail filter initialization if there are any configuration errors. There are not configuration errors here, so it will not so fail. But this makes a safer starting point from which to add other configuration, since if the filter detects errors in any of that additional configuration, filter init will fail rather than the context initing with the filter not providing the protection that you may have intended it to provide.
Allow multi-valued parameters
Multi-valued parameters are essential for supporting forms with multi-choice selectors where the form submission is legitimately represented as repeated parameter names with different values.
So, if you want to scrutinize the characters in all parameters, you might have to relax the requirement that those parameters not be multi-valued.
<filter>
<filter-name>requestParameterFilter</filter-name>
<filter-class>org.apereo.cas.security.RequestParameterPolicyEnforcementFilter</filter-class>
<init-param>
<param-name>allowMultiValuedParameters</param-name>
<param-value>true</param-value>
</init-param>
</filter>
...
<filter-mapping>
<filter-name>requestParameterFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Restrictions suitable for fronting a CAS Client
If you're using this Filter for protection in front of a CAS client library usage, you might want to tighten it down to just checking the request parameters involved in the CAS protocol.
<filter>
<filter-name>requestParameterFilter</filter-name>
<filter-class>org.apereo.cas.security.RequestParameterPolicyEnforcementFilter</filter-class>
<init-param>
<param-name>parametersToCheck</param-name>
<param-value>ticket SAMLArt pgtIou pgtId</param-value>
</init-param>
</filter>
...
<filter-mapping>
<filter-name>requestParameterFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Restrictions suitable for fronting a CAS Server
Likewise, you could use this Filter in front of a CAS Server to prevent unexpected multi-valued submissions of CAS protocol parameters.
<filter>
<filter-name>requestParameterFilter</filter-name>
<filter-class>org.apereo.cas.security.RequestParameterPolicyEnforcementFilter</filter-class>
<init-param>
<param-name>parametersToCheck</param-name>
<param-value>ticket SAMLArt service renew gateway warn logoutUrl pgtUrl</param-value>
</init-param>
<init-param>
<param-name>charactersToForbid</param-name>
<param-value>none</param-value>
</init-param>
</filter>
...
<filter-mapping>
<filter-name>requestParameterFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
This approach has the advantage of only blocking specific CAS protocol parameters, so that if you were to map the Filter in front of say the services management UI you can block unexpectedly multi-valued CAS protocol parameters without blocking submission of the services management edit screen where multiple user attributes are selected for release to a service (a legitimate case of a multi-valued attribute).
Limiting specific request parameters to POST-type requests
You could use this filter to restrict to only POST-type requests those request parameters that you expect only in POST-type requests.
For example, suppose you have a HTML form that submits a form via POST with parameters formFieldOne
and formFieldTwo
. This configuration would block requests that include these parameters in other types of requests, for example in GET requests.
<filter>
<filter-name>requestParameterFilter</filter-name>
<filter-class>org.apereo.cas.security.RequestParameterPolicyEnforcementFilter</filter-class>
<init-param>
<param-name>onlyPostParameters</param-name>
<param-value>formFieldOne formFieldTwo</param-value>
</init-param>
<init-param>
<param-name>charactersToForbid</param-name>
<param-value>none</param-value>
</init-param>
</filter>
...
<filter-mapping>
<filter-name>requestParameterFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
An entirely novel configuration
So, a neat thing about this Filter is that it has nothing to do with CAS and it has no dependencies at all other than the Servlet API, so on that fateful day when you discover that some Java web application has some problem involving illicit submissions of the semicolon character in a request parameter named query
, you can plop this Filter in front of it and get back to safety. Doing so will almost certainly just work, since this Filter has no external dependencies whatsoever except on the Servlet API that had to be present for that Web Application to be a Java web app anyway.
<filter>
<filter-name>requestParameterFilter</filter-name>
<filter-class>org.apereo.cas.security.RequestParameterPolicyEnforcementFilter</filter-class>
<init-param>
<param-name>parametersToCheck</param-name>
<param-value>query</param-value>
</init-param>
<init-param>
<param-name>charactersToForbid</param-name>
<param-value>;</param-value>
</init-param>
</filter>
...
<filter-mapping>
<filter-name>requestParameterFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>