Merge pull request #11672 from asgerf/js/extensions

JS: Add data extension sinks
This commit is contained in:
Asger F
2022-12-13 15:34:11 +01:00
committed by GitHub
19 changed files with 122 additions and 0 deletions

View File

@@ -11,6 +11,10 @@ module NoSql {
/** Gets an expression that is interpreted as a code operator in this query. */
DataFlow::Node getACodeOperator() { none() }
}
private class QueryFromModel extends Query {
QueryFromModel() { this = ModelOutput::getASinkNode("nosql-injection").asSink() }
}
}
/** DEPRECATED: Alias for NoSql */

View File

@@ -235,4 +235,8 @@ module ClientSideUrlRedirect {
this = NextJS::nextRouter().getAMemberCall(["push", "replace"]).getArgument(0)
}
}
private class SinkFromModel extends Sink {
SinkFromModel() { this = ModelOutput::getASinkNode("url-redirection").asSink() }
}
}

View File

@@ -410,4 +410,8 @@ module CodeInjection {
/** DEPRECATED: Alias for JsonStringifySanitizer */
deprecated class JSONStringifySanitizer = JsonStringifySanitizer;
private class SinkFromModel extends Sink {
SinkFromModel() { this = ModelOutput::getASinkNode("code-injection").asSink() }
}
}

View File

@@ -50,4 +50,8 @@ module CommandInjection {
class SystemCommandExecutionSink extends Sink, DataFlow::ValueNode {
SystemCommandExecutionSink() { this = any(SystemCommandExecution sys).getACommandArgument() }
}
private class SinkFromModel extends Sink {
SinkFromModel() { this = ModelOutput::getASinkNode("command-line-injection").asSink() }
}
}

View File

@@ -342,4 +342,8 @@ module DomBasedXss {
outcome = super.getPolarity()
}
}
private class SinkFromModel extends Sink {
SinkFromModel() { this = ModelOutput::getASinkNode("html-injection").asSink() }
}
}

View File

@@ -150,4 +150,8 @@ module ReflectedXss {
this.(Http::RequestHeaderAccess).getAHeaderName() = "referer"
}
}
private class SinkFromModel extends Sink {
SinkFromModel() { this = ModelOutput::getASinkNode("html-injection").asSink() }
}
}

View File

@@ -73,4 +73,12 @@ module RequestForgery {
pred = url.getArgument(0)
)
}
private class SinkFromModel extends Sink {
SinkFromModel() { this = ModelOutput::getASinkNode("request-forgery").asSink() }
override DataFlow::Node getARequest() { result = this }
override string getKind() { result = "endpoint" }
}
}

View File

@@ -62,4 +62,8 @@ module ServerSideUrlRedirect {
)
}
}
private class SinkFromModel extends Sink {
SinkFromModel() { this = ModelOutput::getASinkNode("url-redirection").asSink() }
}
}

View File

@@ -946,4 +946,8 @@ module TaintedPath {
)
)
}
private class SinkFromModel extends Sink {
SinkFromModel() { this = ModelOutput::getASinkNode("path-injection").asSink() }
}
}

View File

@@ -49,4 +49,8 @@ module UnsafeDeserialization {
)
}
}
private class SinkFromModel extends Sink {
SinkFromModel() { this = ModelOutput::getASinkNode("unsafe-deserialization").asSink() }
}
}

View File

@@ -0,0 +1,7 @@
commandInjectionSinks
| execa.example.js:2:7:2:9 | cmd |
sqlInjectionSinks
| connection.example.ts:4:20:4:20 | q |
| connection.example.ts:9:18:9:18 | q |
remoteFlowSources
| message.example.js:1:46:1:50 | event |

View File

@@ -0,0 +1,11 @@
import javascript
private import semmle.javascript.security.dataflow.CommandInjectionCustomizations
private import semmle.javascript.security.dataflow.SqlInjectionCustomizations
query predicate commandInjectionSinks(DataFlow::Node node) {
node instanceof CommandInjection::Sink
}
query predicate sqlInjectionSinks(DataFlow::Node node) { node instanceof SqlInjection::Sink }
query predicate remoteFlowSources(RemoteFlowSource node) { any() }

View File

@@ -0,0 +1,9 @@
import { Connection } from "@example/mysql";
function submit(connection: Connection, q: string) {
connection.query(q); // <-- add 'q' as a SQL injection sink
}
import { getConnection } from "@example/db";
let connection = getConnection();
connection.query(q); // <-- add 'q' as a SQL injection sink

View File

@@ -0,0 +1,20 @@
extensions:
- addsTo:
pack: codeql/javascript-all
extensible: sinkModel
data:
- [
"@example/mysql.Connection",
"Member[query].Argument[0]",
"sql-injection",
]
- addsTo:
pack: codeql/javascript-all
extensible: typeModel
data:
- [
"@example/mysql.Connection",
"@example/db",
"Member[getConnection].ReturnValue",
]

View File

@@ -0,0 +1,2 @@
import { shell } from "@example/execa";
shell(cmd);

View File

@@ -0,0 +1,10 @@
extensions:
- addsTo:
pack: codeql/javascript-all
extensible: sinkModel
data:
- [
"@example/execa",
"Member[shell].Argument[0]",
"command-line-injection",
]

View File

@@ -0,0 +1,7 @@
window.addEventListener("message", function (event) {
let data = event.data; // <-- add 'event.data' as a taint source
});
window.addEventListener("onclick", function (event) {
let data = event.data; // <-- 'event.data' should not be a taint source
});

View File

@@ -0,0 +1,10 @@
extensions:
- addsTo:
pack: codeql/javascript-all
extensible: sourceModel
data:
- [
"global",
"Member[addEventListener].WithStringArgument[0=message].Argument[1].Parameter[0].Member[data]",
"remote-flow",
]

View File

@@ -5,3 +5,5 @@ dependencies:
codeql/javascript-queries: ${workspace}
extractor: javascript
tests: .
dataExtensions:
- library-tests/DataExtensions/*.model.yml