Skip to content

Commit 17d139c

Browse files
committed
JS: Add qhelp
1 parent d92430b commit 17d139c

File tree

3 files changed

+69
-0
lines changed

3 files changed

+69
-0
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
6+
<overview>
7+
<p>
8+
Using a case-sensitive regular expression path in a middleware route enables an attacker to bypass that middleware
9+
when accessing an endpoint with a case-insensitive path.
10+
</p>
11+
</overview>
12+
13+
<recommendation>
14+
<p>
15+
When using a regular expression as a middlware path, make sure the regular expression is
16+
case insensitive by adding the <code>i</code> flag.
17+
</p>
18+
</recommendation>
19+
20+
<example>
21+
<p>
22+
The following example restricts access to paths in the <code>/admin</code> path to users logged in as
23+
an administrator:
24+
</p>
25+
<sample src="examples/CaseSensitiveMiddlewarePath.js" />
26+
<p>
27+
A path such as <code>/admin/users/45</code> can only be accessed by an administrator. However, the path
28+
<code>/ADMIN/USERS/45</code> can be accessed by anyone because the upper-case path doesn't match the case-sensitive regular expression, whereas
29+
Express considers it to match the path string <code>/admin/users</code>.
30+
</p>
31+
<p>
32+
The issue can be fixed by adding the <code>i</code> flag to the regular expression:
33+
</p>
34+
<sample src="examples/CaseSensitiveMiddlewarePathGood.js" />
35+
</example>
36+
37+
<references>
38+
<li>
39+
MDN
40+
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#advanced_searching_with_flags">Regular Expression Flags</a>.
41+
</li>
42+
</references>
43+
</qhelp>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
const app = require('express')();
2+
3+
app.use(/\/admin\/.*/, (req, res, next) => {
4+
if (!req.user.isAdmin) {
5+
res.status(401).send('Unauthorized');
6+
} else {
7+
next();
8+
}
9+
});
10+
11+
app.get('/admin/users/:id', (req, res) => {
12+
res.send(app.database.users[req.params.id]);
13+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
const app = require('express')();
2+
3+
app.use(/\/admin\/.*/i, (req, res, next) => {
4+
if (!req.user.isAdmin) {
5+
res.status(401).send('Unauthorized');
6+
} else {
7+
next();
8+
}
9+
});
10+
11+
app.get('/admin/users/:id', (req, res) => {
12+
res.send(app.database.users[req.params.id]);
13+
});

0 commit comments

Comments
 (0)