JS: Port an experimental CodeInjection variant to ConfigSig

This commit is contained in:
Asger F
2024-11-28 11:19:52 +01:00
parent 1832e93766
commit 8887ca1722
2 changed files with 55 additions and 61 deletions

View File

@@ -15,13 +15,11 @@
*/
import javascript
import DataFlow
import DataFlow::PathGraph
abstract class Sanitizer extends DataFlow::Node { }
abstract class Barrier extends DataFlow::Node { }
/** A non-first leaf in a string-concatenation. Seen as a sanitizer for dynamic import code injection. */
class NonFirstStringConcatLeaf extends Sanitizer {
class NonFirstStringConcatLeaf extends Barrier {
NonFirstStringConcatLeaf() {
exists(StringOps::ConcatenationRoot root |
this = root.getALeaf() and
@@ -51,39 +49,46 @@ class WorkerThreads extends DataFlow::Node {
}
}
class UrlConstructorLabel extends FlowLabel {
class UrlConstructorLabel extends DataFlow::FlowLabel {
UrlConstructorLabel() { this = "UrlConstructorLabel" }
}
/**
* A taint-tracking configuration for reasoning about code injection vulnerabilities.
*/
class Configuration extends TaintTracking::Configuration {
Configuration() { this = "CodeInjection" }
module CodeInjectionConfig implements DataFlow::StateConfigSig {
class FlowState = DataFlow::FlowLabel;
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
source instanceof ActiveThreatModelSource and label.isTaint()
}
override predicate isSink(DataFlow::Node sink) { sink instanceof DynamicImport }
predicate isSink(DataFlow::Node sink) { sink instanceof DynamicImport }
override predicate isSink(DataFlow::Node sink, FlowLabel label) {
predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
sink instanceof WorkerThreads and label instanceof UrlConstructorLabel
}
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
predicate isBarrier(DataFlow::Node node) { node instanceof Barrier }
override predicate isAdditionalFlowStep(
DataFlow::Node pred, DataFlow::Node succ, FlowLabel predlbl, FlowLabel succlbl
predicate isAdditionalFlowStep(
DataFlow::Node pred, DataFlow::FlowLabel predlbl, DataFlow::Node succ,
DataFlow::FlowLabel succlbl
) {
exists(DataFlow::NewNode newUrl | succ = newUrl |
newUrl = DataFlow::globalVarRef("URL").getAnInstantiation() and
pred = newUrl.getArgument(0)
) and
predlbl instanceof StandardFlowLabel and
predlbl.isDataOrTaint() and
succlbl instanceof UrlConstructorLabel
}
}
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
module CodeInjectionFlow = TaintTracking::GlobalWithState<CodeInjectionConfig>;
import CodeInjectionFlow::PathGraph
from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink
where CodeInjectionFlow::flowPath(source, sink)
select sink.getNode(), source, sink, "This command line depends on a $@.", source.getNode(),
"user-provided value"

View File

@@ -1,49 +1,38 @@
nodes
| test.js:5:11:5:44 | payload |
| test.js:5:21:5:44 | req.que ... rameter |
| test.js:5:21:5:44 | req.que ... rameter |
| test.js:6:9:6:43 | payloadURL |
| test.js:6:22:6:43 | new URL ... + sth) |
| test.js:6:30:6:36 | payload |
| test.js:6:30:6:42 | payload + sth |
| test.js:7:16:7:25 | payloadURL |
| test.js:7:16:7:25 | payloadURL |
| test.js:9:5:9:39 | payloadURL |
| test.js:9:18:9:39 | new URL ... + sth) |
| test.js:9:26:9:32 | payload |
| test.js:9:26:9:38 | payload + sth |
| test.js:10:16:10:25 | payloadURL |
| test.js:10:16:10:25 | payloadURL |
| test.js:17:11:17:44 | payload |
| test.js:17:21:17:44 | req.que ... rameter |
| test.js:17:21:17:44 | req.que ... rameter |
| test.js:18:18:18:24 | payload |
| test.js:18:18:18:24 | payload |
| test.js:19:18:19:24 | payload |
| test.js:19:18:19:30 | payload + sth |
| test.js:19:18:19:30 | payload + sth |
edges
| test.js:5:11:5:44 | payload | test.js:6:30:6:36 | payload |
| test.js:5:11:5:44 | payload | test.js:9:26:9:32 | payload |
| test.js:5:21:5:44 | req.que ... rameter | test.js:5:11:5:44 | payload |
| test.js:5:21:5:44 | req.que ... rameter | test.js:5:11:5:44 | payload |
| test.js:6:9:6:43 | payloadURL | test.js:7:16:7:25 | payloadURL |
| test.js:6:9:6:43 | payloadURL | test.js:7:16:7:25 | payloadURL |
| test.js:6:22:6:43 | new URL ... + sth) | test.js:6:9:6:43 | payloadURL |
| test.js:6:30:6:36 | payload | test.js:6:30:6:42 | payload + sth |
| test.js:6:30:6:42 | payload + sth | test.js:6:22:6:43 | new URL ... + sth) |
| test.js:9:5:9:39 | payloadURL | test.js:10:16:10:25 | payloadURL |
| test.js:9:5:9:39 | payloadURL | test.js:10:16:10:25 | payloadURL |
| test.js:9:18:9:39 | new URL ... + sth) | test.js:9:5:9:39 | payloadURL |
| test.js:9:26:9:32 | payload | test.js:9:26:9:38 | payload + sth |
| test.js:9:26:9:38 | payload + sth | test.js:9:18:9:39 | new URL ... + sth) |
| test.js:17:11:17:44 | payload | test.js:18:18:18:24 | payload |
| test.js:17:11:17:44 | payload | test.js:18:18:18:24 | payload |
| test.js:17:11:17:44 | payload | test.js:19:18:19:24 | payload |
| test.js:17:21:17:44 | req.que ... rameter | test.js:17:11:17:44 | payload |
| test.js:17:21:17:44 | req.que ... rameter | test.js:17:11:17:44 | payload |
| test.js:19:18:19:24 | payload | test.js:19:18:19:30 | payload + sth |
| test.js:19:18:19:24 | payload | test.js:19:18:19:30 | payload + sth |
| test.js:5:11:5:44 | payload | test.js:6:30:6:36 | payload | provenance | |
| test.js:5:11:5:44 | payload | test.js:9:26:9:32 | payload | provenance | |
| test.js:5:21:5:44 | req.que ... rameter | test.js:5:11:5:44 | payload | provenance | |
| test.js:6:9:6:43 | payloadURL | test.js:7:16:7:25 | payloadURL | provenance | |
| test.js:6:22:6:43 | new URL ... + sth) | test.js:6:9:6:43 | payloadURL | provenance | |
| test.js:6:30:6:36 | payload | test.js:6:30:6:42 | payload + sth | provenance | |
| test.js:6:30:6:42 | payload + sth | test.js:6:22:6:43 | new URL ... + sth) | provenance | Config |
| test.js:9:5:9:39 | payloadURL | test.js:10:16:10:25 | payloadURL | provenance | |
| test.js:9:18:9:39 | new URL ... + sth) | test.js:9:5:9:39 | payloadURL | provenance | |
| test.js:9:26:9:32 | payload | test.js:9:26:9:38 | payload + sth | provenance | |
| test.js:9:26:9:38 | payload + sth | test.js:9:18:9:39 | new URL ... + sth) | provenance | Config |
| test.js:17:11:17:44 | payload | test.js:18:18:18:24 | payload | provenance | |
| test.js:17:11:17:44 | payload | test.js:19:18:19:24 | payload | provenance | |
| test.js:17:21:17:44 | req.que ... rameter | test.js:17:11:17:44 | payload | provenance | |
| test.js:19:18:19:24 | payload | test.js:19:18:19:30 | payload + sth | provenance | |
nodes
| test.js:5:11:5:44 | payload | semmle.label | payload |
| test.js:5:21:5:44 | req.que ... rameter | semmle.label | req.que ... rameter |
| test.js:6:9:6:43 | payloadURL | semmle.label | payloadURL |
| test.js:6:22:6:43 | new URL ... + sth) | semmle.label | new URL ... + sth) |
| test.js:6:30:6:36 | payload | semmle.label | payload |
| test.js:6:30:6:42 | payload + sth | semmle.label | payload + sth |
| test.js:7:16:7:25 | payloadURL | semmle.label | payloadURL |
| test.js:9:5:9:39 | payloadURL | semmle.label | payloadURL |
| test.js:9:18:9:39 | new URL ... + sth) | semmle.label | new URL ... + sth) |
| test.js:9:26:9:32 | payload | semmle.label | payload |
| test.js:9:26:9:38 | payload + sth | semmle.label | payload + sth |
| test.js:10:16:10:25 | payloadURL | semmle.label | payloadURL |
| test.js:17:11:17:44 | payload | semmle.label | payload |
| test.js:17:21:17:44 | req.que ... rameter | semmle.label | req.que ... rameter |
| test.js:18:18:18:24 | payload | semmle.label | payload |
| test.js:19:18:19:24 | payload | semmle.label | payload |
| test.js:19:18:19:30 | payload + sth | semmle.label | payload + sth |
subpaths
#select
| test.js:7:16:7:25 | payloadURL | test.js:5:21:5:44 | req.que ... rameter | test.js:7:16:7:25 | payloadURL | This command line depends on a $@. | test.js:5:21:5:44 | req.que ... rameter | user-provided value |
| test.js:10:16:10:25 | payloadURL | test.js:5:21:5:44 | req.que ... rameter | test.js:10:16:10:25 | payloadURL | This command line depends on a $@. | test.js:5:21:5:44 | req.que ... rameter | user-provided value |