Skip to content

Commit 46336a5

Browse files
committed
JS: Add HostHeaderPoisoningInEmailGeneration query
1 parent 1b4fc93 commit 46336a5

File tree

4 files changed

+60
-0
lines changed

4 files changed

+60
-0
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* @name Host header poisoning in email generation
3+
* @description Using the HTTP Host header to construct a link in an email can facilitate phishing attacks and leak password reset tokens.
4+
* @kind problem
5+
* @problem.severity error
6+
* @precision high
7+
* @id js/host-header-forgery-in-email-generation
8+
* @tags security
9+
* external/cwe/cwe-640
10+
*/
11+
import javascript
12+
13+
class TaintedHostHeader extends TaintTracking::Configuration {
14+
TaintedHostHeader() { this = "TaintedHostHeader" }
15+
16+
override predicate isSource(DataFlow::Node node) {
17+
exists (HTTP::RequestInputAccess input | node = input |
18+
input.getKind() = "header" and
19+
input.getAHeaderName() = "host")
20+
}
21+
22+
override predicate isSink(DataFlow::Node node) {
23+
exists (EmailSender email | node = email.getABody())
24+
}
25+
}
26+
27+
from TaintedHostHeader taint, DataFlow::Node src, DataFlow::Node sink
28+
where taint.hasFlow(src, sink)
29+
select sink, "Links in this email can be hijacked by poisoning the HTTP host header $@.", src, "here"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| tst.js:17:11:17:113 | `Hi, lo ... token}` | Links in this email can be hijacked by poisoning the HTTP host header $@. | tst.js:17:84:17:91 | req.host | here |
2+
| tst.js:18:11:18:127 | `Hi, lo ... reset.` | Links in this email can be hijacked by poisoning the HTTP host header $@. | tst.js:18:78:18:85 | req.host | here |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Security/CWE-640/HostHeaderPoisoningInEmailGeneration.ql
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
let nodemailer = require('nodemailer');
2+
let express = require('express');
3+
let app = express();
4+
let backend = require('./backend');
5+
6+
app.post('/resetpass', (req, res) => {
7+
let email = req.query.email;
8+
9+
let transport = nodemailer.createTransport({});
10+
11+
let token = backend.getUserSecretResetToken(email);
12+
13+
transport.sendMail({
14+
from: 'webmaster@example.com',
15+
to: email,
16+
subject: 'Forgot password',
17+
text: `Hi, looks like you forgot your password. Click here to reset: https://${req.host}/resettoken/${token}`, // NOT OK
18+
html: `Hi, looks like you forgot your password. Click <a href="https://${req.host}/resettoken/${token}">here</a> to reset.` // NOT OK
19+
});
20+
21+
transport.sendMail({
22+
from: 'webmaster@example.com',
23+
to: email,
24+
subject: 'Forgot password',
25+
text: `Hi, looks like you forgot your password. Click here to reset: https://example.com/resettoken/${token}`, // OK
26+
html: `Hi, looks like you forgot your password. Click <a href="https://example.com/resettoken/${token}">here</a> to reset.` // OK
27+
});
28+
});

0 commit comments

Comments
 (0)