contrib.nodejsscan.host_header_injection.host_header_injection

Author
99
Download Count*
License
Using untrusted Host header for generating dynamic URLs can result in web cache and or password reset poisoning.
Run Locally
Run in CI
Defintion
rules:
- id: host_header_injection
patterns:
- pattern-either:
- pattern-inside: function ($REQ, $RES, ...) {...}
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: |
$X = <... "=~/.*http[s]*:///" + $REQ.host ...>;
- pattern: |
$X = <... "=~/.*http[s]*:///" + $REQ["host"] ...>;
- pattern: |
$X = <... "=~/.*http[s]*:///" + $REQ("host") ...>;
- pattern: |
$X = { $Y: <... "=~/.*http[s]*:///" + $REQ.host ...>};
- pattern: |
$X = { $Y: <... "=~/.*http[s]*:///" + $REQ["host"] ...>};
- pattern: |
$X = { $Y: <... "=~/.*http[s]*:///" + $REQ("host") ...>};
- pattern: |
$Z = $REQ.host;
...
$X = <... "=~/.*http[s]*:///" + $Z ...>;
- pattern: |
$Z = $REQ["host"];
...
$X = <... "=~/.*http[s]*:///" + $Z ...>;
- pattern: |
$Z = $REQ("host");
...
$X = <... "=~/.*http[s]*:///" + $Z ...>;
- pattern: |
$Z = $REQ.host;
...
$X = { $Y: <... "=~/.*http[s]*:///" + $REQ.host ...>};
- pattern: |
$Z = $REQ["host"];
...
$X = { $Y: <... "=~/.*http[s]*:///" + $Z ...>};
- pattern: |
$Z = $REQ("host");
...
$X = { $Y: <... "=~/.*http[s]*:///" + $REQ("host") ...>};
message: Using untrusted Host header for generating dynamic URLs can result in
web cache and or password reset poisoning.
languages:
- javascript
severity: ERROR
metadata:
owasp: A01:2017 - Injection
cwe: "CWE-20: Improper Input Validation"
category: security
technology:
- node.js
- express
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
Examples
host_header_injection.js
// https://www.acunetix.com/blog/articles/automated-detection-of-host-header-attacks/
app.get('/', function (req, res) {
//semgrep string lateral support is pending
var foo = {
text: `reset url: https://${req.host}/password_reset/${token}`
};
//do not match
var x = 'https://' + foo
// do not match
var x = "https://" + req.foo + "/reset" + foo;
// do not match
var x = "https://" + z + "/reset";
// ruleid:host_header_injection
var url = 'http://' + req.host;
// ruleid:host_header_injection
var reset = 'https://' + req.host + '/password_reset';
// ruleid:host_header_injection
var pass = "https://" + req.host + "/reset";
// ruleid:host_header_injection
var z = req.host;
var pass = "https://" + z + "/reset";
// ruleid:host_header_injection
var reset_url = "Reset password: <a href='http://" + req.host + "/reset_pass'>Reset</a>";
// ruleid:host_header_injection
var foo = {
text: 'password: https://' + req.host + '/token/',
token: 'f2131ASDSADASoo',
};
// ruleid:host_header_injection
var foo = {
text: 'reset password: https://' + req['host'] + '/token/',
token: 'f2131ASDSADASoo',
};
// ruleid:host_header_injection
let x = "https://" + req['host'] + "/reset" + foo;
// ruleid:host_header_injection
x = "https://" + req("host") + "/reset" + foo + 'barr' + foo2;
// ruleid:host_header_injection
var foo = {
text: 'reset password: https://' + req.host + '/resettoken/' + foo,
token: 'f2131ASDSADASoo',
};
});
Short Link: https://sg.run/dKA6