Skip to content

Commit b143e14

Browse files
committed
Intial support for partial queries for js
1 parent 09b52a0 commit b143e14

File tree

4 files changed

+140
-0
lines changed

4 files changed

+140
-0
lines changed

javascript/lib/ghsl/Utils.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ private import semmle.javascript.security.dataflow.CommandInjectionCustomization
66
private import semmle.javascript.security.dataflow.CodeInjectionCustomizations
77
private import semmle.javascript.security.dataflow.LogInjectionQuery as LogInjection
88
private import semmle.javascript.security.dataflow.NosqlInjectionCustomizations
9+
private import semmle.javascript.security.dataflow.SqlInjectionCustomizations
910
private import semmle.javascript.security.dataflow.Xss as Xss
1011
private import semmle.javascript.security.dataflow.XxeCustomizations
1112

@@ -77,6 +78,8 @@ class AllSinks extends DataFlow::Node {
7778
sink = "log-injection" or
7879
this instanceof NosqlInjection::Sink and
7980
sink = "nosql-injection" or
81+
this instanceof SqlInjection::Sink and
82+
sink = "sql-injection" or
8083
this instanceof Xss::Shared::Sink and
8184
sink = "xss" or
8285
this instanceof Xxe::Sink and
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* @name Remote Sources
3+
* @kind problem
4+
* @problem.severity note
5+
* @precision low
6+
* @id js/debugging/remote-sources
7+
* @tags debugging
8+
*/
9+
10+
import javascript
11+
12+
// ==========================================================================
13+
// Helper Predicates
14+
// ==========================================================================
15+
16+
/**
17+
* Filter results to a specific file and line number
18+
*
19+
* **Examples:**
20+
*
21+
* ```
22+
* filterByLocation(sources, "db.js", 1)
23+
* // or we don't care about the line numbers
24+
* filterByLocation(sources, "db.js", _)
25+
* ```
26+
*/
27+
predicate filterByLocation(DataFlow::Node node, string relative_path, int linenumber) {
28+
node.getLocation().getFile().getRelativePath() = relative_path and
29+
node.getLocation().getStartLine() = linenumber
30+
}
31+
32+
33+
// ==========================================================================
34+
// Sources
35+
// ==========================================================================
36+
37+
/**
38+
* All Sources (Remote and Local)
39+
*/
40+
final class AllSources extends RemoteSources, LocalSources { }
41+
42+
/**
43+
* Remote Sources (HTTP frameworks, etc)
44+
*/
45+
class RemoteSources extends ThreatModelSource {
46+
RemoteSources() { this.getThreatModel() = "remote" }
47+
}
48+
49+
/**
50+
* Local Sources (CLI arguments, Filesystem, etc)
51+
*/
52+
class LocalSources extends ThreatModelSource {
53+
LocalSources() { this.getThreatModel() = "local" }
54+
}
55+
56+
from RemoteSources sources
57+
// where
58+
// // Filter results to a specific file
59+
// filterByLocation(sources, "app.js", _)
60+
select sources, "Remote Sources"
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* @name Partial Path Query from Sink
3+
* @kind path-problem
4+
* @problem.severity warning
5+
* @security-severity 1.0
6+
* @sub-severity low
7+
* @precision low
8+
* @id js/debugging/partial-path-from-sink
9+
* @tags debugging
10+
*/
11+
12+
import javascript
13+
import ghsl
14+
import DataFlow
15+
16+
// Partial Graph
17+
module PartialFlowConfig implements DataFlow::ConfigSig {
18+
predicate isSource(DataFlow::Node source) { any() }
19+
20+
predicate isSink(DataFlow::Node sink) { sink instanceof AllSinks }
21+
}
22+
23+
int explorationLimit() { result = 10 }
24+
25+
private module PartialFlows = DataFlow::Global<PartialFlowConfig>;
26+
27+
private module PartialFlowsGraph = PartialFlows::FlowExplorationRev<explorationLimit/0>;
28+
29+
private import PartialFlowsGraph::PartialPathGraph
30+
31+
from PartialFlowsGraph::PartialPathNode source, PartialFlowsGraph::PartialPathNode sink
32+
where
33+
/// Only show sinks from a certain file
34+
//filterByLocation(sink.getNode(), "index.js", _) and
35+
/// Only show sources that match our criteria
36+
//checkSource(source.getNode()) and
37+
/// Partial Path
38+
PartialFlowsGraph::partialFlow(source, sink, _)
39+
select sink.getNode(), source, sink, "Partial Graph $@.", source.getNode(), "user-provided value"
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* @name Partial Path Query from Source
3+
* @kind path-problem
4+
* @problem.severity warning
5+
* @security-severity 1.0
6+
* @sub-severity low
7+
* @precision low
8+
* @id js/debugging/partial-path-from-source
9+
* @tags debugging
10+
*/
11+
12+
import javascript
13+
import ghsl
14+
import DataFlow
15+
16+
// Partial Graph
17+
module PartialFlowConfig implements DataFlow::ConfigSig {
18+
predicate isSource(DataFlow::Node source) {
19+
source instanceof AllSources
20+
}
21+
22+
predicate isSink(DataFlow::Node sink) { none() }
23+
}
24+
25+
int explorationLimit() { result = 10 }
26+
27+
private module PartialFlows = DataFlow::Global<PartialFlowConfig>;
28+
29+
private module PartialFlowsGraph = PartialFlows::FlowExplorationFwd<explorationLimit/0>;
30+
31+
private import PartialFlowsGraph::PartialPathGraph
32+
33+
from PartialFlowsGraph::PartialPathNode source, PartialFlowsGraph::PartialPathNode sink
34+
where
35+
/// Filter by location
36+
// filterByLocation(source.getNode(), "main.js", _) and
37+
PartialFlowsGraph::partialFlow(source, sink, _)
38+
select sink.getNode(), source, sink, "Partial Graph $@.", source.getNode(), "user-provided value"

0 commit comments

Comments
 (0)