I am using org.owasp.esapi in a java project. I am using the ESAPI.encoder().forHTML() method for encoding the user input but this method encodes the '&' to "&" but I do not want to change the '&' so I want to whitelist the '&' character that the encoder does not encode it. So how can I change the ESAPI.properties file such that the encoder will whitelist this method.

please help me to find the properties which whitelist any character.

2

There are 2 best solutions below

2
Kevin W. Wall On

ESAPI intentionally doesn't provide an easy way for you to white-list additional characters. Many have asked for that without realizing the ramifications. (In this case, it could allow for attacks that come from double-encoding.) So the only way to do that is to write your own encoder to replace org.owasp.esapi.reference.DefaultEncoder by specifying your own class for the ESAPI.Encoder property and we certainly do NOT recommend you doing that.

That said, if I may ask, what specific problem are you trying to solve here? Usually there is just a specific field or two where some character they are required to allow to be rendered is one that is normally blocked and it comes out to be double-encoded so '&' shows up as '&' for instance. If you explain what the specific context is that you want to do, we can suggest alternatives that would be less dangerous than what you are suggesting.

0
Kevin W. Wall On

This is an alternative approach. I do not recommend this because it is difficult to get correct. Have an expert at XSS check review your code and then do some extensive testing using DAST tools or manual pen testing using something like OWASP ZAP or Portswigger Burp Suite.

Warning: I did not check any of this code or even try to compile it, so you have been warned!

Second to the warning, I don't recall ever seeing a legitimate address that required a '&', so perhaps this is just some edge use case that I don't fully understand. But as I said in my first answer, there is a reason why ESAPI does not allow users to specify their own set of "immune" characters that are excluded from being encoded.

That said, you can do this if you wish to write a custom encoder, but depending on what other special characters you want you 'address' to allow (e.g., probably '-', ',', and '.', but hopefully not ';' or '%'), there may be a simpler way and that is to just use strict allow-list custom validation.

You can do that by adding a custom regular expression to your ESAPI 'validation.properties' file. For example, maybe something like this:

# Allow any combination of upper or lower case alphabetic chars, digits, space,
# common, period, ampersand, or hypen. Require a length between 8 and 256 characters.
Validator.Address="^[A-Za-z0-9 ,.&-]{8,256}$"

(Note: If you want '-' to be allowed, you MUST place it as the very first or very last character in the character class of your regex.)

Then you would use that regex in combination with either one of the Validator.getValidInput or Validator.isValidInput methods.

String allowedAddr = ESAPI.validator().getValidInput(
                        "Customer address",     // descriptive name for logs
                        addressParam,           // actual user input
                        "Address"               // name of your regex
                        false,                  // no null / empty strings
                        true);                  // canonicalize input before validation

Just keep in mind that the safety of this very much depends on what characters you want to allow in your address.

Also, there is a possibility that the last argument may need to be 'false' as there is a possibility that an '&' in your addressParam input may trigger it depending on the settings of your ESAPI.properties files.