Skip to content

Commit c879654

Browse files
committed
JS: add qhelp
1 parent 8d3ac39 commit c879654

File tree

3 files changed

+84
-0
lines changed

3 files changed

+84
-0
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
2+
<qhelp>
3+
4+
<overview>
5+
<p>
6+
Using the HTTP Host header to construct a link in an email can facilitate phishing attacks and leak password reset tokens.
7+
A malicious user can send an HTTP request to the targeted web site, but with a Host header that refers to his own web site.
8+
This means the emails will be sent out to potential victims, originating from a server they trust but with
9+
links leading to a malicious web site.
10+
</p>
11+
<p>
12+
If the email contains a password reset link, and should the victim click the link, the secret reset token will be leaked to the attacker.
13+
Using the leaked token, the attacker can then construct the real reset link and use it to change the victim's password.
14+
</p>
15+
</overview>
16+
17+
<recommendation>
18+
<p>
19+
Obtain the server's host name from a configuration file and avoid relying on the Host header.
20+
</p>
21+
</recommendation>
22+
23+
<example>
24+
<p>
25+
The following example uses the <code>req.host</code> to generate a password reset link.
26+
This value is derived from the Host header, and can thus be set to anything by an attacker:
27+
</p>
28+
<sample src="examples/HostHeaderPoisoningInEmailGeneration.js"/>
29+
30+
<p>
31+
To ensure the link refers to the correct web site, get the host name from a configuration file:
32+
</p>
33+
<sample src="examples/HostHeaderPoisoningInEmailGenerationGood.js"/>
34+
</example>
35+
36+
<references>
37+
<li>
38+
Mitre:
39+
<a href="https://cwe.mitre.org/data/definitions/640.html">CWE-640: Weak Password Recovery Mechanism for Forgotten Password</a>.
40+
</li>
41+
<li>
42+
Ian Muscat:
43+
<a href="https://www.acunetix.com/blog/articles/automated-detection-of-host-header-attacks/">What is a Host Header Attack?</a>.
44+
</li>
45+
</references>
46+
</qhelp>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
let nodemailer = require('nodemailer');
2+
let express = require('express');
3+
let backend = require('./backend');
4+
5+
let app = express();
6+
7+
let config = JSON.parse(fs.readFileSync('config.json', 'utf8'));
8+
9+
app.post('/resetpass', (req, res) => {
10+
let email = req.query.email;
11+
let transport = nodemailer.createTransport(config.smtp);
12+
let token = backend.getUserSecretResetToken(email);
13+
transport.sendMail({
14+
from: 'webmaster@example.com',
15+
to: email,
16+
subject: 'Forgot password',
17+
text: `Forgot your password?. Click here to reset: https://${req.host}/resettoken/${token}`,
18+
});
19+
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
let nodemailer = require('nodemailer');
2+
let express = require('express');
3+
let backend = require('./backend');
4+
5+
let app = express();
6+
7+
let config = JSON.parse(fs.readFileSync('config.json', 'utf8'));
8+
9+
app.post('/resetpass', (req, res) => {
10+
let email = req.query.email;
11+
let transport = nodemailer.createTransport(config.smtp);
12+
let token = backend.getUserSecretResetToken(email);
13+
transport.sendMail({
14+
from: 'webmaster@example.com',
15+
to: email,
16+
subject: 'Forgot password',
17+
text: `Forgot your password?. Click here to reset: https://${config.hostname}/resettoken/${token}`,
18+
});
19+
});

0 commit comments

Comments
 (0)