JavaScript: Add flow summary extraction queries.

This commit is contained in:
Max Schaefer
2018-07-30 16:33:48 +01:00
parent 6d893d4be7
commit f4fed3657d
17 changed files with 605 additions and 1 deletions

View File

@@ -0,0 +1,36 @@
/**
* Imports the standard library and all taint-tracking configuration classes from the security queries.
*/
import javascript
import semmle.javascript.security.dataflow.BrokenCryptoAlgorithm
import semmle.javascript.security.dataflow.CleartextLogging
import semmle.javascript.security.dataflow.CleartextStorage
import semmle.javascript.security.dataflow.ClientSideUrlRedirect
import semmle.javascript.security.dataflow.CodeInjection
import semmle.javascript.security.dataflow.CommandInjection
import semmle.javascript.security.dataflow.ConditionalBypass
import semmle.javascript.security.dataflow.CorsMisconfigurationForCredentials
import semmle.javascript.security.dataflow.DifferentKindsComparisonBypass
import semmle.javascript.security.dataflow.DomBasedXss as DomBasedXss
import semmle.javascript.security.dataflow.FileAccessToHttp
import semmle.javascript.security.dataflow.HardcodedCredentials
import semmle.javascript.security.dataflow.InsecureRandomness
import semmle.javascript.security.dataflow.InsufficientPasswordHash
import semmle.javascript.security.dataflow.NosqlInjection
import semmle.javascript.security.dataflow.ReflectedXss as ReflectedXss
import semmle.javascript.security.dataflow.RegExpInjection
import semmle.javascript.security.dataflow.RemotePropertyInjection
import semmle.javascript.security.dataflow.RequestForgery
import semmle.javascript.security.dataflow.ServerSideUrlRedirect
import semmle.javascript.security.dataflow.SqlInjection
import semmle.javascript.security.dataflow.StackTraceExposure
import semmle.javascript.security.dataflow.StoredXss as StoredXss
import semmle.javascript.security.dataflow.TaintedFormatString
import semmle.javascript.security.dataflow.TaintedPath
import semmle.javascript.security.dataflow.TypeConfusionThroughParameterTampering
import semmle.javascript.security.dataflow.UnsafeDeserialization
import semmle.javascript.security.dataflow.XmlBomb
import semmle.javascript.security.dataflow.XpathInjection
import semmle.javascript.security.dataflow.Xxe

View File

@@ -0,0 +1,32 @@
/**
* @name Extract flow step summaries
* @description Extracts flow step summaries, that is, tuples `(p1, lbl1, p2, lbl2, cfg)`
* representing the fact that data with flow label `lbl1` may flow from a
* user-controlled exit node of portal `p1` to an escaping entry node of portal `p2`,
* and have label `lbl2` at that point. Moreover, the path from `p1` to `p2` contains
* no sanitizers specified by configuration `cfg`.
* @kind flow-step-summary
* @id js/step-summary-extraction
*/
import AllConfigurations
import PortalExitSource
import PortalEntrySink
from TaintTracking::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink,
Portal p1, Portal p2, DataFlow::FlowLabel lbl1, DataFlow::FlowLabel lbl2
where cfg.hasFlowPath(source, sink) and
p1 = source.getNode().(PortalExitSource).getPortal() and
p2 = sink.getNode().(PortalEntrySink).getPortal() and
lbl1 = sink.getPathSummary().getStartLabel() and
lbl2 = sink.getPathSummary().getEndLabel() and
// avoid constructing infeasible paths
sink.getPathSummary().hasCall() = false and
sink.getPathSummary().hasReturn() = false and
// restrict to steps flow function parameters to returns
p1.(ParameterPortal).getBasePortal() = p2.(ReturnPortal).getBasePortal() and
// restrict to data/taint flow
lbl1 instanceof DataFlow::StandardFlowLabel
select p1.toString(), lbl1.toString(),
p2.toString(), lbl2.toString(),
cfg.toString()

View File

@@ -0,0 +1,19 @@
/**
* @name Extract sink summaries
* @description Extracts sink summaries, that is, tuples `(p, lbl, cfg)` representing the fact
* that data with flow label `lbl` may flow from a user-controlled exit node of portal
* `p` to a known sink for configuration `cfg`.
* @kind sink-summary
* @id js/sink-summary-extraction
*/
import AllConfigurations
import PortalExitSource
from TaintTracking::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink,
Portal p
where cfg.hasFlowPath(source, sink) and
p = source.getNode().(PortalExitSource).getPortal() and
// avoid constructing infeasible paths
sink.getPathSummary().hasReturn() = false
select p.toString(), source.getPathSummary().getStartLabel().toString(), cfg.toString()

View File

@@ -0,0 +1,19 @@
/**
* @name Extract source summaries
* @description Extracts source summaries, that is, tuples `(p, lbl, cfg)` representing the fact
* that data may flow from a known source for configuration `cfg` to an escaping entry
* node of portal `p`, and have flow label `lbl` at that point.
* @kind source-summary
* @id js/source-summary-extraction
*/
import AllConfigurations
import PortalEntrySink
from TaintTracking::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink,
Portal p
where cfg.hasFlowPath(source, sink) and
p = sink.getNode().(PortalEntrySink).getPortal() and
// avoid constructing infeasible paths
sink.getPathSummary().hasCall() = false
select p.toString(), sink.getPathSummary().getEndLabel().toString(), cfg.toString()

View File

@@ -0,0 +1,24 @@
import javascript
import semmle.javascript.dataflow.Portals
/**
* An escaping entry node of a portal, viewed as an additional sink node for any flow
* configuration currently in scope.
*/
class PortalEntrySink extends DataFlow::AdditionalSink {
Portal p;
PortalEntrySink() {
this = p.getAnEntryNode(true)
}
override predicate isSinkFor(DataFlow::Configuration cfg, DataFlow::FlowLabel lbl) {
cfg instanceof TaintTracking::Configuration and
lbl = any(DataFlow::FlowLabel l)
}
/** Gets the portal of which this is an entry node. */
Portal getPortal() {
result = p
}
}

View File

@@ -0,0 +1,24 @@
import javascript
import semmle.javascript.dataflow.Portals
/**
* A remote exit node of a portal, viewed as an additional source node for any flow
* configuration currently in scope.
*/
class PortalExitSource extends DataFlow::AdditionalSource {
Portal p;
PortalExitSource() {
this = p.getAnExitNode(true)
}
override predicate isSourceFor(DataFlow::Configuration cfg, DataFlow::FlowLabel lbl) {
cfg instanceof TaintTracking::Configuration and
lbl = any(DataFlow::FlowLabel l)
}
/** Gets the portal of which this is an exit node. */
Portal getPortal() {
result = p
}
}