mirror of
https://github.com/github/codeql.git
synced 2026-04-24 16:25:15 +02:00
JavaScript: Improve query help for js/server-side-unvalidated-url-redirection.
This commit is contained in:
@@ -16,6 +16,10 @@ To guard against untrusted URL redirection, it is advisable to avoid putting use
|
||||
directly into a redirect URL. Instead, maintain a list of authorized
|
||||
redirects on the server; then choose from that list based on the user input provided.
|
||||
</p>
|
||||
<p>
|
||||
If this is not possible, then the user input should be validated in some other way,
|
||||
for example by verifying that the target URL is on the same host as the current page.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
@@ -32,6 +36,13 @@ before doing the redirection:
|
||||
</p>
|
||||
|
||||
<sample src="examples/ServerSideUrlRedirectGood.js"/>
|
||||
|
||||
<p>
|
||||
Alternatively, we can check that the target URL does not redirect to a different host:
|
||||
</p>
|
||||
|
||||
<sample src="examples/ServerSideUrlRedirectGood2.js"/>
|
||||
|
||||
</example>
|
||||
|
||||
<references>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const app = require("express")();
|
||||
|
||||
app.get('/some/path', function(req, res) {
|
||||
app.get('/redirect', function(req, res) {
|
||||
// BAD: a request parameter is incorporated without validation into a URL redirect
|
||||
res.redirect(req.param("target"));
|
||||
res.redirect(req.params["target"]);
|
||||
});
|
||||
|
||||
@@ -2,9 +2,12 @@ const app = require("express")();
|
||||
|
||||
const VALID_REDIRECT = "http://cwe.mitre.org/data/definitions/601.html";
|
||||
|
||||
app.get('/some/path', function(req, res) {
|
||||
app.get('/redirect', function(req, res) {
|
||||
// GOOD: the request parameter is validated against a known fixed string
|
||||
let target = req.param("target");
|
||||
if (VALID_REDIRECT === target)
|
||||
let target = req.params["target"]
|
||||
if (VALID_REDIRECT === target) {
|
||||
res.redirect(target);
|
||||
} else {
|
||||
res.redirect("/");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
const app = require("express")();
|
||||
|
||||
function isLocalUrl(url) {
|
||||
return url.startsWith("/") && !url.startsWith("//") && !url.startsWith("/\\");
|
||||
}
|
||||
|
||||
app.get('/redirect', function(req, res) {
|
||||
// GOOD: check that we don't redirect to a different host
|
||||
let target = req.params["target"];
|
||||
if (isLocalUrl(target)) {
|
||||
res.redirect(target);
|
||||
} else {
|
||||
res.redirect("/");
|
||||
}
|
||||
});
|
||||
@@ -1,4 +1,7 @@
|
||||
nodes
|
||||
| ServerSideUrlRedirect.js:5:16:5:35 | req.params["target"] |
|
||||
| ServerSideUrlRedirect.js:5:16:5:35 | req.params["target"] |
|
||||
| ServerSideUrlRedirect.js:5:16:5:35 | req.params["target"] |
|
||||
| express.js:7:16:7:34 | req.param("target") |
|
||||
| express.js:7:16:7:34 | req.param("target") |
|
||||
| express.js:7:16:7:34 | req.param("target") |
|
||||
@@ -114,6 +117,7 @@ nodes
|
||||
| react-native.js:9:26:9:32 | tainted |
|
||||
| react-native.js:9:26:9:32 | tainted |
|
||||
edges
|
||||
| ServerSideUrlRedirect.js:5:16:5:35 | req.params["target"] | ServerSideUrlRedirect.js:5:16:5:35 | req.params["target"] |
|
||||
| express.js:7:16:7:34 | req.param("target") | express.js:7:16:7:34 | req.param("target") |
|
||||
| express.js:12:26:12:44 | req.param("target") | express.js:12:26:12:44 | req.param("target") |
|
||||
| express.js:27:7:27:34 | target | express.js:33:18:33:23 | target |
|
||||
@@ -211,6 +215,7 @@ edges
|
||||
| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted |
|
||||
| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted |
|
||||
#select
|
||||
| ServerSideUrlRedirect.js:5:16:5:35 | req.params["target"] | ServerSideUrlRedirect.js:5:16:5:35 | req.params["target"] | ServerSideUrlRedirect.js:5:16:5:35 | req.params["target"] | Untrusted URL redirection depends on a $@. | ServerSideUrlRedirect.js:5:16:5:35 | req.params["target"] | user-provided value |
|
||||
| express.js:7:16:7:34 | req.param("target") | express.js:7:16:7:34 | req.param("target") | express.js:7:16:7:34 | req.param("target") | Untrusted URL redirection depends on a $@. | express.js:7:16:7:34 | req.param("target") | user-provided value |
|
||||
| express.js:12:26:12:44 | req.param("target") | express.js:12:26:12:44 | req.param("target") | express.js:12:26:12:44 | req.param("target") | Untrusted URL redirection depends on a $@. | express.js:12:26:12:44 | req.param("target") | user-provided value |
|
||||
| express.js:33:18:33:23 | target | express.js:27:16:27:34 | req.param("target") | express.js:33:18:33:23 | target | Untrusted URL redirection depends on a $@. | express.js:27:16:27:34 | req.param("target") | user-provided value |
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
const app = require("express")();
|
||||
|
||||
app.get('/redirect', function(req, res) {
|
||||
// BAD: a request parameter is incorporated without validation into a URL redirect
|
||||
res.redirect(req.params["target"]);
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
const app = require("express")();
|
||||
|
||||
const VALID_REDIRECT = "http://cwe.mitre.org/data/definitions/601.html";
|
||||
|
||||
app.get('/redirect', function(req, res) {
|
||||
// GOOD: the request parameter is validated against a known fixed string
|
||||
let target = req.params["target"]
|
||||
if (VALID_REDIRECT === target) {
|
||||
res.redirect(target);
|
||||
} else {
|
||||
res.redirect("/");
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
const app = require("express")();
|
||||
|
||||
function isLocalUrl(url) {
|
||||
return url.startsWith("/") && !url.startsWith("//") && !url.startsWith("/\\");
|
||||
}
|
||||
|
||||
app.get('/redirect', function(req, res) {
|
||||
// GOOD: check that we don't redirect to a different host
|
||||
let target = req.params["target"];
|
||||
if (isLocalUrl(target)) {
|
||||
res.redirect(target);
|
||||
} else {
|
||||
res.redirect("/");
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user