How to fix the separation of HTTP response vulnerabilities using ESAPI

after the last starts of findbugs (FB) have been started, he complains about the vulnerability: security vulnerability - HTTP response. The following code launches it:

String referrer = req.getParameter("referrer"); if (referrer != null) { launchURL += "&referrer="+(referrer); } resp.sendRedirect(launchURL); 

Basically, the http 'referrer' parameter contains the URL that the browser returns to when you click the return button in our application. It is added to the URL as a parameter. After a little research, I know that I need to sanitize the referrer URL. After a bit more research, I found the esapi project, which seems to offer such functionality:

 //1st canonicalize import org.owasp.esapi.Encoder; import org.owasp.esapi.Validator; import org.owasp.esapi.reference.DefaultEncoder; import org.owasp.esapi.reference.DefaultValidator; [...] Encoder encoder = new DefaultEncoder(new ArrayList<String>()); String cReferrer = encoder.canonicalize(referrer); 

However, I did not understand how to detect, for example. jscript code or other material that is not relevant to the referrer url. So how can I achieve this with esapi?

I tried:

 Validator validator = new DefaultValidator(encoder); validator.isValidInput("Redirect URL",referrer,"HTTPParameterValue",512,false); 

however this does not work. I need a function that leads to:

http://www.google.com (ok)

http://www.google.com/login?dest=http://google.com/%0D%0ALocation : javascript:% 0D% 0A% 0D% 0Aalert (document.cookie) (does not work)

Or is it enough to invoke the following statement?

 encoder.encodeForHTMLAttribute(referrer); 

Any help was appreciated.

+4
source share
4 answers

Here is my final decision, if anyone is interested. I canonicalize first, and then the URL decodes the string. If CR or LF (\ n \ r) exists, I just cut the rest of this potential attack string, starting with \ n or \ r.

 String sanitize(String url) throws EncodingException{ Encoder encoder = new DefaultEncoder(new ArrayList<String>()); //first canonicalize String clean = encoder.canonicalize(url).trim(); //then url decode clean = encoder.decodeFromURL(clean); //detect and remove any existent \r\n == %0D%0A == CRLF to prevent HTTP Response Splitting int idxR = clean.indexOf('\r'); int idxN = clean.indexOf('\n'); if(idxN >= 0 || idxR>=0){ if(idxN>idxR){ //just cut off the part after the LF clean = clean.substring(0,idxN-1); } else{ //just cut off the part after the CR clean = clean.substring(0,idxR-1); } } //re-encode again return encoder.encodeForURL(clean); } 

Theoretically, I could later check the value against the 'HTTPParameterValue' regex, which is defined in ESAPI.properties, however he did not like the colon in http: //, and I have not examined it yet.

And one more note after testing: the most modern browser currently (Firefox> 3.6, Chrome, IE10, etc.) detects this vulnerability and does not execute code ...

+6
source

I would suggest a whitelist method in which you check the referrer string for valid characters only. Regex would be a good option.

EDIT:

The org.owasp.esapi.reference.DefaultEncoder class you are org.owasp.esapi.reference.DefaultEncoder does not actually encode anything. Take a look at the source code of the encodeForHTMLAttribute(referrer) method here on grepcode . A typical URL encoding (carriage return encoding and line feed) will not help either .

Thus, the path forward will be the device of some validation logic that validates a valid character set. Here is another insightful article .

+1
source

I think you have the right idea, but you are using the wrong encoder. The value of the Referer [sic] header is really a URL, not an HTML attribute, so you really want to use:

encoder.encodeForURL(referrer);

Kevin

+1
source

The accepted answer will not work if there is "\ n \ r" in the line. Example: If I have a line: "This is str\n\rstr" , it returns "This is str\nstr"

Corrected version of the answer above:

  String sanitizeCarriageReturns(String value) { int idxR = value.indexOf('\r'); int idxN = value.indexOf('\n'); if (idxN >= 0 || idxR >= 0) { if ((idxN > idxR && idxR<0) || (idxR > idxN && idxR>=0)) { value = value.substring(0, idxN); } else if (idxN < idxR){ value = value.substring(0, idxR); } } return value; } 
0
source

Source: https://habr.com/ru/post/1479725/


All Articles