mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
JS: Add SharedTaintStep
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
|
||||
import javascript
|
||||
private import semmle.javascript.dataflow.internal.FlowSteps as FlowSteps
|
||||
private import semmle.javascript.dataflow.internal.Unit
|
||||
private import semmle.javascript.dataflow.InferredTypes
|
||||
private import semmle.javascript.internal.CachedStages
|
||||
|
||||
@@ -139,7 +140,7 @@ module TaintTracking {
|
||||
|
||||
final override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
isAdditionalTaintStep(pred, succ) or
|
||||
any(AdditionalTaintStep dts).step(pred, succ)
|
||||
sharedTaintStep(pred, succ)
|
||||
}
|
||||
|
||||
final override predicate isAdditionalFlowStep(
|
||||
@@ -207,6 +208,33 @@ module TaintTracking {
|
||||
override predicate sanitizes(boolean outcome, Expr e) { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint-propagating data flow edge that should be added to all taint tracking
|
||||
* configurations in addition to standard data flow edges.
|
||||
*
|
||||
* This class is a singleton, and thus subclasses do not need to specify a characteristic predicate.
|
||||
*
|
||||
* Note: For performance reasons, all subclasses of this class should be part
|
||||
* of the standard library. Override `Configuration::isAdditionalTaintStep`
|
||||
* for analysis-specific taint steps.
|
||||
*/
|
||||
class SharedTaintStep extends Unit {
|
||||
/**
|
||||
* Holds if `pred` → `succ` should be considered a taint-propagating
|
||||
* data flow edge.
|
||||
*/
|
||||
abstract predicate step(DataFlow::Node pred, DataFlow::Node succ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `pred -> succ` is an edge used by all taint-tracking configurations.
|
||||
*/
|
||||
cached predicate sharedTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
any(SharedTaintStep step).step(pred, succ)
|
||||
or
|
||||
any(AdditionalTaintStep step).step(pred, succ)
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint-propagating data flow edge that should be added to all taint tracking
|
||||
* configurations in addition to standard data flow edges.
|
||||
@@ -215,13 +243,11 @@ module TaintTracking {
|
||||
* of the standard library. Override `Configuration::isAdditionalTaintStep`
|
||||
* for analysis-specific taint steps.
|
||||
*/
|
||||
cached
|
||||
abstract class AdditionalTaintStep extends DataFlow::Node {
|
||||
/**
|
||||
* Holds if `pred` → `succ` should be considered a taint-propagating
|
||||
* data flow edge.
|
||||
*/
|
||||
cached
|
||||
abstract predicate step(DataFlow::Node pred, DataFlow::Node succ);
|
||||
}
|
||||
|
||||
@@ -312,14 +338,12 @@ module TaintTracking {
|
||||
/**
|
||||
* A taint propagating data flow edge through persistent storage.
|
||||
*/
|
||||
class PersistentStorageTaintStep extends AdditionalTaintStep {
|
||||
PersistentReadAccess read;
|
||||
|
||||
PersistentStorageTaintStep() { this = read }
|
||||
|
||||
class PersistentStorageTaintStep extends SharedTaintStep {
|
||||
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
pred = read.getAWrite().getValue() and
|
||||
succ = read
|
||||
exists(PersistentReadAccess read |
|
||||
pred = read.getAWrite().getValue() and
|
||||
succ = read
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,10 +384,8 @@ module TaintTracking {
|
||||
* taint to flow from `v` to any read of `c2.state.p`, where `c2`
|
||||
* also is an instance of `C`.
|
||||
*/
|
||||
private class ReactComponentStateTaintStep extends AdditionalTaintStep {
|
||||
DataFlow::Node source;
|
||||
|
||||
ReactComponentStateTaintStep() {
|
||||
private class ReactComponentStateTaintStep extends SharedTaintStep {
|
||||
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(ReactComponent c, DataFlow::PropRead prn, DataFlow::PropWrite pwn |
|
||||
(
|
||||
c.getACandidateStateSource().flowsTo(pwn.getBase()) or
|
||||
@@ -375,14 +397,10 @@ module TaintTracking {
|
||||
)
|
||||
|
|
||||
prn.getPropertyName() = pwn.getPropertyName() and
|
||||
this = prn and
|
||||
source = pwn.getRhs()
|
||||
succ = prn and
|
||||
pred = pwn.getRhs()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
pred = source and succ = this
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
private newtype TUnit = MkUnit()
|
||||
|
||||
/**
|
||||
* A class with only one instance.
|
||||
*/
|
||||
class Unit extends TUnit {
|
||||
final string toString() { result = "Unit" }
|
||||
}
|
||||
Reference in New Issue
Block a user