From 29803562ebd808a36692c50f45010de4350ffce3 Mon Sep 17 00:00:00 2001 From: "pixeebot[bot]" <104101892+pixeebot[bot]@users.noreply.github.com> Date: Sat, 26 Apr 2025 23:25:03 +0100 Subject: [PATCH] (Snyk) Fixed finding: "Improper Neutralization of CRLF Sequences in HTTP Headers" (#3424) ## Remediation This change fixes "Improper Neutralization of CRLF Sequences in HTTP Headers" (id = java/HttpResponseSplitting) identified by Snyk. ## Details This change ensures that HTTP response header values can't contain newline characters, leaving you vulnerable to HTTP response splitting and other attacks. If malicious users can get newline characters into an HTTP response header, they can inject and forge new header values that look like they came from the server, and trick web gateways, proxies, and browsers. This leads to vulnerabilities like Cross-site Scripting (XSS), HTTP response splitting, and more attacks from there. Our change simply makes sure that if the string passed to be a new response header value is non-null, all the newline characters (CR and LF) will be removed: ```diff + import io.github.pixee.security.Newlines; ... String orderId = getUserOrderId(); - response.setHeader("X-Acme-Order-ID", orderId); + response.setHeader("X-Acme-Order-ID", Newlines.stripAll(orderId)); ``` Note: Many modern application servers will sanitize these values, but it's almost never specified in documentation, and thus there is little guarantee against regression. Given that, we still recommend this practice.
More reading * [https://cwe.mitre.org/data/definitions/113](https://cwe.mitre.org/data/definitions/113) * [https://www.netsparker.com/blog/web-security/crlf-http-header/](https://www.netsparker.com/blog/web-security/crlf-http-header/) * [https://owasp.org/www-community/attacks/HTTP_Response_Splitting](https://owasp.org/www-community/attacks/HTTP_Response_Splitting) * [https://regilero.github.io/security/english/2015/10/04/http_smuggling_in_2015_part_one/](https://regilero.github.io/security/english/2015/10/04/http_smuggling_in_2015_part_one/)
Co-authored-by: pixeebot[bot] <104101892+pixeebot[bot]@users.noreply.github.com> --- .../SPDF/config/security/UserBasedRateLimitingFilter.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/stirling/software/SPDF/config/security/UserBasedRateLimitingFilter.java b/src/main/java/stirling/software/SPDF/config/security/UserBasedRateLimitingFilter.java index 1c725c9f2..7bc0cc9bd 100644 --- a/src/main/java/stirling/software/SPDF/config/security/UserBasedRateLimitingFilter.java +++ b/src/main/java/stirling/software/SPDF/config/security/UserBasedRateLimitingFilter.java @@ -121,7 +121,7 @@ public class UserBasedRateLimitingFilter extends OncePerRequestFilter { if (probe.isConsumed()) { response.setHeader( "X-Rate-Limit-Remaining", - Newlines.stripAll(Long.toString(probe.getRemainingTokens()))); + stripNewlines(Newlines.stripAll(Long.toString(probe.getRemainingTokens())))); filterChain.doFilter(request, response); } else { long waitForRefill = probe.getNanosToWaitForRefill() / 1_000_000_000; @@ -141,4 +141,8 @@ public class UserBasedRateLimitingFilter extends OncePerRequestFilter { .build(); return Bucket.builder().addLimit(limit).build(); } + + private static String stripNewlines(final String s) { + return s.replaceAll("[\n\r]", ""); + } }