Merge pull request #22126 from owen-mc/js/convert-qlref-inline-expectations

JS: Convert qlref tests to inline expectations
This commit is contained in:
Owen Mansel-Chan
2026-07-11 00:24:20 +01:00
committed by GitHub
42 changed files with 158 additions and 147 deletions

View File

@@ -1 +1,2 @@
experimental/Security/CWE-094-dataURL/CodeInjection.ql
query: experimental/Security/CWE-094-dataURL/CodeInjection.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -2,21 +2,21 @@ const { Worker } = require('node:worker_threads');
var app = require('express')();
app.post('/path', async function (req, res) {
const payload = req.query.queryParameter // like: payload = 'data:text/javascript,console.log("hello!");//'
const payload = req.query.queryParameter // $ Source // like: payload = 'data:text/javascript,console.log("hello!");//'
let payloadURL = new URL(payload + sth) // NOT OK
new Worker(payloadURL);
new Worker(payloadURL); // $ Alert
payloadURL = new URL(payload + sth) // NOT OK
new Worker(payloadURL);
new Worker(payloadURL); // $ Alert
payloadURL = new URL(sth + payload) // OK
new Worker(payloadURL);
});
app.post('/path2', async function (req, res) {
const payload = req.query.queryParameter // like: payload = 'data:text/javascript,console.log("hello!");//'
await import(payload) // NOT OK
await import(payload + sth) // NOT OK
const payload = req.query.queryParameter // $ Source // like: payload = 'data:text/javascript,console.log("hello!");//'
await import(payload) // $ Alert // NOT OK
await import(payload + sth) // $ Alert // NOT OK
await import(sth + payload) // OK
});

View File

@@ -1 +1,2 @@
experimental/Security/CWE-099/EnvValueAndKeyInjection.ql
query: experimental/Security/CWE-099/EnvValueAndKeyInjection.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -2,9 +2,9 @@ const http = require('node:http');
http.createServer((req, res) => {
const { EnvValue, EnvKey } = req.body;
process.env[EnvKey] = EnvValue; // NOT OK
process.env[EnvKey] = EnvValue; // NOT OK
const { EnvValue, EnvKey } = req.body; // $ Source
process.env[EnvKey] = EnvValue; // $ Alert // NOT OK
process.env[EnvKey] = EnvValue; // $ Alert // NOT OK
res.end('env has been injected!');
});

View File

@@ -1 +1,2 @@
experimental/Security/CWE-099/EnvValueInjection.ql
query: experimental/Security/CWE-099/EnvValueInjection.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,10 +1,10 @@
const http = require('node:http');
http.createServer((req, res) => {
const { EnvValue } = req.body;
process.env["A_Critical_Env"] = EnvValue; // NOT OK
process.env[AKey] = EnvValue; // NOT OK
process.env.AKey = EnvValue; // NOT OK
const { EnvValue } = req.body; // $ Source
process.env["A_Critical_Env"] = EnvValue; // $ Alert // NOT OK
process.env[AKey] = EnvValue; // $ Alert // NOT OK
process.env.AKey = EnvValue; // $ Alert // NOT OK
res.end('env has been injected!');
});

View File

@@ -10,18 +10,18 @@ function aJWT() {
}
(function () {
const UserToken = aJwt()
const UserToken = aJwt() // $ Alert
// BAD: no signature verification
jwtJsonwebtoken.decode(UserToken) // NOT OK
jwtJsonwebtoken.decode(UserToken) // $ Sink // NOT OK
})();
(function () {
const UserToken = aJwt()
const UserToken = aJwt() // $ Alert
// BAD: no signature verification
jwtJsonwebtoken.decode(UserToken) // NOT OK
jwtJsonwebtoken.verify(UserToken, getSecret(), { algorithms: ["HS256", "none"] }) // NOT OK
jwtJsonwebtoken.decode(UserToken) // $ Sink // NOT OK
jwtJsonwebtoken.verify(UserToken, getSecret(), { algorithms: ["HS256", "none"] }) // $ Sink // NOT OK
})();
(function () {

View File

@@ -1 +1,2 @@
experimental/Security/CWE-347/decodeJwtWithoutVerificationLocalSource.ql
query: experimental/Security/CWE-347/decodeJwtWithoutVerificationLocalSource.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -9,10 +9,10 @@ function aJWT() {
}
(function () {
const UserToken = aJwt()
const UserToken = aJwt() // $ Alert
// no signature verification
jose.decodeJwt(UserToken) // NOT OK
jose.decodeJwt(UserToken) // $ Sink // NOT OK
})();
(async function () {

View File

@@ -10,9 +10,9 @@ function aJWT() {
}
(function () {
const UserToken = aJwt()
const UserToken = aJwt() // $ Alert
// jwt-decode
// no signature verification
jwt_decode(UserToken) // NOT OK
jwt_decode(UserToken) // $ Sink // NOT OK
})();

View File

@@ -10,10 +10,10 @@ function aJWT() {
}
(function () {
const UserToken = aJwt()
const UserToken = aJwt() // $ Alert
// BAD: no signature verification
jwt_simple.decode(UserToken, getSecret(), true); // NOT OK
jwt_simple.decode(UserToken, getSecret(), true); // $ Sink // NOT OK
})();
(function () {

View File

@@ -7,18 +7,18 @@ function getSecret() {
return "A Safe generated random key"
}
app.get('/jwtJsonwebtoken1', (req, res) => {
const UserToken = req.headers.authorization;
const UserToken = req.headers.authorization; // $ Alert
// BAD: no signature verification
jwtJsonwebtoken.decode(UserToken) // NOT OK
jwtJsonwebtoken.decode(UserToken) // $ Sink // NOT OK
})
app.get('/jwtJsonwebtoken2', (req, res) => {
const UserToken = req.headers.authorization;
const UserToken = req.headers.authorization; // $ Alert
// BAD: no signature verification
jwtJsonwebtoken.decode(UserToken) // NOT OK
jwtJsonwebtoken.verify(UserToken, getSecret(), { algorithms: ["HS256", "none"] }) // NOT OK
jwtJsonwebtoken.decode(UserToken) // $ Sink // NOT OK
jwtJsonwebtoken.verify(UserToken, getSecret(), { algorithms: ["HS256", "none"] }) // $ Sink // NOT OK
})
app.get('/jwtJsonwebtoken3', (req, res) => {

View File

@@ -1 +1,2 @@
experimental/Security/CWE-347/decodeJwtWithoutVerification.ql
query: experimental/Security/CWE-347/decodeJwtWithoutVerification.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -8,9 +8,9 @@ function getSecret() {
}
app.get('/jose1', (req, res) => {
const UserToken = req.headers.authorization;
const UserToken = req.headers.authorization; // $ Alert
// no signature verification
jose.decodeJwt(UserToken) // NOT OK
jose.decodeJwt(UserToken) // $ Sink // NOT OK
})

View File

@@ -8,11 +8,11 @@ function getSecret() {
}
app.get('/jwtDecode', (req, res) => {
const UserToken = req.headers.authorization;
const UserToken = req.headers.authorization; // $ Alert
// jwt-decode
// no signature verification
jwt_decode(UserToken) // NOT OK
jwt_decode(UserToken) // $ Sink // NOT OK
})
app.listen(port, () => {

View File

@@ -7,10 +7,10 @@ function getSecret() {
return "A Safe generated random key"
}
app.get('/jwtSimple1', (req, res) => {
const UserToken = req.headers.authorization;
const UserToken = req.headers.authorization; // $ Alert
// no signature verification
jwt_simple.decode(UserToken, getSecret(), true); // NOT OK
jwt_simple.decode(UserToken, getSecret(), true); // $ Sink // NOT OK
})
app.get('/jwtSimple2', (req, res) => {

View File

@@ -1 +1,2 @@
./experimental/Security/CWE-918/SSRF.ql
query: ./experimental/Security/CWE-918/SSRF.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1,2 @@
experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard.ql
query: experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -8,6 +8,6 @@ async function validateUrlHost(host) { // NOT OK
throw new Error('blocked private host');
}
return fetch('http://' + host + '/');
}
} // $ Alert[javascript/ssrf-ipv6-transition-incomplete-guard]
module.exports = { validateUrlHost };

View File

@@ -13,6 +13,6 @@ function checkTargetHost(host) { // NOT OK
throw new Error('blocked internal host');
}
return http.get('http://' + host + '/');
}
} // $ Alert[javascript/ssrf-ipv6-transition-incomplete-guard]
module.exports = { checkTargetHost };

View File

@@ -13,8 +13,8 @@ const app = express();
app.get('/check-with-axios', req => {
// without validation
const url = req.query.url;
axios.get(url); //SSRF
const url = req.query.url; // $ Source
axios.get(url); // $ Alert // SSRF
// validating domain only
const decodedURI = decodeURIComponent(req.query.url);
@@ -22,8 +22,8 @@ app.get('/check-with-axios', req => {
const { hostname } = url.parse(decodedURI);
if (isValidDomain(hostname, validDomains)) {
axios.get(req.query.url); //SSRF
if (isValidDomain(hostname, VALID_DOMAINS)) {
axios.get(req.query.url); // $ Alert // SSRF
}
});
@@ -31,4 +31,4 @@ const isValidDomain = (hostname, validDomains) => (
validDomains.some(domain => (
hostname === domain || hostname.endsWith(`.${domain}`))
)
);
);

View File

@@ -6,7 +6,7 @@ const express = require('express');
const app = express();
app.get('/check-with-axios', validationMiddleware, req => {
axios.get("test.com/" + req.query.tainted); // OK is sanitized by the middleware - False Positive
axios.get("test.com/" + req.query.tainted); // $ SPURIOUS: Alert // OK is sanitized by the middleware - False Positive
});

View File

@@ -16,11 +16,11 @@ app.get('/check-with-axios', req => {
const hardcoded = 'hardcodeado';
axios.get('test.com/' + hardcoded); // OK
axios.get('test.com/' + req.query.tainted); // SSRF
axios.get('test.com/' + req.query.tainted); // $ Alert // SSRF
axios.get('test.com/' + Number(req.query.tainted)); // OK
axios.get('test.com/' + req.user.id); // OK
axios.get('test.com/' + encodeURIComponent(req.query.tainted)); // OK
axios.get(`/addresses/${req.query.tainted}`); // SSRF
axios.get(`/addresses/${req.query.tainted}`); // $ Alert // SSRF
axios.get(`/addresses/${encodeURIComponent(req.query.tainted)}`); // OK
if (Number.isInteger(req.query.tainted)) {
@@ -30,11 +30,11 @@ app.get('/check-with-axios', req => {
if (isValidInput(req.query.tainted)){
axios.get('test.com/' + req.query.tainted); // OK
} else {
axios.get('test.com/' + req.query.tainted); // SSRF
axios.get('test.com/' + req.query.tainted); // $ Alert // SSRF
}
if (doesntCheckAnything(req.query.tainted)) {
axios.get('test.com/' + req.query.tainted); // SSRF
axios.get('test.com/' + req.query.tainted); // $ Alert // SSRF
}
if (isValidPath(req.query.tainted, VALID_PATHS)) {
@@ -42,7 +42,7 @@ app.get('/check-with-axios', req => {
}
let baseURL = require('config').base
axios.get(`${baseURL}${req.query.tainted}`); // SSRF
axios.get(`${baseURL}${req.query.tainted}`); // $ Alert // SSRF
if(!isValidInput(req.query.tainted)) {
return;

View File

@@ -13,32 +13,32 @@ app.get('/check-with-axios', req => {
axios.get("test.com/" + req.query.tainted); // OK
}
if (req.query.tainted.match(/^.*$/)) { // anything
axios.get("test.com/" + req.query.tainted); // SSRF - False Negative
axios.get("test.com/" + req.query.tainted); // $ Alert // SSRF
}
const baseURL = "test.com/"
if (isValidPath(req.params.tainted) ) {
if (isValidPath(req.params.tainted)) {
axios.get(baseURL + req.params.tainted); // OK
}
if (!isValidPath(req.params.tainted) ) {
axios.get(baseURL + req.params.tainted); // SSRF
if (!isValidPath(req.params.tainted)) {
axios.get(baseURL + req.params.tainted); // $ Alert // SSRF
} else {
axios.get(baseURL + req.params.tainted); // OK
}
// Blacklists are not safe
if (!req.query.tainted.match(/^[/\.%]+$/)) {
axios.get("test.com/" + req.query.tainted); // SSRF
axios.get("test.com/" + req.query.tainted); // $ Alert // SSRF
}
if (!isInBlacklist(req.params.tainted) ) {
axios.get(baseURL + req.params.tainted); // SSRF
if (!isInBlacklist(req.params.tainted)) {
axios.get(baseURL + req.params.tainted); // $ Alert // SSRF
}
if (!isValidPath(req.params.tainted)) {
return;
}
axios.get("test.com/" + req.query.tainted); // OK - False Positive
axios.get("test.com/" + req.query.tainted); // $ SPURIOUS: Alert // OK - False Positive
if (req.query.tainted.matchAll(/^[0-9a-z]+$/g)) { // letters and numbers
axios.get("test.com/" + req.query.tainted); // OK
@@ -48,20 +48,20 @@ app.get('/check-with-axios', req => {
}
});
const isValidPath = path => path.match(/^[0-9a-z]+$/);
const isValidPath = path => path.match(/^[0-9a-z]+$/);
const isInBlackList = path => path.match(/^[/\.%]+$/);
const isInBlackList = path => path.match(/^[/\.%]+$/);
app.get('/check-with-axios', req => {
const baseURL = "test.com/"
if (isValidPathMatchAll(req.params.tainted) ) {
if (isValidPathMatchAll(req.params.tainted)) {
axios.get(baseURL + req.params.tainted); // OK
}
if (!isValidPathMatchAll(req.params.tainted) ) {
axios.get(baseURL + req.params.tainted); // NOT OK - SSRF
if (!isValidPathMatchAll(req.params.tainted)) {
axios.get(baseURL + req.params.tainted); // $ Alert // NOT OK - SSRF
} else {
axios.get(baseURL + req.params.tainted); // OK
}
});
const isValidPathMatchAll = path => path.matchAll(/^[0-9a-z]+$/g);
const isValidPathMatchAll = path => path.matchAll(/^[0-9a-z]+$/g);

View File

@@ -12,7 +12,7 @@ app.get("/check-with-axios", req => {
axios.get("test.com/" + req.query.tainted); // OK
}
if (isAlphanumeric(req.query.tainted)) {
axios.get("test.com/" + req.query.tainted); // SSRF
axios.get("test.com/" + req.query.tainted); // $ Alert // SSRF
}
if (validAlphanumeric(req.query.tainted)) {
axios.get("test.com/" + req.query.tainted); // OK
@@ -24,7 +24,7 @@ app.get("/check-with-axios", req => {
axios.get("test.com/" + req.query.tainted); // OK
}
if (wrongValidation(req.query.tainted)) {
axios.get("test.com/" + req.query.tainted); // SSRF
axios.get("test.com/" + req.query.tainted); // $ Alert // SSRF
}
// numbers
@@ -47,25 +47,25 @@ app.get("/check-with-axios", req => {
axios.get("test.com/" + req.query.tainted); // OK
}
if (validHexa(req.query.tainted)) {
axios.get("test.com/" + req.query.tainted); // OK. False Positive
axios.get("test.com/" + req.query.tainted); // $ SPURIOUS: Alert // OK. False Positive
}
// with simple assignation
const numberURL = req.query.tainted;
const numberURL = req.query.tainted; // $ Source
if (validNumber(numberURL)) {
axios.get("test.com/" + numberURL); // OK
}
if (validNumber(numberURL)) {
axios.get("test.com/" + req.query.tainted); // OK. False Positive
axios.get("test.com/" + req.query.tainted); // $ SPURIOUS: Alert // OK. False Positive
}
if (validNumber(req.query.tainted)) {
axios.get("test.com/" + numberURL); // OK. False Positive
axios.get("test.com/" + numberURL); // $ SPURIOUS: Alert // OK. False Positive
}
if (validHexadecimal(req.query.tainted) || validHexaColor(req.query.tainted) ||
validDecimal(req.query.tainted) || validFloat(req.query.tainted) || validInt(req.query.tainted) ||
validNumber(req.query.tainted) || validOctal(req.query.tainted)) {
axios.get("test.com/" + req.query.tainted); // OK. False Positive
if (validHexadecimal(req.query.tainted) || validHexaColor(req.query.tainted) ||
validDecimal(req.query.tainted) || validFloat(req.query.tainted) || validInt(req.query.tainted) ||
validNumber(req.query.tainted) || validOctal(req.query.tainted)) {
axios.get("test.com/" + req.query.tainted); // $ SPURIOUS: Alert // OK. False Positive
}
});
@@ -93,6 +93,6 @@ const validHexaColor = url => validator.isHexColor(url);
const validUUID = url => validator.isUUID(url);
// unsafe validators
const wrongValidation = url => validator.isByteLength(url, {min:4,max:8});
const wrongValidation = url => validator.isByteLength(url, { min: 4, max: 8 });
const isAlphanumeric = url => true;

View File

@@ -1 +1,2 @@
experimental/StandardLibrary/MultipleArgumentsToSetConstructor.ql
query: experimental/StandardLibrary/MultipleArgumentsToSetConstructor.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,4 +1,4 @@
const vowels = new Set('a', 'e', 'i', 'o', 'u');
const vowels = new Set('a', 'e', 'i', 'o', 'u'); // $ Alert
function isVowel(char) {
return vowels.has(char.toLowerCase());

View File

@@ -1,6 +1,6 @@
let xs = [1, 2, 3];
let ys = [4, 5, 6];
new Set(...xs, ...ys); // NOT OK
new Set(...xs, ...ys); // $ Alert // NOT OK
new Set([...xs, ...ys]); // OK
new Set(xs); // OK
new Set(); // OK

View File

@@ -1 +1,2 @@
meta/analysis-quality/UnpromotedRouteHandlerCandidate.ql
query: meta/analysis-quality/UnpromotedRouteHandlerCandidate.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1,2 @@
meta/analysis-quality/UnpromotedRouteSetupCandidate.ql
query: meta/analysis-quality/UnpromotedRouteSetupCandidate.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1 @@
function handler(request, h){}
function handler(request, h){} // $ Alert[js/unpromoted-route-handler-candidate]

View File

@@ -2,14 +2,14 @@ var http = require('http');
http.createServer(function(req, res){});
unknown.createServer(function(req, res){});
unknown.createServer(function(req, res){}); // $ Alert[js/unpromoted-route-setup-candidate]
var createServer = http.createServer;
createServer(function(req, res){});
http.createServer().on("request", function(req, res){});
unknown.on("request", function(req, res){});
unknown.once("request", function(req, res){});
unknown.on("request", function(req, res){}); // $ Alert[js/unpromoted-route-setup-candidate]
unknown.once("request", function(req, res){}); // $ Alert[js/unpromoted-route-setup-candidate]
function getHandler(){
return function(req, res){};

View File

@@ -4,10 +4,10 @@ var app = express();
var route1 = {
method: 'post',
url: '/foo',
middleWares: [function(req, res){}],
middleWares: [function(req, res){}], // $ Alert[js/unpromoted-route-handler-candidate]
handler(req, res) {
}
} // $ Alert[js/unpromoted-route-handler-candidate]
};
app[route1.method](route1.url, route1.middleWares, route1.handler);
@@ -19,14 +19,14 @@ var routes = [
url: '/foo',
handler(req, res) {
}
} // $ Alert[js/unpromoted-route-handler-candidate]
},
{
method: 'post',
url: '/foo',
handler(req, res) {
}
} // $ Alert[js/unpromoted-route-handler-candidate]
}
];
routes.forEach((route) => {
@@ -39,7 +39,7 @@ var route2 = {
url: '/foo',
handler(req, res) {
}
} // $ Alert[js/unpromoted-route-handler-candidate]
};
app[route2.method.toLowerCase()](route2.url, route2.handler);
@@ -49,13 +49,13 @@ var route3 = {
url: '/foo',
handler(req, res) {
}
} // $ Alert[js/unpromoted-route-handler-candidate]
};
function wrap(f){
return function(req, res){
f(req);
}
} // $ Alert[js/unpromoted-route-handler-candidate]
}
app[route3.method](route3.url, wrap(route3.handler));
confuse(wrap); // confuse the type inference

View File

@@ -3,9 +3,9 @@ var app = express();
app.get('/some/path', function(req, res) {})
someOtherApp.get('/some/path', function(req, res) {})
someOtherApp.get('/some/path', function(req, res) {}) // $ Alert[js/unpromoted-route-setup-candidate]
someOtherApp.get('/some/path', function(request, response) {})
someOtherApp.get('/some/path', function(request, response) {}) // $ Alert[js/unpromoted-route-setup-candidate]
someOtherApp.get('/some/path', function(r) {
r.acceptsCharsets()
@@ -27,23 +27,23 @@ someOtherApp.get('/some/path', function(r, s, n) {
n('route')
})
someOtherApp.delete('/some/path', function(req, res) {})
someOtherApp.delete('/some/path', function(req, res) {}) // $ Alert[js/unpromoted-route-setup-candidate]
someOtherApp.get('/some/path',
function(req, res) {},
function(req, res) {})
function(req, res) {}) // $ Alert[js/unpromoted-route-setup-candidate]
someOtherApp.get('/some/path', [
function(req, res) {},
function(req, res) {}
])
]) // $ Alert[js/unpromoted-route-setup-candidate]
someOtherApp.get('/some/path',
function() {},
function(req, res) {})
function(req, res) {}) // $ Alert[js/unpromoted-route-setup-candidate]
function f(req, res) {}
function f(req, res) {} // $ Alert[js/unpromoted-route-handler-candidate]
function f(ctx, next) {
ctx.acceptsCharsets()
@@ -51,25 +51,25 @@ function f(ctx, next) {
function f(req, res) {
req()
}
} // $ Alert[js/unpromoted-route-handler-candidate]
function called(req,res) {
}
} // $ Alert[js/unpromoted-route-handler-candidate]
called()
function f(req,res) {
return;
}
} // $ Alert[js/unpromoted-route-handler-candidate]
function f(req,res) {
return x;
}
} // $ Alert[js/unpromoted-route-handler-candidate]
function adHocTestsFor_HeuristicRouteHandler() {
function rh_dead(req, res) {
}
} // $ Alert[js/unpromoted-route-handler-candidate]
function rh_flowToSetup(req, res) {
@@ -84,7 +84,7 @@ function adHocTestsFor_HeuristicRouteHandler() {
function rh_flowToHeuristicSetup(req, res) {
}
unknownApp.get('/some/path', rh_flowToHeuristicSetup)
unknownApp.get('/some/path', rh_flowToHeuristicSetup) // $ Alert[js/unpromoted-route-setup-candidate]
}
function adHocTestsFor_HeuristicRouteSetups() {
@@ -93,22 +93,22 @@ function adHocTestsFor_HeuristicRouteSetups() {
}
app.get('/some/path', rh);
unknownApp.get('/some/path', rh);
unknownApp.get('/some/path', rh); // $ Alert[js/unpromoted-route-setup-candidate]
unknownApp.get('/some/path', [rh]);
unknownApp.get('/some/path', [rh]); // $ Alert[js/unpromoted-route-setup-candidate]
unknownApp.get('/some/path', unknown);
unknownApp.get('/some/path', [unknown]);
unknownApp.get('/some/path', unknown, rh);
unknownApp.get('/some/path', unknown, rh); // $ Alert[js/unpromoted-route-setup-candidate]
}
function adHocTestsFor_HeuristicRouteHandler_withTracking() {
function get_rh_dead() {
return function rh_dead(req, res) {
}
} // $ Alert[js/unpromoted-route-handler-candidate]
}
var rh_dead = get_rh_dead();
@@ -134,7 +134,7 @@ function adHocTestsFor_HeuristicRouteHandler_withTracking() {
}
}
var rh_flowToHeuristicSetup = get_rh_flowToHeuristicSetup();
unknownApp.get('/some/path', rh_flowToHeuristicSetup)
unknownApp.get('/some/path', rh_flowToHeuristicSetup) // $ Alert[js/unpromoted-route-setup-candidate]
}
function adHocTestsFor_HeuristicRouteSetups_withTracking() {
@@ -146,13 +146,13 @@ function adHocTestsFor_HeuristicRouteSetups_withTracking() {
var rh = get_rh();
app.get('/some/path', rh);
unknownApp.get('/some/path', rh);
unknownApp.get('/some/path', rh); // $ Alert[js/unpromoted-route-setup-candidate]
unknownApp.get('/some/path', [rh]);
unknownApp.get('/some/path', [rh]); // $ Alert[js/unpromoted-route-setup-candidate]
unknownApp.get('/some/path', unknown);
unknownApp.get('/some/path', [unknown]);
unknownApp.get('/some/path', unknown, rh);
unknownApp.get('/some/path', unknown, rh); // $ Alert[js/unpromoted-route-setup-candidate]
}

View File

@@ -1 +1,2 @@
Security/CWE-094/CodeInjection.ql
query: Security/CWE-094/CodeInjection.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -12,11 +12,11 @@ app.get('/ejs', (req, res) => {
},
dataInStringLiteral: req.query.dataInStringLiteral,
dataInStringLiteralRaw: req.query.dataInStringLiteralRaw,
dataInGeneratedCode: req.query.dataInGeneratedCode,
dataInGeneratedCode: req.query.dataInGeneratedCode, // $ Source
dataInGeneratedCodeRaw: req.query.dataInGeneratedCodeRaw,
backslashSink1: req.query.backslashSink1,
backslashSink1: req.query.backslashSink1, // $ Source
backslashSink2: req.query.backslashSink2,
dataInEventHandlerString: req.query.dataInEventHandlerString,
dataInEventHandlerString: req.query.dataInEventHandlerString, // $ Source
dataInEventHandlerStringRaw: req.query.dataInEventHandlerStringRaw,
});
});
@@ -31,11 +31,11 @@ app.get('/hbs', (req, res) => {
},
dataInStringLiteral: req.query.dataInStringLiteral,
dataInStringLiteralRaw: req.query.dataInStringLiteralRaw,
dataInGeneratedCode: req.query.dataInGeneratedCode,
dataInGeneratedCode: req.query.dataInGeneratedCode, // $ Source
dataInGeneratedCodeRaw: req.query.dataInGeneratedCodeRaw,
backslashSink1: req.query.backslashSink1,
backslashSink1: req.query.backslashSink1, // $ Source
backslashSink2: req.query.backslashSink2,
dataInEventHandlerString: req.query.dataInEventHandlerString,
dataInEventHandlerString: req.query.dataInEventHandlerString, // $ Source
dataInEventHandlerStringRaw: req.query.dataInEventHandlerStringRaw,
});
});
@@ -50,20 +50,20 @@ app.get('/njk', (req, res) => {
},
dataInStringLiteral: req.query.dataInStringLiteral,
dataInStringLiteralRaw: req.query.dataInStringLiteralRaw,
dataInGeneratedCode: req.query.dataInGeneratedCode,
dataInGeneratedCodeRaw: req.query.dataInGeneratedCodeRaw,
dataInGeneratedCode: req.query.dataInGeneratedCode, // $ Source
dataInGeneratedCodeRaw: req.query.dataInGeneratedCodeRaw, // $ Source
dataInGeneratedCodeJsonRaw: req.query.dataInGeneratedCodeJsonRaw,
backslashSink1: req.query.backslashSink1,
backslashSink1: req.query.backslashSink1, // $ Source
backslashSink2: req.query.backslashSink2,
dataInEventHandlerString: req.query.dataInEventHandlerString,
dataInEventHandlerStringRaw: req.query.dataInEventHandlerStringRaw,
dataInEventHandlerString: req.query.dataInEventHandlerString, // $ Source
dataInEventHandlerStringRaw: req.query.dataInEventHandlerStringRaw, // $ Source
});
});
app.get('/angularjs', (req, res) => {
res.render('angularjs_sinks', {
escapedHtml: req.query.escapedHtml,
rawHtml: req.query.rawHtml,
escapedHtml: req.query.escapedHtml, // $ Source
rawHtml: req.query.rawHtml, // $ Source
});
});

View File

@@ -1,5 +1,5 @@
<div>
<%= escapedHtml %>
<%- rawHtml %>
<%= escapedHtml %> <!-- $ Alert -->
<%- rawHtml %> <!-- $ Alert -->
</div>
<div ng-click="blah()"></div>

View File

@@ -1,7 +1,7 @@
<html>
<body ng-app="foo">
<%= escapedHtml %>
<%- rawHtml %>
<%= escapedHtml %> <!-- $ Alert -->
<%- rawHtml %> <!-- $ Alert -->
<% include angularjs_include %>
</body>

View File

@@ -10,15 +10,15 @@
var dataInStringLiteral = "<%= dataInStringLiteral %>";
var dataInStringLiteralRaw = "<%- dataInStringLiteralRaw %>";
var dataInGeneratedCode = <%= dataInGeneratedCode %>;
var dataInGeneratedCode = <%= dataInGeneratedCode %>; // $ Alert
var dataInGeneratedCodeRaw = <%- dataInGeneratedCodeRaw %>;
init("<%= backslashSink1 %>", "<%= backslashSink2 %>");
init("<%= backslashSink1 %>", "<%= backslashSink2 %>"); // $ Alert
var mustache = "{{ rawHtml }}";
</script>
<button onclick="doSomething('<%= dataInEventHandlerString %>')">Click me</button>
<button onclick="doSomething('<%= dataInEventHandlerString %>')">Click me</button> <!-- $ Alert -->
<button onclick="doSomething('<%- dataInEventHandlerStringRaw %>')">Click me</button>
<%- include('ejs_include1', { foo: rawHtml }) _%>

View File

@@ -22,15 +22,15 @@
var dataInStringLiteral = "{{ dataInStringLiteral }}";
var dataInStringLiteralRaw = "{{{ dataInStringLiteralRaw }}}";
var dataInGeneratedCode = {{ dataInGeneratedCode }};
var dataInGeneratedCode = {{ dataInGeneratedCode }}; // $ Alert
var dataInGeneratedCodeRaw = {{{ dataInGeneratedCodeRaw }}};
init("{{ backslashSink1 }}", "{{ backslashSink2 }}");
init("{{ backslashSink1 }}", "{{ backslashSink2 }}"); // $ Alert
var ejs = "<%= rawHtml %>";
</script>
<button onclick="doSomething('{{ dataInEventHandlerString }}')">Click me</button>
<button onclick="doSomething('{{ dataInEventHandlerString }}')">Click me</button> <!-- $ Alert -->
<button onclick="doSomething('{{{ dataInEventHandlerStringRaw }}}')">Click me</button>
</body>
</html>

View File

@@ -10,16 +10,16 @@
var dataInStringLiteral = "{{ dataInStringLiteral }}";
var dataInStringLiteralRaw = "{{ dataInStringLiteralRaw | safe }}";
var dataInGeneratedCode = {{ dataInGeneratedCode }};
var dataInGeneratedCodeRaw = {{ dataInGeneratedCodeRaw | safe }};
var dataInGeneratedCode = {{ dataInGeneratedCode }}; // $ Alert
var dataInGeneratedCodeRaw = {{ dataInGeneratedCodeRaw | safe }}; // $ Alert
var dataInGeneratedCodeJsonRaw = {{ dataInGeneratedCodeJsonRaw | json | safe }};
init("{{ backslashSink1 }}", "{{ backslashSink2 }}");
init("{{ backslashSink1 }}", "{{ backslashSink2 }}"); // $ Alert
var ejs = "<%= rawHtml %>";
</script>
<button onclick="doSomething('{{ dataInEventHandlerString }}')">Click me</button>
<button onclick="doSomething('{{ dataInEventHandlerStringRaw | safe }}')">Click me</button>
<button onclick="doSomething('{{ dataInEventHandlerString }}')">Click me</button> <!-- $ Alert -->
<button onclick="doSomething('{{ dataInEventHandlerStringRaw | safe }}')">Click me</button> <!-- $ Alert -->
</body>
</html>

View File

@@ -21,7 +21,7 @@
controller: notInjected7
};
function injected8(name){} // OK - false negative: we do not track through properties
function injected8(name){} // $ MISSING: Alert // false negative: we do not track through properties
var obj8 = {
controller: injected8
};