Class RequestParameterPolicyEnforcementFilter

  • All Implemented Interfaces:
    javax.servlet.Filter

    public class RequestParameterPolicyEnforcementFilter
    extends AbstractSecurityFilter
    implements javax.servlet.Filter
    This is a Java Servlet Filter that examines specified Request Parameters as to whether they contain specified characters and as to whether they are multivalued throws an Exception if they do not meet configured rules.

    Configuration:

    The filter defaults to checking all request parameters for the hash, percent, question mark, and ampersand characters, and enforcing no-multi-valued-ness.

    You can turn off multi-value checking by setting the init-param "allowMultiValuedParameters" to "true". Setting it to "false" is a no-op retaining the default configuration. Setting this parameter to any other value may fail filter initialization.

    You can change the set of request parameters being examined by setting the init-param "parametersToCheck" to a whitespace delimited list of parameters to check. Setting it to the special value "*" retains the default behavior of checking all. Setting it to a blank value may fail filter initialization. Setting it to a String containing the asterisk token and any additional token may fail filter initialization.

    You can change the set of characters looked for by setting the init-param "charactersToForbid" to a whitespace delimited list of characters to forbid. Setting it to the special value "none" disables the illicit character blocking feature of this Filter (for the case where you only want to use the mutli-valued-ness blocking). Setting it to a blank value may fail filter initialization. Setting it to a value that fails to parse perfectly (e.g., a value with multi-character Strings between the whitespace delimiters) may fail filter initialization. The default set of characters disallowed is percent, hash, question mark, and ampersand.

    You can limit a set of request parameters to only be allowed on requests of type POST by setting the init-param "onlyPostParameters" to a whitespace-delimited list of parameters. Unlike "parametersToCheck", this does not support the special value "*". Setting "onlyPostParameters" to a blank value fails filter initialization. By default (when "onlyPostParameters" is not set), the filter does not limit request parameters to only POST requests.

    Setting any other init parameter other than these recognized by this Filter will fail Filter initialization. This is to protect the adopter from typos or misunderstandings in web.xml configuration such that an intended configuration might not have taken effect, since that might have security implications.

    Setting the Filter to both allow multi-valued parameters and to disallow no characters would make the Filter a no-op, and so may fail filter initialization since you probably meant the Filter to be doing something.

    The intent of this filter is rough, brute force blocking of unexpected characters in specific CAS protocol related request parameters. This is one option as a workaround for patching in place certain Java CAS Client versions that may be vulnerable to certain attacks involving crafted request parameter values that may be mishandled. This is also suitable for patching certain CAS Server versions to make more of an effort to detect and block out-of-spec CAS protocol requests. Aside from the intent to be useful for those cases, there is nothing CAS-specific about this Filter itself. This is a generic Filter for doing some pretty basic generic sanity checking on request parameters. It might come in handy the next time this kind of issue arises.

    This Filter is written to have no external .jar dependencies aside from the Servlet API necessary to be a Filter.

    Since:
    6.1.0
    • Field Summary

      Fields 
      Modifier and Type Field Description
      static java.lang.String ALLOW_MULTI_VALUED_PARAMETERS
      The name of the optional Filter init-param specifying whether the checked request parameters are allowed to have multiple values.
      static java.lang.String CHARACTERS_TO_FORBID
      The name of the optional Filter init-param specifying what characters are forbidden in the checked request parameters.
      static java.lang.String DEFAULT_CHARACTERS_BLOCKED
      The set of Characters blocked by default on checked parameters.
      static java.lang.String ONLY_POST_PARAMETERS
      The name of the optional Filter init-param specifying what request parameters ought to be send via POST requests only.
      static java.lang.String PARAMETERS_TO_CHECK
      The name of the optional Filter init-param specifying what request parameters ought to be checked.
      static java.lang.String PATTERN_TO_BLOCK
      Name of the setting to specify a pattern that would be checked against the request URL to block if a successful match is found.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      static void checkOnlyPostParameters​(java.lang.String method, java.util.Map parameterMap, java.util.Set<java.lang.String> onlyPostParameters)
      Check that some parameters should only be in POST requests (according to the configuration).
      void destroy()  
      void doFilter​(javax.servlet.ServletRequest request, javax.servlet.ServletResponse response, javax.servlet.FilterChain chain)  
      static void enforceParameterContentCharacterRestrictions​(java.util.Set<java.lang.String> parametersToCheck, java.util.Set<java.lang.Character> charactersToForbid, java.util.Map parameterMap)
      For each parameter to check, for each value of that parameter, check that the value does not contain forbidden characters.
      void init​(javax.servlet.FilterConfig filterConfig)  
      static java.util.Set<java.lang.Character> parseCharactersToForbid​(java.lang.String value)
      Parse a whitespace delimited set of Characters from a String.
      static java.util.Set<java.lang.String> parseParametersList​(java.lang.String initParamValue, boolean allowWildcard)
      Parse the whitespace delimited String of parameters to check.
      static void requireNotMultiValued​(java.util.Set<java.lang.String> parametersToCheck, java.util.Map parameterMap)
      For each parameter to check, verify that it has zero or one value.
      static void throwIfUnrecognizedParamName​(java.util.Enumeration initParamNames)
      Examines the Filter init parameter names and throws ServletException if they contain an unrecognized init parameter name.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • DEFAULT_CHARACTERS_BLOCKED

        public static final java.lang.String DEFAULT_CHARACTERS_BLOCKED
        The set of Characters blocked by default on checked parameters. Expressed as a whitespace delimited set of characters.
        See Also:
        Constant Field Values
      • PARAMETERS_TO_CHECK

        public static final java.lang.String PARAMETERS_TO_CHECK
        The name of the optional Filter init-param specifying what request parameters ought to be checked. The value is a whitespace delimited set of parameters. The exact value '*' has the special meaning of matching all parameters, and is the default behavior.
        See Also:
        Constant Field Values
      • CHARACTERS_TO_FORBID

        public static final java.lang.String CHARACTERS_TO_FORBID
        The name of the optional Filter init-param specifying what characters are forbidden in the checked request parameters. The value is a whitespace delimited set of such characters.
        See Also:
        Constant Field Values
      • ALLOW_MULTI_VALUED_PARAMETERS

        public static final java.lang.String ALLOW_MULTI_VALUED_PARAMETERS
        The name of the optional Filter init-param specifying whether the checked request parameters are allowed to have multiple values. Allowable values for this init parameter are `true` and `false`.
        See Also:
        Constant Field Values
      • PATTERN_TO_BLOCK

        public static final java.lang.String PATTERN_TO_BLOCK
        Name of the setting to specify a pattern that would be checked against the request URL to block if a successful match is found.
        See Also:
        Constant Field Values
      • ONLY_POST_PARAMETERS

        public static final java.lang.String ONLY_POST_PARAMETERS
        The name of the optional Filter init-param specifying what request parameters ought to be send via POST requests only.
        See Also:
        Constant Field Values
    • Constructor Detail

      • RequestParameterPolicyEnforcementFilter

        public RequestParameterPolicyEnforcementFilter()
    • Method Detail

      • throwIfUnrecognizedParamName

        public static void throwIfUnrecognizedParamName​(java.util.Enumeration initParamNames)
        Examines the Filter init parameter names and throws ServletException if they contain an unrecognized init parameter name.

        This is a stateless static method.

        This method is an implementation detail and is not exposed API. This method is only non-private to allow JUnit testing.

        Parameters:
        initParamNames - init param names, in practice as read from the FilterConfig.
      • parseParametersList

        public static java.util.Set<java.lang.String> parseParametersList​(java.lang.String initParamValue,
                                                                          boolean allowWildcard)
        Parse the whitespace delimited String of parameters to check.

        If the String is null, return the empty set. If the whitespace delimited String contains no tokens, throw IllegalArgumentException. If the sole token is an asterisk, return the empty set. If the asterisk token is encountered among other tokens, throw IllegalArgumentException.

        This method returning an empty Set has the special meaning of "check all parameters".

        This is a stateless static method.

        This method is an implementation detail and is not exposed API. This method is only non-private to allow JUnit testing.

        Parameters:
        initParamValue - null, or a non-blank whitespace delimited list of parameters to check
        allowWildcard - whether a wildcard is allowed instead of the parameters list
        Returns:
        a Set of String names of parameters to check, or an empty set representing check-them-all.
        Throws:
        java.lang.IllegalArgumentException - when the init param value is out of spec
      • parseCharactersToForbid

        public static java.util.Set<java.lang.Character> parseCharactersToForbid​(java.lang.String value)
        Parse a whitespace delimited set of Characters from a String.

        If the String is "none" parse to empty set meaning block no characters. If the String is empty throw, to avoid configurer accidentally configuring not to block any characters.

        Parameters:
        value - value of the init param to parse
        Returns:
        non-null Set of zero or more Characters to block
      • requireNotMultiValued

        public static void requireNotMultiValued​(java.util.Set<java.lang.String> parametersToCheck,
                                                 java.util.Map parameterMap)
        For each parameter to check, verify that it has zero or one value.

        The Set of parameters to check MAY be empty. The parameter map MAY NOT contain any given parameter to check.

        This method is an implementation detail and is not exposed API. This method is only non-private to allow JUnit testing.

        Parameters:
        parametersToCheck - non-null potentially empty Set of String names of parameters
        parameterMap - non-null Map from String name of parameter to String[] values
        Throws:
        java.lang.IllegalStateException - if a parameterToCheck is present in the parameterMap with multiple values.
      • enforceParameterContentCharacterRestrictions

        public static void enforceParameterContentCharacterRestrictions​(java.util.Set<java.lang.String> parametersToCheck,
                                                                        java.util.Set<java.lang.Character> charactersToForbid,
                                                                        java.util.Map parameterMap)
        For each parameter to check, for each value of that parameter, check that the value does not contain forbidden characters.

        This method is an implementation detail and is not exposed API. This method is only non-private to allow JUnit testing.

        Parameters:
        parametersToCheck - Set of String request parameter names to look for
        charactersToForbid - Set of Character characters to forbid
        parameterMap - String to String[] Map, in practice as read from ServletRequest
      • checkOnlyPostParameters

        public static void checkOnlyPostParameters​(java.lang.String method,
                                                   java.util.Map parameterMap,
                                                   java.util.Set<java.lang.String> onlyPostParameters)
        Check that some parameters should only be in POST requests (according to the configuration).
        Parameters:
        method - the method of the request
        parameterMap - all the request parameters
        onlyPostParameters - parameters that should only be in POST requests
      • init

        public void init​(javax.servlet.FilterConfig filterConfig)
        Specified by:
        init in interface javax.servlet.Filter
      • doFilter

        public void doFilter​(javax.servlet.ServletRequest request,
                             javax.servlet.ServletResponse response,
                             javax.servlet.FilterChain chain)
                      throws java.io.IOException,
                             javax.servlet.ServletException
        Specified by:
        doFilter in interface javax.servlet.Filter
        Throws:
        java.io.IOException
        javax.servlet.ServletException
      • destroy

        public void destroy()
        Specified by:
        destroy in interface javax.servlet.Filter