JavaScript: Improve query help for js/server-side-unvalidated-url-redirection.

This commit is contained in:
Max Schaefer
2023-07-18 15:55:11 +01:00
parent ab1f341aa6
commit 7823ff968c
8 changed files with 73 additions and 5 deletions

View File

@@ -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>

View File

@@ -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"]);
});

View File

@@ -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("/");
}
});

View File

@@ -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("/");
}
});

View File

@@ -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 |

View File

@@ -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"]);
});

View File

@@ -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("/");
}
});

View File

@@ -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("/");
}
});