mirror of
https://github.com/github/codeql.git
synced 2025-12-17 09:13:20 +01:00
302 lines
11 KiB
JavaScript
302 lines
11 KiB
JavaScript
function m1() {
|
|
const flowThrough = mkSummary("Argument[0]", "ReturnValue");
|
|
sink(flowThrough(source())); // NOT OK
|
|
sink(flowThrough(source() + "x")); // OK - we are not tracking taint in this test
|
|
sink(flowThrough("x")); // OK
|
|
}
|
|
|
|
function m2() {
|
|
const flowIntoProp = mkSummary("Argument[0]", "ReturnValue.Member[prop]");
|
|
sink(flowIntoProp(source()).prop); // NOT OK
|
|
sink(flowIntoProp(source()).prop2); // OK
|
|
sink(flowIntoProp(source())); // OK
|
|
}
|
|
|
|
function m3() {
|
|
const flowOutOfProp = mkSummary("Argument[0].Member[prop]", "ReturnValue");
|
|
sink(flowOutOfProp({ prop: source() })); // NOT OK
|
|
sink(flowOutOfProp({ prop2: source() })); // OK
|
|
sink(flowOutOfProp(source())); // OK
|
|
|
|
const obj = {};
|
|
obj.prop = source();
|
|
sink(flowOutOfProp(obj)); // NOT OK
|
|
sink(obj); // OK
|
|
sink(obj.prop); // NOT OK
|
|
}
|
|
|
|
function m4() {
|
|
const flowIntoArrayElement = mkSummary("Argument[0]", "ReturnValue.ArrayElement");
|
|
sink(flowIntoArrayElement(source()).pop()); // NOT OK
|
|
sink(flowIntoArrayElement(source())[0]); // NOT OK
|
|
sink(flowIntoArrayElement(source())[Math.random()]); // NOT OK
|
|
sink(flowIntoArrayElement(source()).prop); // OK
|
|
}
|
|
|
|
function m5() {
|
|
const flowOutOfInnerCallback = mkSummary("Argument[0].Parameter[0].Argument[0]", "ReturnValue");
|
|
sink(flowOutOfInnerCallback(cb => { cb(source()); })); // NOT OK [INCONSISTENCY]
|
|
}
|
|
|
|
async function m6() {
|
|
const flowOutOfPromise = mkSummary("Argument[0].Awaited", "ReturnValue");
|
|
const flowIntoPromise = mkSummary("Argument[0]", "ReturnValue.Awaited");
|
|
|
|
sink(flowOutOfPromise(flowIntoPromise(source()))); // NOT OK (although the synchronous flow is technically not possible)
|
|
|
|
let data = { prop: source() };
|
|
sink(flowOutOfPromise(flowIntoPromise(data)).prop); // NOT OK
|
|
sink(flowOutOfPromise(flowIntoPromise(flowIntoPromise(data))).prop); // NOT OK
|
|
sink(flowOutOfPromise(flowOutOfPromise(flowIntoPromise(data))).prop); // NOT OK
|
|
sink(flowOutOfPromise(data).prop); // NOT OK - because Awaited allows pass-through of a non-promise value
|
|
sink(flowIntoPromise(data).prop); // OK - promise object does not have the 'prop' property
|
|
|
|
sink(flowOutOfPromise(Promise.resolve(source()))); // NOT OK
|
|
sink(flowOutOfPromise(Promise.resolve("safe").then(x => source()))); // NOT OK
|
|
sink(flowOutOfPromise(Promise.resolve("safe").then(x => "safe"))); // OK
|
|
sink(flowOutOfPromise(Promise.resolve(source()).then(x => "safe"))); // OK
|
|
|
|
sink(flowOutOfPromise(Promise.reject(source()))); // OK
|
|
sink(flowOutOfPromise(Promise.reject(source()).then(x => "safe", y => y))); // NOT OK
|
|
sink(flowOutOfPromise(Promise.reject(source()).then(x => x, y => "safe"))); // OK
|
|
sink(flowOutOfPromise(Promise.reject("safe").then(x => x, y => y))); // OK
|
|
|
|
sink(flowOutOfPromise(Promise.reject(source()))); // OK
|
|
sink(flowOutOfPromise(Promise.reject(source()).catch(err => err))); // NOT OK
|
|
sink(flowOutOfPromise(Promise.reject(source()).catch(err => "safe"))); // OK
|
|
sink(flowOutOfPromise(Promise.reject("safe").catch(err => err))); // OK
|
|
|
|
sink(flowOutOfPromise(Promise.reject(source()).then(x => "safe").catch(err => err))); // NOT OK
|
|
|
|
sink(flowOutOfPromise(Promise.reject(source()).finally(() => "safe").catch(err => err))); // NOT OK
|
|
sink(flowOutOfPromise(Promise.resolve(source()).finally(() => "safe").then(err => err))); // NOT OK
|
|
sink(flowOutOfPromise(Promise.reject("safe").finally(() => { throw source() }).catch(err => err))); // NOT OK
|
|
|
|
Promise.resolve("safe")
|
|
.then(x => { throw source(); })
|
|
.catch(err => {
|
|
sink(err); // NOT OK
|
|
});
|
|
|
|
Promise.resolve("safe")
|
|
.then(x => { throw source(); })
|
|
.then(x => "safe")
|
|
.catch(err => {
|
|
sink(err); // NOT OK
|
|
});
|
|
|
|
sink(await flowIntoPromise(source())); // NOT OK
|
|
flowIntoPromise(source()).then(value => sink(value)); // NOT OK
|
|
sink(await flowIntoPromise(flowIntoPromise(source()))); // NOT OK
|
|
|
|
async function makePromise() {
|
|
return source();
|
|
}
|
|
sink(flowOutOfPromise(makePromise())); // NOT OK
|
|
|
|
let taintedPromise = new Promise((resolve, reject) => resolve(source()));
|
|
sink(flowOutOfPromise(taintedPromise)); // NOT OK
|
|
|
|
new Promise((resolve, reject) => resolve(source())).then(x => sink(x)); // NOT OK
|
|
new Promise((resolve, reject) => resolve(source())).catch(err => sink(err)); // OK
|
|
new Promise((resolve, reject) => reject(source())).then(x => sink(x)); // OK
|
|
new Promise((resolve, reject) => reject(source())).catch(err => sink(err)); // NOT OK
|
|
|
|
Promise.all([
|
|
flowIntoPromise(source()),
|
|
source(),
|
|
"safe"
|
|
]).then(([x1, x2, x3]) => {
|
|
sink(x1); // NOT OK
|
|
sink(x2); // NOT OK
|
|
sink(x3); // OK
|
|
});
|
|
}
|
|
|
|
function m8() {
|
|
const flowOutOfCallback = mkSummary("Argument[0].ReturnValue", "ReturnValue");
|
|
|
|
sink(flowOutOfCallback(() => source())); // NOT OK
|
|
sink(flowOutOfCallback((source))); // OK
|
|
|
|
function sourceCallback() {
|
|
return source();
|
|
}
|
|
sink(flowOutOfCallback(sourceCallback)); // NOT OK
|
|
}
|
|
|
|
function m9() {
|
|
const flowIntoCallback = mkSummary("Argument[0]", "Argument[1].Parameter[0]");
|
|
|
|
sink(flowIntoCallback(source(), x => sink(x))); // NOT OK
|
|
sink(flowIntoCallback("safe", x => sink(x))); // OK
|
|
sink(flowIntoCallback(source(), x => ignore(x))); // OK
|
|
sink(flowIntoCallback("safe", x => ignore(x))); // OK
|
|
}
|
|
|
|
function m10() {
|
|
const flowThroughCallback = mkSummary([
|
|
["Argument[0]", "Argument[1].Parameter[0]"],
|
|
["Argument[1].ReturnValue", "ReturnValue"]
|
|
]);
|
|
|
|
sink(flowThroughCallback(source(), x => x)); // NOT OK
|
|
sink(flowThroughCallback(source(), x => "safe")); // OK
|
|
sink(flowThroughCallback("safe", x => x)); // OK
|
|
sink(flowThroughCallback("safe", x => "safe")); // OK
|
|
}
|
|
|
|
function m11() {
|
|
const flowFromSideEffectOnParameter = mkSummary("Argument[0].Parameter[0].Member[prop]", "ReturnValue");
|
|
|
|
let data = flowFromSideEffectOnParameter(param => {
|
|
param.prop = source();
|
|
});
|
|
sink(data); // NOT OK
|
|
|
|
function manullyWritten(param) {
|
|
param.prop = source();
|
|
}
|
|
let obj = {};
|
|
manullyWritten(obj);
|
|
sink(obj.prop); // NOT OK
|
|
}
|
|
|
|
async function m13() {
|
|
async function testStoreBack(x) {
|
|
(await x).prop = source();
|
|
}
|
|
const obj = {};
|
|
const promise = Promise.resolve(obj);
|
|
testStoreBack(promise);
|
|
sink(obj.prop); // NOT OK [INCONSISTENCY]
|
|
sink(promise.prop); // OK [INCONSISTENCY]
|
|
sink((await promise).prop); // NOT OK
|
|
|
|
const obj2 = {};
|
|
testStoreBack(obj2);
|
|
sink(obj2.prop);; // NOT OK
|
|
}
|
|
|
|
function m14() {
|
|
const flowOutOfAnyArgument = mkSummary("Argument[0..]", "ReturnValue");
|
|
sink(flowOutOfAnyArgument(source())); // NOT OK
|
|
sink(flowOutOfAnyArgument(source(), "safe", "safe")); // NOT OK
|
|
sink(flowOutOfAnyArgument("safe", source(), "safe")); // NOT OK
|
|
sink(flowOutOfAnyArgument("safe", "safe", source())); // NOT OK
|
|
sink(flowOutOfAnyArgument("safe", "safe", "safe")); // OK
|
|
|
|
const flowOutOfAnyArgumentExceptFirst = mkSummary("Argument[1..]", "ReturnValue");
|
|
sink(flowOutOfAnyArgumentExceptFirst(source())); // OK
|
|
sink(flowOutOfAnyArgumentExceptFirst(source(), "safe", "safe")); // OK
|
|
sink(flowOutOfAnyArgumentExceptFirst("safe", source(), "safe")); // NOT OK
|
|
sink(flowOutOfAnyArgumentExceptFirst("safe", "safe", source())); // NOT OK
|
|
sink(flowOutOfAnyArgumentExceptFirst("safe", "safe", "safe")); // OK
|
|
|
|
const flowIntoAnyParameter = mkSummary("Argument[0]", "Argument[1].Parameter[0..]");
|
|
flowIntoAnyParameter(source(), (x1, x2, x3) => sink(x1)); // NOT OK
|
|
flowIntoAnyParameter(source(), (x1, x2, x3) => sink(x2)); // NOT OK
|
|
flowIntoAnyParameter(source(), (x1, x2, x3) => sink(x3)); // NOT OK
|
|
|
|
const flowIntoAnyParameterExceptFirst = mkSummary("Argument[0]", "Argument[1].Parameter[1..]");
|
|
flowIntoAnyParameterExceptFirst(source(), (x1, x2, x3) => sink(x1)); // OK
|
|
flowIntoAnyParameterExceptFirst(source(), (x1, x2, x3) => sink(x2)); // NOT OK
|
|
flowIntoAnyParameterExceptFirst(source(), (x1, x2, x3) => sink(x3)); // NOT OK
|
|
}
|
|
|
|
function m15() {
|
|
const array = [];
|
|
array.push("safe", "safe", source());
|
|
sink(array.pop()); // NOT OK
|
|
|
|
const array2 = [];
|
|
array2.push(source());
|
|
array2.push("safe");
|
|
array2.push("safe");
|
|
array2.forEach(x => sink(x)); // NOT OK
|
|
|
|
const array3 = [];
|
|
array3.push(...[source()]);
|
|
array3.forEach(x => sink(x)); // NOT OK
|
|
|
|
const array4 = [source()];
|
|
array4 = Array.prototype.slice.call(array4);
|
|
sink(array4.pop()); // NOT OK
|
|
|
|
[source()].forEach((value, index, array) => { sink(array.pop()) }); // NOT OK
|
|
const array5 = [source()];
|
|
array5.forEach((value, index, array) => { sink(array.pop()) }); // NOT OK
|
|
["safe"].forEach((value, index, array) => { sink(array.pop()) }); // OK
|
|
}
|
|
|
|
function m16() {
|
|
const array0 = [source(), 'safe', 'safe'];
|
|
sink(array0[0]); // NOT OK
|
|
sink(array0[1]); // OK
|
|
sink(array0[2]); // OK
|
|
|
|
const array1 = ['safe', source(), 'safe'];
|
|
sink(array1[0]); // OK
|
|
sink(array1[1]); // NOT OK
|
|
sink(array1[2]); // OK
|
|
|
|
const array2 = ['safe', 'safe', source()];
|
|
sink(array2[0]); // OK
|
|
sink(array2[1]); // OK
|
|
sink(array2[2]); // NOT OK
|
|
}
|
|
|
|
function m17() {
|
|
const map = new Map();
|
|
map.set('foo', source());
|
|
map.set('bar', 'safe');
|
|
|
|
sink(map.get('foo')); // NOT OK
|
|
sink(map.get('bar')); // OK
|
|
sink(map.get(getUnkown())); // NOT OK
|
|
|
|
const map2 = new Map();
|
|
map2.set(getUnkown(), source());
|
|
sink(map2.get('foo')); // NOT OK
|
|
sink(map2.get('bar')); // NOT OK
|
|
sink(map2.get(getUnkown())); // NOT OK
|
|
|
|
const map3 = new Map();
|
|
map3.set('foo', source());
|
|
map3.forEach(value => sink(value)); // NOT OK
|
|
for (let [key, value] of map3) {
|
|
sink(value); // NOT OK
|
|
}
|
|
}
|
|
|
|
function m18() {
|
|
const staticParam0 = mkSummary("Argument[0]", "ReturnValue");
|
|
const staticParam1 = mkSummary("Argument[1]", "ReturnValue");
|
|
const dynamicParam0 = mkSummary("Argument[0..]", "ReturnValue");
|
|
const dynamicParam1 = mkSummary("Argument[1..]", "ReturnValue");
|
|
|
|
sink(staticParam0(...[source()])); // NOT OK
|
|
sink(staticParam0(...["safe", source()])); // OK
|
|
sink(staticParam0(...[source(), "safe", ])); // NOT OK
|
|
sink(staticParam0("safe", ...[source()])); // OK
|
|
sink(staticParam0(source(), ...["safe"])); // NOT OK
|
|
|
|
sink(staticParam1(...[source()])); // OK
|
|
sink(staticParam1(...["safe", source()])); // NOT OK
|
|
sink(staticParam1(...[source(), "safe", ])); // OK
|
|
sink(staticParam1("safe", ...[source()])); // NOT OK
|
|
sink(staticParam1(source(), ...["safe"])); // OK
|
|
|
|
sink(dynamicParam0(...[source()])); // NOT OK
|
|
sink(dynamicParam0(...["safe", source()])); // NOT OK
|
|
sink(dynamicParam0(...[source(), "safe", ])); // NOT OK
|
|
sink(dynamicParam0("safe", ...[source()])); // NOT OK
|
|
sink(dynamicParam0(source(), ...["safe"])); // NOT OK
|
|
|
|
sink(dynamicParam1(...[source()])); // OK
|
|
sink(dynamicParam1(...["safe", source()])); // NOT OK
|
|
sink(dynamicParam1(...[source(), "safe", ])); // OK
|
|
sink(dynamicParam1("safe", ...[source()])); // NOT OK
|
|
sink(dynamicParam1(source(), ...["safe"])); // OK
|
|
}
|