After running VeraCode, it reported a following error \"Improper Neutralization of CRLF Sequences in HTTP Headers (\'HTTP Response Splitting\')\" in the following code fragm
I believe the problem is because the line
languageCookie.Value = Server.UrlDecode(Request.QueryString["l"]);
accepts (untrusted) user input (i.e. Request.QueryString["l"]
).
Try adding a function call to remove any carriage returns or line feed characters (including their encoded equivalents like %0d
and %0a
) from that query string parameter before storing it in languageCookie
.
For example, you might try changing that line to:
languageCookie.Value = Server.UrlDecode(Request.QueryString["l"])
.Replace("\r", string.Empty)
.Replace("%0d", string.Empty)
.Replace("%0D", string.Empty)
.Replace("\n", string.Empty)
.Replace("%0a", string.Empty)
.Replace("%0A", string.Empty);
though that should probably be cleaned up a bit (I'm not a C# programmer at this time).
See also
In Asp.Net you have to check for two things first cookies must be httponly .You can specify that in your webconfig
<httpCookies httpOnlyCookies="true"/>
and after that make sure you have santized the that you are saving in your cookies like
HttpCookie cookies=new HttpCookies("key",Sanitizer.GetSafeHtml(value));
This sanitizer class is from ANtixss library. For details you can check this link Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response Splitting') (CWE ID 113)
Description
A function call contains an HTTP response splitting flaw. Writing unsanitized user-supplied input into an HTTP header allows an attacker to manipulate the HTTP response rendered by the browser, leading to cache poisoning and crosssite scripting attacks.
Recommendations
Remove unexpected carriage returns and line feeds from user-supplied data used to construct an HTTP response. Always validate user-supplied input to ensure that it conforms to the expected format, using centralized data validation routines when possible.
Issue Code
response.setHeader(headerKey,headerValue);
response.addHeader(headerKey, headerValue);
Fixed Code
DefaultHTTPUtilities httpUtilities = new DefaultHTTPUtilities();
httpUtilities.setHeader(headerKey,headerValue);
httpUtilities.addHeader(response, headerKey,headerValue);
The easiest way to remove this issue is to use ESAPI httputilities present in esapi jar. You can use
ESAPI.httpUtilities().setHeader(response,param,value);
ESAPI.httpUtilities().addCookies(response, param,value);
and similar methods for other tasks. You will need to have ESAPI.properrties set in you classpath. This is the way we implemented for Java. Same features are available for other languages too.
No additional work is required and it will solve the issue in veracode.
It looks like a false positive as ASP.Net will automatically check the response headers and encode CRLF characters when the configuration option EnableHeaderChecking is true (the default value).This is available since version 2.0 of the .Net framework and will also protect the response header against CRLF chars present in the cookie name.
References:
https://docs.microsoft.com/en-us/dotnet/api/system.web.configuration.httpruntimesection.enableheaderchecking?view=netframework-4.6.2
https://referencesource.microsoft.com/#System.Web/HttpHeaderCollection.cs,e201dcca44935c73
I understand that the scanner cannot trust that the server settings will be correct so I went and did a few tests with a function that replaces any CRLF chars from the string used in the cookie name, but Veracode simply won't accept it.
It seems like the scanner will only accept sanitization code from a pre-defined list of utilities. I did quite a few tests with URLEncode (which will encode the CRLF chars) from a few of the approved utilities but yet no luck.
References:
https://community.veracode.com/s/question/0D53400004DJusECAT/how-to-fix-crlf-http-response-splitting-in-java (though this answer refers to java it includes the link to the list of approved sanitizers, including C#)
https://help.veracode.com/reader/4EKhlLSMHm5jC8P8j3XccQ/IiF_rOE79ANbwnZwreSPGA
One liner to replace all character causing CRLF using StringUtils. It works for me
StringUtils.replaceEach(strForCRLF, new String[] { "\n", "\r","%0d", "%0D", "%0a", "%0A" }, new String[] { "", "", "", "", "", "" });