mirror of
https://github.com/github/codeql.git
synced 2026-01-29 22:32:58 +01:00
Merge pull request #201 from max/update-data-flow
Update data flow and taint-tracking libraries
This commit is contained in:
@@ -3,152 +3,8 @@
|
||||
* global (inter-procedural) taint-tracking analyses.
|
||||
*/
|
||||
|
||||
import go
|
||||
import semmle.go.dataflow.DataFlow
|
||||
|
||||
module TaintTracking {
|
||||
private import semmle.go.dataflow.internal.DataFlowPrivate
|
||||
private import semmle.go.dataflow.FunctionInputsAndOutputs
|
||||
|
||||
/**
|
||||
* Holds if taint propagates from `source` to `sink` in zero or more local
|
||||
* (intra-procedural) steps.
|
||||
*/
|
||||
predicate localTaint(DataFlow::Node source, DataFlow::Node sink) { localTaintStep*(source, sink) }
|
||||
|
||||
/**
|
||||
* Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local
|
||||
* (intra-procedural) step.
|
||||
*/
|
||||
predicate localTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||
// Ordinary data flow
|
||||
DataFlow::localFlowStep(nodeFrom, nodeTo)
|
||||
or
|
||||
taintStep(nodeFrom, nodeTo)
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint tracking configuration.
|
||||
*
|
||||
* A taint tracking configuration is a special data flow configuration
|
||||
* (`DataFlow::Configuration`) that allows for flow through nodes that do not
|
||||
* necessarily preserve values, but are still relevant from a taint tracking
|
||||
* perspective. (For example, string concatenation, where one of the operands
|
||||
* is tainted.)
|
||||
*
|
||||
* Each use of the taint tracking library must define its own unique extension
|
||||
* of this abstract class. A configuration defines a set of relevant sources
|
||||
* (`isSource`) and sinks (`isSink`), and may additionally treat intermediate
|
||||
* nodes as "sanitizers" (`isSanitizer`) as well as add custom taint flow steps
|
||||
* (`isAdditionalTaintStep()`).
|
||||
*/
|
||||
abstract class Configuration extends DataFlow::Configuration {
|
||||
bindingset[this]
|
||||
Configuration() { any() }
|
||||
|
||||
/**
|
||||
* Holds if `source` is a relevant taint source.
|
||||
*
|
||||
* The smaller this predicate is, the faster `hasFlow()` will converge.
|
||||
*/
|
||||
// overridden to provide taint-tracking specific qldoc
|
||||
abstract override predicate isSource(DataFlow::Node source);
|
||||
|
||||
/**
|
||||
* Holds if `sink` is a relevant taint sink.
|
||||
*
|
||||
* The smaller this predicate is, the faster `hasFlow()` will converge.
|
||||
*/
|
||||
// overridden to provide taint-tracking specific qldoc
|
||||
abstract override predicate isSink(DataFlow::Node sink);
|
||||
|
||||
/** Holds if the intermediate node `node` is a taint sanitizer. */
|
||||
predicate isSanitizer(DataFlow::Node node) { none() }
|
||||
|
||||
final override predicate isBarrier(DataFlow::Node node) { isSanitizer(node) }
|
||||
|
||||
/**
|
||||
* Holds if the additional taint propagation step from `pred` to `succ`
|
||||
* must be taken into account in the analysis.
|
||||
*/
|
||||
predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { none() }
|
||||
|
||||
final override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
isAdditionalTaintStep(pred, succ)
|
||||
or
|
||||
taintStep(pred, succ)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if taint may flow from `source` to `sink` for this configuration.
|
||||
*/
|
||||
// overridden to provide taint-tracking specific qldoc
|
||||
override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) {
|
||||
super.hasFlow(source, sink)
|
||||
}
|
||||
}
|
||||
|
||||
/** Holds if taint flows from `pred` to `succ` via a reference or dereference. */
|
||||
predicate referenceStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
succ.asExpr().(AddressExpr).getOperand() = pred.asExpr()
|
||||
or
|
||||
succ.asExpr().(StarExpr).getBase() = pred.asExpr()
|
||||
}
|
||||
|
||||
/** Holds if taint flows from `pred` to `succ` via a field read. */
|
||||
predicate fieldReadStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
succ.(DataFlow::FieldReadNode).getBase() = pred
|
||||
}
|
||||
|
||||
/** Holds if taint flows from `pred` to `succ` via an array index operation. */
|
||||
predicate arrayStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
succ.asExpr().(IndexExpr).getBase() = pred.asExpr()
|
||||
}
|
||||
|
||||
/** Holds if taint flows from `pred` to `succ` via an extract tuple operation. */
|
||||
predicate tupleStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
succ = DataFlow::extractTupleElement(pred, _)
|
||||
}
|
||||
|
||||
/** Holds if taint flows from `pred` to `succ` via string concatenation. */
|
||||
predicate stringConcatStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(DataFlow::BinaryOperationNode conc | conc.getOperator() = "+" |
|
||||
succ = conc and conc.getAnOperand() = pred
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if taint flows from `pred` to `succ` via a slice operation. */
|
||||
predicate sliceStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
succ.asExpr().(SliceExpr).getBase() = pred.asExpr()
|
||||
}
|
||||
|
||||
/** Holds if taint flows from `pred` to `succ` via a function model. */
|
||||
predicate functionModelStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(FunctionModel m, DataFlow::CallNode c, FunctionInput inp, FunctionOutput outp |
|
||||
c = m.getACall() and
|
||||
m.hasTaintFlow(inp, outp) and
|
||||
pred = inp.getNode(c) and
|
||||
succ = outp.getNode(c)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if taint flows from `pred` to `succ` in one step.
|
||||
*/
|
||||
predicate taintStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
referenceStep(pred, succ) or
|
||||
fieldReadStep(pred, succ) or
|
||||
arrayStep(pred, succ) or
|
||||
tupleStep(pred, succ) or
|
||||
stringConcatStep(pred, succ) or
|
||||
sliceStep(pred, succ) or
|
||||
functionModelStep(pred, succ)
|
||||
}
|
||||
|
||||
/**
|
||||
* A model of a function specifying that the function propagates taint from
|
||||
* a parameter or qualifier to a result.
|
||||
*/
|
||||
abstract class FunctionModel extends Function {
|
||||
abstract predicate hasTaintFlow(FunctionInput input, FunctionOutput output);
|
||||
}
|
||||
import semmle.go.dataflow.internal.tainttracking1.TaintTrackingImpl
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,9 @@
|
||||
private import go
|
||||
private import DataFlowUtil
|
||||
private import DataFlowImplCommon::Public
|
||||
|
||||
private newtype TReturnKind =
|
||||
TSingleReturn()
|
||||
or
|
||||
TSingleReturn() or
|
||||
TMultiReturn(int i) { exists(SignatureType st | exists(st.getResultType(i))) }
|
||||
|
||||
/**
|
||||
@@ -17,9 +17,7 @@ class ReturnKind extends TReturnKind {
|
||||
this = TSingleReturn() and
|
||||
result = "return"
|
||||
or
|
||||
exists(int i | this = TMultiReturn(i) |
|
||||
result = "return[" + i + "]"
|
||||
)
|
||||
exists(int i | this = TMultiReturn(i) | result = "return[" + i + "]")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,10 +27,7 @@ class ReturnNode extends ResultNode {
|
||||
|
||||
ReturnNode() {
|
||||
exists(int nr | nr = fd.getType().getNumResult() |
|
||||
if nr = 1 then
|
||||
kind = TSingleReturn()
|
||||
else
|
||||
kind = TMultiReturn(i)
|
||||
if nr = 1 then kind = TSingleReturn() else kind = TMultiReturn(i)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -43,7 +38,6 @@ class ReturnNode extends ResultNode {
|
||||
/** A data flow node that represents the output of a call. */
|
||||
class OutNode extends DataFlow::Node {
|
||||
DataFlow::CallNode call;
|
||||
|
||||
int i;
|
||||
|
||||
OutNode() {
|
||||
@@ -66,9 +60,7 @@ OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) {
|
||||
kind = TSingleReturn() and
|
||||
result = c.getResult()
|
||||
or
|
||||
exists(int i | kind = TMultiReturn(i) |
|
||||
result = c.getResult(i)
|
||||
)
|
||||
exists(int i | kind = TMultiReturn(i) | result = c.getResult(i))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -241,3 +233,38 @@ class DataFlowCall extends Expr {
|
||||
/** Gets the enclosing callable of this call. */
|
||||
DataFlowCallable getEnclosingCallable() { result = this.getEnclosingFunction() }
|
||||
}
|
||||
|
||||
/** Holds if `e` is an expression that always has the same Boolean value `val`. */
|
||||
private predicate constantBooleanExpr(Expr e, boolean val) {
|
||||
e.getBoolValue() = val
|
||||
or
|
||||
exists(SsaExplicitDefinition v, Expr src |
|
||||
IR::evalExprInstruction(e) = v.getVariable().getAUse() and
|
||||
IR::evalExprInstruction(src) = v.getRhs() and
|
||||
constantBooleanExpr(src, val)
|
||||
)
|
||||
}
|
||||
|
||||
/** An argument that always has the same Boolean value. */
|
||||
private class ConstantBooleanArgumentNode extends ArgumentNode, ExprNode {
|
||||
ConstantBooleanArgumentNode() { constantBooleanExpr(this.getExpr(), _) }
|
||||
|
||||
/** Gets the Boolean value of this expression. */
|
||||
boolean getBooleanValue() { constantBooleanExpr(this.getExpr(), result) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the node `n` is unreachable when the call context is `call`.
|
||||
*/
|
||||
cached
|
||||
predicate isUnreachableInCall(Node n, DataFlowCall call) {
|
||||
exists(
|
||||
ParameterNode param, ConstantBooleanArgumentNode arg, ControlFlow::ConditionGuardNode guard
|
||||
|
|
||||
// get constant bool argument and parameter for this call
|
||||
viableParamArg(call, param, arg) and
|
||||
// which is used in a guard controlling `n` with the opposite value of `arg`
|
||||
guard.ensures(param.getAUse(), arg.getBooleanValue().booleanNot()) and
|
||||
guard.dominates(n.getBasicBlock())
|
||||
)
|
||||
}
|
||||
|
||||
@@ -683,8 +683,18 @@ Node extractTupleElement(Node t, int i) {
|
||||
* Holds if data flows from `nodeFrom` to `nodeTo` in exactly one local
|
||||
* (intra-procedural) step.
|
||||
*/
|
||||
cached
|
||||
predicate localFlowStep(Node nodeFrom, Node nodeTo) {
|
||||
simpleLocalFlowStep(nodeFrom, nodeTo)
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: do not use.
|
||||
*
|
||||
* This is the local flow predicate that's used as a building block in global
|
||||
* data flow. It may have less flow than the `localFlowStep` predicate.
|
||||
*/
|
||||
cached
|
||||
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
|
||||
// Instruction -> Instruction
|
||||
exists(Expr pred, Expr succ |
|
||||
succ.(LogicalBinaryExpr).getAnOperand() = pred or
|
||||
|
||||
124
ql/src/semmle/go/dataflow/internal/TaintTrackingUtil.qll
Normal file
124
ql/src/semmle/go/dataflow/internal/TaintTrackingUtil.qll
Normal file
@@ -0,0 +1,124 @@
|
||||
private import go
|
||||
|
||||
/**
|
||||
* Holds if taint can flow from `src` to `sink` in zero or more
|
||||
* local (intra-procedural) steps.
|
||||
*/
|
||||
predicate localTaint(DataFlow::Node src, DataFlow::Node sink) { localTaintStep*(src, sink) }
|
||||
|
||||
/**
|
||||
* Holds if taint can flow from `src` to `sink` in zero or more
|
||||
* local (intra-procedural) steps.
|
||||
*/
|
||||
predicate localExprTaint(Expr src, Expr sink) {
|
||||
localTaint(DataFlow::exprNode(src), DataFlow::exprNode(sink))
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if taint can flow in one local step from `src` to `sink`.
|
||||
*/
|
||||
predicate localTaintStep(DataFlow::Node src, DataFlow::Node sink) {
|
||||
DataFlow::localFlowStep(src, sink) or
|
||||
localAdditionalTaintStep(src, sink)
|
||||
}
|
||||
|
||||
private newtype TUnit = TMkUnit()
|
||||
|
||||
class Unit extends TUnit {
|
||||
string toString() { result = "unit" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A unit class for adding additional taint steps.
|
||||
*
|
||||
* Extend this class to add additional taint steps that should apply to all
|
||||
* taint configurations.
|
||||
*/
|
||||
class AdditionalTaintStep extends Unit {
|
||||
/**
|
||||
* Holds if the step from `node1` to `node2` should be considered a taint
|
||||
* step for all configurations.
|
||||
*/
|
||||
abstract predicate step(DataFlow::Node node1, DataFlow::Node node2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the additional step from `pred` to `succ` should be included in all
|
||||
* global taint flow configurations.
|
||||
*/
|
||||
predicate localAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
referenceStep(pred, succ) or
|
||||
fieldReadStep(pred, succ) or
|
||||
arrayStep(pred, succ) or
|
||||
tupleStep(pred, succ) or
|
||||
stringConcatStep(pred, succ) or
|
||||
sliceStep(pred, succ) or
|
||||
functionModelStep(pred, succ) or
|
||||
any(AdditionalTaintStep a).step(pred, succ)
|
||||
}
|
||||
|
||||
/** Holds if taint flows from `pred` to `succ` via a reference or dereference. */
|
||||
predicate referenceStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
succ.asExpr().(AddressExpr).getOperand() = pred.asExpr()
|
||||
or
|
||||
succ.asExpr().(StarExpr).getBase() = pred.asExpr()
|
||||
}
|
||||
|
||||
/** Holds if taint flows from `pred` to `succ` via a field read. */
|
||||
predicate fieldReadStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
succ.(DataFlow::FieldReadNode).getBase() = pred
|
||||
}
|
||||
|
||||
/** Holds if taint flows from `pred` to `succ` via an array index operation. */
|
||||
predicate arrayStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
succ.asExpr().(IndexExpr).getBase() = pred.asExpr()
|
||||
}
|
||||
|
||||
/** Holds if taint flows from `pred` to `succ` via an extract tuple operation. */
|
||||
predicate tupleStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
succ = DataFlow::extractTupleElement(pred, _)
|
||||
}
|
||||
|
||||
/** Holds if taint flows from `pred` to `succ` via string concatenation. */
|
||||
predicate stringConcatStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(DataFlow::BinaryOperationNode conc | conc.getOperator() = "+" |
|
||||
succ = conc and conc.getAnOperand() = pred
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if taint flows from `pred` to `succ` via a slice operation. */
|
||||
predicate sliceStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
succ.asExpr().(SliceExpr).getBase() = pred.asExpr()
|
||||
}
|
||||
|
||||
/** Holds if taint flows from `pred` to `succ` via a function model. */
|
||||
predicate functionModelStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(FunctionModel m, DataFlow::CallNode c, FunctionInput inp, FunctionOutput outp |
|
||||
c = m.getACall() and
|
||||
m.hasTaintFlow(inp, outp) and
|
||||
pred = inp.getNode(c) and
|
||||
succ = outp.getNode(c)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A model of a function specifying that the function propagates taint from
|
||||
* a parameter or qualifier to a result.
|
||||
*/
|
||||
abstract class FunctionModel extends Function {
|
||||
abstract predicate hasTaintFlow(FunctionInput input, FunctionOutput output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the additional step from `src` to `sink` should be included in all
|
||||
* global taint flow configurations.
|
||||
*/
|
||||
predicate defaultAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) {
|
||||
localAdditionalTaintStep(src, sink)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` should be a barrier in all global taint flow configurations
|
||||
* but not in local taint.
|
||||
*/
|
||||
predicate defaultTaintBarrier(DataFlow::Node node) { none() }
|
||||
@@ -0,0 +1,112 @@
|
||||
import TaintTrackingParameter::Public
|
||||
private import TaintTrackingParameter::Private
|
||||
|
||||
/**
|
||||
* A configuration of interprocedural taint tracking analysis. This defines
|
||||
* sources, sinks, and any other configurable aspect of the analysis. Each
|
||||
* use of the taint tracking library must define its own unique extension of
|
||||
* this abstract class.
|
||||
*
|
||||
* A taint-tracking configuration is a special data flow configuration
|
||||
* (`DataFlow::Configuration`) that allows for flow through nodes that do not
|
||||
* necessarily preserve values but are still relevant from a taint tracking
|
||||
* perspective. (For example, string concatenation, where one of the operands
|
||||
* is tainted.)
|
||||
*
|
||||
* To create a configuration, extend this class with a subclass whose
|
||||
* characteristic predicate is a unique singleton string. For example, write
|
||||
*
|
||||
* ```
|
||||
* class MyAnalysisConfiguration extends TaintTracking::Configuration {
|
||||
* MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" }
|
||||
* // Override `isSource` and `isSink`.
|
||||
* // Optionally override `isSanitizer`.
|
||||
* // Optionally override `isSanitizerIn`.
|
||||
* // Optionally override `isSanitizerOut`.
|
||||
* // Optionally override `isSanitizerGuard`.
|
||||
* // Optionally override `isAdditionalTaintStep`.
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* Then, to query whether there is flow between some `source` and `sink`,
|
||||
* write
|
||||
*
|
||||
* ```
|
||||
* exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink))
|
||||
* ```
|
||||
*
|
||||
* Multiple configurations can coexist, but it is unsupported to depend on
|
||||
* another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the
|
||||
* overridden predicates that define sources, sinks, or additional steps.
|
||||
* Instead, the dependency should go to a `TaintTracking2::Configuration` or a
|
||||
* `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc.
|
||||
*/
|
||||
abstract class Configuration extends DataFlow::Configuration {
|
||||
bindingset[this]
|
||||
Configuration() { any() }
|
||||
|
||||
/**
|
||||
* Holds if `source` is a relevant taint source.
|
||||
*
|
||||
* The smaller this predicate is, the faster `hasFlow()` will converge.
|
||||
*/
|
||||
// overridden to provide taint-tracking specific qldoc
|
||||
abstract override predicate isSource(DataFlow::Node source);
|
||||
|
||||
/**
|
||||
* Holds if `sink` is a relevant taint sink.
|
||||
*
|
||||
* The smaller this predicate is, the faster `hasFlow()` will converge.
|
||||
*/
|
||||
// overridden to provide taint-tracking specific qldoc
|
||||
abstract override predicate isSink(DataFlow::Node sink);
|
||||
|
||||
/** Holds if the node `node` is a taint sanitizer. */
|
||||
predicate isSanitizer(DataFlow::Node node) { none() }
|
||||
|
||||
final override predicate isBarrier(DataFlow::Node node) {
|
||||
isSanitizer(node) or
|
||||
defaultTaintBarrier(node)
|
||||
}
|
||||
|
||||
/** DEPRECATED: override `isSanitizerIn` and `isSanitizerOut` instead. */
|
||||
deprecated predicate isSanitizerEdge(DataFlow::Node node1, DataFlow::Node node2) { none() }
|
||||
|
||||
deprecated final override predicate isBarrierEdge(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
isSanitizerEdge(node1, node2)
|
||||
}
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isSanitizerIn(DataFlow::Node node) { none() }
|
||||
|
||||
final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
|
||||
|
||||
/** Holds if data flow out of `node` is prohibited. */
|
||||
predicate isSanitizerOut(DataFlow::Node node) { none() }
|
||||
|
||||
final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
|
||||
|
||||
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
|
||||
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
||||
|
||||
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }
|
||||
|
||||
/**
|
||||
* Holds if the additional taint propagation step from `node1` to `node2`
|
||||
* must be taken into account in the analysis.
|
||||
*/
|
||||
predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() }
|
||||
|
||||
final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
isAdditionalTaintStep(node1, node2) or
|
||||
defaultAdditionalTaintStep(node1, node2)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if taint may flow from `source` to `sink` for this configuration.
|
||||
*/
|
||||
// overridden to provide taint-tracking specific qldoc
|
||||
override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) {
|
||||
super.hasFlow(source, sink)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import semmle.go.dataflow.internal.TaintTrackingUtil as Public
|
||||
|
||||
module Private {
|
||||
import semmle.go.dataflow.DataFlow::DataFlow as DataFlow
|
||||
}
|
||||
@@ -35,7 +35,7 @@ module CleartextLogging {
|
||||
exists(Write write | write.writesField(trg.getASuccessor*(), _, src))
|
||||
or
|
||||
// taint steps that do not include flow through fields
|
||||
TaintTracking::taintStep(src, trg) and not TaintTracking::fieldReadStep(src, trg)
|
||||
TaintTracking::localTaintStep(src, trg) and not TaintTracking::fieldReadStep(src, trg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,6 @@ module CommandInjection {
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { guard instanceof SanitizerGuard }
|
||||
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { guard instanceof SanitizerGuard }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ module OpenUrlRedirect {
|
||||
)
|
||||
or
|
||||
// taint steps that do not include flow through fields
|
||||
TaintTracking::taintStep(pred, succ) and not TaintTracking::fieldReadStep(pred, succ)
|
||||
TaintTracking::localTaintStep(pred, succ) and not TaintTracking::fieldReadStep(pred, succ)
|
||||
}
|
||||
|
||||
override predicate isBarrierOut(DataFlow::Node node) { hostnameSanitizingPrefixEdge(node, _) }
|
||||
|
||||
@@ -23,6 +23,6 @@ module ReflectedXss {
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { guard instanceof SanitizerGuard }
|
||||
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { guard instanceof SanitizerGuard }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,6 @@ module SqlInjection {
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { guard instanceof SanitizerGuard }
|
||||
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { guard instanceof SanitizerGuard }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,6 @@ module TaintedPath {
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { guard instanceof SanitizerGuard }
|
||||
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { guard instanceof SanitizerGuard }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,6 @@ module ZipSlip {
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { guard instanceof SanitizerGuard }
|
||||
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { guard instanceof SanitizerGuard }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
edges
|
||||
| IncompleteHostnameRegexp.go:11:11:11:39 | "^((www\|beta).)?example.com/" [string] | IncompleteHostnameRegexp.go:12:41:12:42 | re |
|
||||
| main.go:12:15:12:39 | `https://www.example.com` [string] | main.go:12:15:12:39 | `https://www.example.com` |
|
||||
| IncompleteHostnameRegexp.go:11:11:11:39 | "^((www\|beta).)?example.com/" : string | IncompleteHostnameRegexp.go:12:41:12:42 | re |
|
||||
nodes
|
||||
| IncompleteHostnameRegexp.go:11:11:11:39 | "^((www\|beta).)?example.com/" : string | semmle.label | "^((www\|beta).)?example.com/" : string |
|
||||
| IncompleteHostnameRegexp.go:12:41:12:42 | re | semmle.label | re |
|
||||
| main.go:12:15:12:39 | `https://www.example.com` | semmle.label | `https://www.example.com` |
|
||||
#select
|
||||
| IncompleteHostnameRegexp.go:11:11:11:39 | "^((www\|beta).)?example.com/" [string] | IncompleteHostnameRegexp.go:11:11:11:39 | "^((www\|beta).)?example.com/" [string] | IncompleteHostnameRegexp.go:12:41:12:42 | re | This regular expression has an unescaped dot before ')?example.com', so it might match more hosts than expected when used $@. | IncompleteHostnameRegexp.go:12:41:12:42 | re | here |
|
||||
| main.go:12:15:12:39 | `https://www.example.com` [string] | main.go:12:15:12:39 | `https://www.example.com` [string] | main.go:12:15:12:39 | `https://www.example.com` | This regular expression has an unescaped dot before 'example.com', so it might match more hosts than expected when used $@. | main.go:12:15:12:39 | `https://www.example.com` | here |
|
||||
| IncompleteHostnameRegexp.go:11:11:11:39 | "^((www\|beta).)?example.com/" : string | IncompleteHostnameRegexp.go:11:11:11:39 | "^((www\|beta).)?example.com/" : string | IncompleteHostnameRegexp.go:12:41:12:42 | re | This regular expression has an unescaped dot before ')?example.com', so it might match more hosts than expected when used $@. | IncompleteHostnameRegexp.go:12:41:12:42 | re | here |
|
||||
| main.go:12:15:12:39 | `https://www.example.com` | main.go:12:15:12:39 | `https://www.example.com` | main.go:12:15:12:39 | `https://www.example.com` | This regular expression has an unescaped dot before 'example.com', so it might match more hosts than expected when used $@. | main.go:12:15:12:39 | `https://www.example.com` | here |
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
edges
|
||||
| TaintedPath.go:10:10:10:14 | selection of URL [pointer type] | TaintedPath.go:13:29:13:32 | path |
|
||||
| TaintedPath.go:10:10:10:14 | selection of URL [pointer type] | TaintedPath.go:17:28:17:61 | call to Join |
|
||||
| TaintedPath.go:10:10:10:14 | selection of URL : pointer type | TaintedPath.go:13:29:13:32 | path |
|
||||
| TaintedPath.go:10:10:10:14 | selection of URL : pointer type | TaintedPath.go:17:28:17:61 | call to Join |
|
||||
nodes
|
||||
| TaintedPath.go:10:10:10:14 | selection of URL : pointer type | semmle.label | selection of URL : pointer type |
|
||||
| TaintedPath.go:13:29:13:32 | path | semmle.label | path |
|
||||
| TaintedPath.go:17:28:17:61 | call to Join | semmle.label | call to Join |
|
||||
#select
|
||||
| TaintedPath.go:13:29:13:32 | path | TaintedPath.go:10:10:10:14 | selection of URL [pointer type] | TaintedPath.go:13:29:13:32 | path | This path depends on $@. | TaintedPath.go:10:10:10:14 | selection of URL | a user-provided value |
|
||||
| TaintedPath.go:17:28:17:61 | call to Join | TaintedPath.go:10:10:10:14 | selection of URL [pointer type] | TaintedPath.go:17:28:17:61 | call to Join | This path depends on $@. | TaintedPath.go:10:10:10:14 | selection of URL | a user-provided value |
|
||||
| TaintedPath.go:13:29:13:32 | path | TaintedPath.go:10:10:10:14 | selection of URL : pointer type | TaintedPath.go:13:29:13:32 | path | This path depends on $@. | TaintedPath.go:10:10:10:14 | selection of URL | a user-provided value |
|
||||
| TaintedPath.go:17:28:17:61 | call to Join | TaintedPath.go:10:10:10:14 | selection of URL : pointer type | TaintedPath.go:17:28:17:61 | call to Join | This path depends on $@. | TaintedPath.go:10:10:10:14 | selection of URL | a user-provided value |
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
edges
|
||||
| ZipSlip.go:12:24:12:29 | selection of Name [string] | ZipSlip.go:14:20:14:20 | p |
|
||||
| tst.go:15:11:15:16 | selection of Name [string] | tst.go:20:20:20:23 | path |
|
||||
| ZipSlip.go:12:24:12:29 | selection of Name : string | ZipSlip.go:14:20:14:20 | p |
|
||||
| tst.go:15:11:15:16 | selection of Name : string | tst.go:20:20:20:23 | path |
|
||||
nodes
|
||||
| ZipSlip.go:12:24:12:29 | selection of Name : string | semmle.label | selection of Name : string |
|
||||
| ZipSlip.go:14:20:14:20 | p | semmle.label | p |
|
||||
| tst.go:15:11:15:16 | selection of Name : string | semmle.label | selection of Name : string |
|
||||
| tst.go:20:20:20:23 | path | semmle.label | path |
|
||||
#select
|
||||
| ZipSlip.go:12:24:12:29 | selection of Name | ZipSlip.go:12:24:12:29 | selection of Name [string] | ZipSlip.go:14:20:14:20 | p | Unsanitized archive entry, which may contain '..', is used in a $@. | ZipSlip.go:14:20:14:20 | p | file system operation |
|
||||
| tst.go:15:11:15:16 | selection of Name | tst.go:15:11:15:16 | selection of Name [string] | tst.go:20:20:20:23 | path | Unsanitized archive entry, which may contain '..', is used in a $@. | tst.go:20:20:20:23 | path | file system operation |
|
||||
| ZipSlip.go:12:24:12:29 | selection of Name | ZipSlip.go:12:24:12:29 | selection of Name : string | ZipSlip.go:14:20:14:20 | p | Unsanitized archive entry, which may contain '..', is used in a $@. | ZipSlip.go:14:20:14:20 | p | file system operation |
|
||||
| tst.go:15:11:15:16 | selection of Name | tst.go:15:11:15:16 | selection of Name : string | tst.go:20:20:20:23 | path | Unsanitized archive entry, which may contain '..', is used in a $@. | tst.go:20:20:20:23 | path | file system operation |
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
edges
|
||||
| CommandInjection.go:9:13:9:19 | selection of URL [pointer type] | CommandInjection.go:10:22:10:28 | cmdName |
|
||||
| CommandInjection.go:9:13:9:19 | selection of URL : pointer type | CommandInjection.go:10:22:10:28 | cmdName |
|
||||
nodes
|
||||
| CommandInjection.go:9:13:9:19 | selection of URL : pointer type | semmle.label | selection of URL : pointer type |
|
||||
| CommandInjection.go:10:22:10:28 | cmdName | semmle.label | cmdName |
|
||||
#select
|
||||
| CommandInjection.go:10:22:10:28 | cmdName | CommandInjection.go:9:13:9:19 | selection of URL [pointer type] | CommandInjection.go:10:22:10:28 | cmdName | This command depends on $@. | CommandInjection.go:9:13:9:19 | selection of URL | a user-provided value |
|
||||
| CommandInjection.go:10:22:10:28 | cmdName | CommandInjection.go:9:13:9:19 | selection of URL : pointer type | CommandInjection.go:10:22:10:28 | cmdName | This command depends on $@. | CommandInjection.go:9:13:9:19 | selection of URL | a user-provided value |
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
edges
|
||||
| ReflectedXss.go:11:15:11:20 | selection of Form [Values] | ReflectedXss.go:14:39:14:46 | username |
|
||||
| contenttype.go:10:11:10:16 | selection of Form [Values] | contenttype.go:16:11:16:22 | type conversion |
|
||||
| ReflectedXss.go:11:15:11:20 | selection of Form : Values | ReflectedXss.go:14:39:14:46 | username |
|
||||
| contenttype.go:10:11:10:16 | selection of Form : Values | contenttype.go:16:11:16:22 | type conversion |
|
||||
nodes
|
||||
| ReflectedXss.go:11:15:11:20 | selection of Form : Values | semmle.label | selection of Form : Values |
|
||||
| ReflectedXss.go:14:39:14:46 | username | semmle.label | username |
|
||||
| contenttype.go:10:11:10:16 | selection of Form : Values | semmle.label | selection of Form : Values |
|
||||
| contenttype.go:16:11:16:22 | type conversion | semmle.label | type conversion |
|
||||
#select
|
||||
| ReflectedXss.go:14:39:14:46 | username | ReflectedXss.go:11:15:11:20 | selection of Form [Values] | ReflectedXss.go:14:39:14:46 | username | Cross-site scripting vulnerability due to $@. | ReflectedXss.go:11:15:11:20 | selection of Form | user-provided value |
|
||||
| contenttype.go:16:11:16:22 | type conversion | contenttype.go:10:11:10:16 | selection of Form [Values] | contenttype.go:16:11:16:22 | type conversion | Cross-site scripting vulnerability due to $@. | contenttype.go:10:11:10:16 | selection of Form | user-provided value |
|
||||
| ReflectedXss.go:14:39:14:46 | username | ReflectedXss.go:11:15:11:20 | selection of Form : Values | ReflectedXss.go:14:39:14:46 | username | Cross-site scripting vulnerability due to $@. | ReflectedXss.go:11:15:11:20 | selection of Form | user-provided value |
|
||||
| contenttype.go:16:11:16:22 | type conversion | contenttype.go:10:11:10:16 | selection of Form : Values | contenttype.go:16:11:16:22 | type conversion | Cross-site scripting vulnerability due to $@. | contenttype.go:10:11:10:16 | selection of Form | user-provided value |
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
edges
|
||||
| SqlInjection.go:11:3:11:9 | selection of URL [pointer type] | SqlInjection.go:12:11:12:11 | q |
|
||||
| main.go:9:11:9:16 | selection of Form [Values] | main.go:9:11:9:28 | index expression |
|
||||
| SqlInjection.go:11:3:11:9 | selection of URL : pointer type | SqlInjection.go:12:11:12:11 | q |
|
||||
| main.go:9:11:9:16 | selection of Form : Values | main.go:9:11:9:28 | index expression |
|
||||
nodes
|
||||
| SqlInjection.go:11:3:11:9 | selection of URL : pointer type | semmle.label | selection of URL : pointer type |
|
||||
| SqlInjection.go:12:11:12:11 | q | semmle.label | q |
|
||||
| main.go:9:11:9:16 | selection of Form : Values | semmle.label | selection of Form : Values |
|
||||
| main.go:9:11:9:28 | index expression | semmle.label | index expression |
|
||||
#select
|
||||
| SqlInjection.go:12:11:12:11 | q | SqlInjection.go:11:3:11:9 | selection of URL [pointer type] | SqlInjection.go:12:11:12:11 | q | This query depends on $@. | SqlInjection.go:11:3:11:9 | selection of URL | a user-provided value |
|
||||
| main.go:9:11:9:28 | index expression | main.go:9:11:9:16 | selection of Form [Values] | main.go:9:11:9:28 | index expression | This query depends on $@. | main.go:9:11:9:16 | selection of Form | a user-provided value |
|
||||
| SqlInjection.go:12:11:12:11 | q | SqlInjection.go:11:3:11:9 | selection of URL : pointer type | SqlInjection.go:12:11:12:11 | q | This query depends on $@. | SqlInjection.go:11:3:11:9 | selection of URL | a user-provided value |
|
||||
| main.go:9:11:9:28 | index expression | main.go:9:11:9:16 | selection of Form : Values | main.go:9:11:9:28 | index expression | This query depends on $@. | main.go:9:11:9:16 | selection of Form | a user-provided value |
|
||||
|
||||
@@ -1,54 +1,88 @@
|
||||
edges
|
||||
| passwords.go:8:12:8:12 | definition of x [string] | passwords.go:9:14:9:14 | x |
|
||||
| passwords.go:25:14:25:21 | password [string] | passwords.go:25:14:25:21 | password |
|
||||
| passwords.go:26:14:26:23 | selection of password [string] | passwords.go:26:14:26:23 | selection of password |
|
||||
| passwords.go:27:14:27:26 | call to getPassword [string] | passwords.go:27:14:27:26 | call to getPassword |
|
||||
| passwords.go:28:14:28:28 | call to getPassword [string] | passwords.go:28:14:28:28 | call to getPassword |
|
||||
| passwords.go:30:8:30:15 | password [string] | passwords.go:8:12:8:12 | definition of x [string] |
|
||||
| passwords.go:32:12:32:19 | password [string] | passwords.go:32:12:32:19 | password |
|
||||
| passwords.go:34:28:34:35 | password [string] | passwords.go:34:14:34:35 | ...+... |
|
||||
| passwords.go:36:10:38:2 | composite literal [passStruct] | passwords.go:39:14:39:17 | obj1 |
|
||||
| passwords.go:42:6:42:13 | password [string] | passwords.go:44:14:44:17 | obj2 |
|
||||
| passwords.go:48:11:48:18 | password [string] | passwords.go:47:14:47:17 | obj3 |
|
||||
| passwords.go:51:14:51:27 | fixed_password [string] | passwords.go:51:14:51:27 | fixed_password |
|
||||
| passwords.go:85:19:87:2 | composite literal [passSetStruct] | passwords.go:88:14:88:26 | utilityObject |
|
||||
| passwords.go:90:12:90:19 | password [string] | passwords.go:91:23:91:28 | secret |
|
||||
| passwords.go:101:33:101:40 | password [string] | passwords.go:101:15:101:40 | ...+... |
|
||||
| passwords.go:107:34:107:41 | password [string] | passwords.go:107:16:107:41 | ...+... |
|
||||
| passwords.go:112:33:112:40 | password [string] | passwords.go:112:15:112:40 | ...+... |
|
||||
| passwords.go:116:28:116:36 | password1 [stringable] | passwords.go:116:14:116:45 | ...+... |
|
||||
| passwords.go:118:12:123:2 | composite literal [Config] | passwords.go:125:14:125:19 | config |
|
||||
| passwords.go:118:12:123:2 | composite literal [x, ... (1)] | passwords.go:126:14:126:19 | config [x, ... (1)] |
|
||||
| passwords.go:118:12:123:2 | composite literal [y, ... (1)] | passwords.go:127:14:127:19 | config [y, ... (1)] |
|
||||
| passwords.go:121:13:121:20 | password [string] | passwords.go:118:12:123:2 | composite literal [x, ... (1)] |
|
||||
| passwords.go:121:13:121:20 | password [string] | passwords.go:125:14:125:19 | config |
|
||||
| passwords.go:122:13:122:25 | call to getPassword [string] | passwords.go:118:12:123:2 | composite literal [y, ... (1)] |
|
||||
| passwords.go:122:13:122:25 | call to getPassword [string] | passwords.go:125:14:125:19 | config |
|
||||
| passwords.go:126:14:126:19 | config [x, ... (1)] | passwords.go:126:14:126:21 | selection of x |
|
||||
| passwords.go:127:14:127:19 | config [y, ... (1)] | passwords.go:127:14:127:21 | selection of y |
|
||||
| util.go:14:9:14:18 | selection of password [string] | passwords.go:28:14:28:28 | call to getPassword |
|
||||
| util.go:14:9:14:18 | selection of password [string] | passwords.go:28:14:28:28 | call to getPassword [string] |
|
||||
| passwords.go:8:12:8:12 | definition of x : string | passwords.go:9:14:9:14 | x |
|
||||
| passwords.go:30:8:30:15 | password : string | passwords.go:8:12:8:12 | definition of x : string |
|
||||
| passwords.go:34:28:34:35 | password : string | passwords.go:34:14:34:35 | ...+... |
|
||||
| passwords.go:36:10:38:2 | composite literal : passStruct | passwords.go:39:14:39:17 | obj1 |
|
||||
| passwords.go:42:6:42:13 | password : string | passwords.go:44:14:44:17 | obj2 |
|
||||
| passwords.go:48:11:48:18 | password : string | passwords.go:47:14:47:17 | obj3 |
|
||||
| passwords.go:85:19:87:2 | composite literal : passSetStruct | passwords.go:88:14:88:26 | utilityObject |
|
||||
| passwords.go:90:12:90:19 | password : string | passwords.go:91:23:91:28 | secret |
|
||||
| passwords.go:101:33:101:40 | password : string | passwords.go:101:15:101:40 | ...+... |
|
||||
| passwords.go:107:34:107:41 | password : string | passwords.go:107:16:107:41 | ...+... |
|
||||
| passwords.go:112:33:112:40 | password : string | passwords.go:112:15:112:40 | ...+... |
|
||||
| passwords.go:116:28:116:36 | password1 : stringable | passwords.go:116:14:116:45 | ...+... |
|
||||
| passwords.go:118:12:123:2 | composite literal : Config | passwords.go:125:14:125:19 | config |
|
||||
| passwords.go:118:12:123:2 | composite literal [x] : string | passwords.go:126:14:126:19 | config [x] : string |
|
||||
| passwords.go:118:12:123:2 | composite literal [y] : string | passwords.go:127:14:127:19 | config [y] : string |
|
||||
| passwords.go:121:13:121:20 | password : string | passwords.go:118:12:123:2 | composite literal [x] : string |
|
||||
| passwords.go:121:13:121:20 | password : string | passwords.go:125:14:125:19 | config |
|
||||
| passwords.go:122:13:122:25 | call to getPassword : string | passwords.go:118:12:123:2 | composite literal [y] : string |
|
||||
| passwords.go:122:13:122:25 | call to getPassword : string | passwords.go:125:14:125:19 | config |
|
||||
| passwords.go:126:14:126:19 | config [x] : string | passwords.go:126:14:126:21 | selection of x |
|
||||
| passwords.go:127:14:127:19 | config [y] : string | passwords.go:127:14:127:21 | selection of y |
|
||||
| util.go:14:9:14:18 | selection of password : string | passwords.go:28:14:28:28 | call to getPassword |
|
||||
nodes
|
||||
| passwords.go:8:12:8:12 | definition of x : string | semmle.label | definition of x : string |
|
||||
| passwords.go:9:14:9:14 | x | semmle.label | x |
|
||||
| passwords.go:25:14:25:21 | password | semmle.label | password |
|
||||
| passwords.go:26:14:26:23 | selection of password | semmle.label | selection of password |
|
||||
| passwords.go:27:14:27:26 | call to getPassword | semmle.label | call to getPassword |
|
||||
| passwords.go:28:14:28:28 | call to getPassword | semmle.label | call to getPassword |
|
||||
| passwords.go:30:8:30:15 | password : string | semmle.label | password : string |
|
||||
| passwords.go:32:12:32:19 | password | semmle.label | password |
|
||||
| passwords.go:34:14:34:35 | ...+... | semmle.label | ...+... |
|
||||
| passwords.go:34:28:34:35 | password : string | semmle.label | password : string |
|
||||
| passwords.go:36:10:38:2 | composite literal : passStruct | semmle.label | composite literal : passStruct |
|
||||
| passwords.go:39:14:39:17 | obj1 | semmle.label | obj1 |
|
||||
| passwords.go:42:6:42:13 | password : string | semmle.label | password : string |
|
||||
| passwords.go:44:14:44:17 | obj2 | semmle.label | obj2 |
|
||||
| passwords.go:47:14:47:17 | obj3 | semmle.label | obj3 |
|
||||
| passwords.go:48:11:48:18 | password : string | semmle.label | password : string |
|
||||
| passwords.go:51:14:51:27 | fixed_password | semmle.label | fixed_password |
|
||||
| passwords.go:85:19:87:2 | composite literal : passSetStruct | semmle.label | composite literal : passSetStruct |
|
||||
| passwords.go:88:14:88:26 | utilityObject | semmle.label | utilityObject |
|
||||
| passwords.go:90:12:90:19 | password : string | semmle.label | password : string |
|
||||
| passwords.go:91:23:91:28 | secret | semmle.label | secret |
|
||||
| passwords.go:101:15:101:40 | ...+... | semmle.label | ...+... |
|
||||
| passwords.go:101:33:101:40 | password : string | semmle.label | password : string |
|
||||
| passwords.go:107:16:107:41 | ...+... | semmle.label | ...+... |
|
||||
| passwords.go:107:34:107:41 | password : string | semmle.label | password : string |
|
||||
| passwords.go:112:15:112:40 | ...+... | semmle.label | ...+... |
|
||||
| passwords.go:112:33:112:40 | password : string | semmle.label | password : string |
|
||||
| passwords.go:116:14:116:45 | ...+... | semmle.label | ...+... |
|
||||
| passwords.go:116:28:116:36 | password1 : stringable | semmle.label | password1 : stringable |
|
||||
| passwords.go:118:12:123:2 | composite literal : Config | semmle.label | composite literal : Config |
|
||||
| passwords.go:118:12:123:2 | composite literal [x] : string | semmle.label | composite literal [x] : string |
|
||||
| passwords.go:118:12:123:2 | composite literal [y] : string | semmle.label | composite literal [y] : string |
|
||||
| passwords.go:121:13:121:20 | password : string | semmle.label | password : string |
|
||||
| passwords.go:122:13:122:25 | call to getPassword : string | semmle.label | call to getPassword : string |
|
||||
| passwords.go:125:14:125:19 | config | semmle.label | config |
|
||||
| passwords.go:126:14:126:19 | config [x] : string | semmle.label | config [x] : string |
|
||||
| passwords.go:126:14:126:21 | selection of x | semmle.label | selection of x |
|
||||
| passwords.go:127:14:127:19 | config [y] : string | semmle.label | config [y] : string |
|
||||
| passwords.go:127:14:127:21 | selection of y | semmle.label | selection of y |
|
||||
| util.go:14:9:14:18 | selection of password : string | semmle.label | selection of password : string |
|
||||
#select
|
||||
| passwords.go:9:14:9:14 | x | passwords.go:30:8:30:15 | password [string] | passwords.go:9:14:9:14 | x | Sensitive data returned by $@ is logged here. | passwords.go:30:8:30:15 | password | an access to password |
|
||||
| passwords.go:25:14:25:21 | password | passwords.go:25:14:25:21 | password [string] | passwords.go:25:14:25:21 | password | Sensitive data returned by $@ is logged here. | passwords.go:25:14:25:21 | password | an access to password |
|
||||
| passwords.go:26:14:26:23 | selection of password | passwords.go:26:14:26:23 | selection of password [string] | passwords.go:26:14:26:23 | selection of password | Sensitive data returned by $@ is logged here. | passwords.go:26:14:26:23 | selection of password | an access to password |
|
||||
| passwords.go:27:14:27:26 | call to getPassword | passwords.go:27:14:27:26 | call to getPassword [string] | passwords.go:27:14:27:26 | call to getPassword | Sensitive data returned by $@ is logged here. | passwords.go:27:14:27:26 | call to getPassword | a call to getPassword |
|
||||
| passwords.go:28:14:28:28 | call to getPassword | passwords.go:28:14:28:28 | call to getPassword [string] | passwords.go:28:14:28:28 | call to getPassword | Sensitive data returned by $@ is logged here. | passwords.go:28:14:28:28 | call to getPassword | a call to getPassword |
|
||||
| passwords.go:28:14:28:28 | call to getPassword | util.go:14:9:14:18 | selection of password [string] | passwords.go:28:14:28:28 | call to getPassword | Sensitive data returned by $@ is logged here. | util.go:14:9:14:18 | selection of password | an access to password |
|
||||
| passwords.go:32:12:32:19 | password | passwords.go:32:12:32:19 | password [string] | passwords.go:32:12:32:19 | password | Sensitive data returned by $@ is logged here. | passwords.go:32:12:32:19 | password | an access to password |
|
||||
| passwords.go:34:14:34:35 | ...+... | passwords.go:34:28:34:35 | password [string] | passwords.go:34:14:34:35 | ...+... | Sensitive data returned by $@ is logged here. | passwords.go:34:28:34:35 | password | an access to password |
|
||||
| passwords.go:39:14:39:17 | obj1 | passwords.go:36:10:38:2 | composite literal [passStruct] | passwords.go:39:14:39:17 | obj1 | Sensitive data returned by $@ is logged here. | passwords.go:36:10:38:2 | composite literal | an access to password |
|
||||
| passwords.go:44:14:44:17 | obj2 | passwords.go:42:6:42:13 | password [string] | passwords.go:44:14:44:17 | obj2 | Sensitive data returned by $@ is logged here. | passwords.go:42:6:42:13 | password | an access to password |
|
||||
| passwords.go:47:14:47:17 | obj3 | passwords.go:48:11:48:18 | password [string] | passwords.go:47:14:47:17 | obj3 | Sensitive data returned by $@ is logged here. | passwords.go:48:11:48:18 | password | an access to password |
|
||||
| passwords.go:51:14:51:27 | fixed_password | passwords.go:51:14:51:27 | fixed_password [string] | passwords.go:51:14:51:27 | fixed_password | Sensitive data returned by $@ is logged here. | passwords.go:51:14:51:27 | fixed_password | an access to fixed_password |
|
||||
| passwords.go:88:14:88:26 | utilityObject | passwords.go:85:19:87:2 | composite literal [passSetStruct] | passwords.go:88:14:88:26 | utilityObject | Sensitive data returned by $@ is logged here. | passwords.go:85:19:87:2 | composite literal | an access to passwordSet |
|
||||
| passwords.go:91:23:91:28 | secret | passwords.go:90:12:90:19 | password [string] | passwords.go:91:23:91:28 | secret | Sensitive data returned by $@ is logged here. | passwords.go:90:12:90:19 | password | an access to password |
|
||||
| passwords.go:101:15:101:40 | ...+... | passwords.go:101:33:101:40 | password [string] | passwords.go:101:15:101:40 | ...+... | Sensitive data returned by $@ is logged here. | passwords.go:101:33:101:40 | password | an access to password |
|
||||
| passwords.go:107:16:107:41 | ...+... | passwords.go:107:34:107:41 | password [string] | passwords.go:107:16:107:41 | ...+... | Sensitive data returned by $@ is logged here. | passwords.go:107:34:107:41 | password | an access to password |
|
||||
| passwords.go:112:15:112:40 | ...+... | passwords.go:112:33:112:40 | password [string] | passwords.go:112:15:112:40 | ...+... | Sensitive data returned by $@ is logged here. | passwords.go:112:33:112:40 | password | an access to password |
|
||||
| passwords.go:116:14:116:45 | ...+... | passwords.go:116:28:116:36 | password1 [stringable] | passwords.go:116:14:116:45 | ...+... | Sensitive data returned by $@ is logged here. | passwords.go:116:28:116:36 | password1 | an access to password1 |
|
||||
| passwords.go:125:14:125:19 | config | passwords.go:118:12:123:2 | composite literal [Config] | passwords.go:125:14:125:19 | config | Sensitive data returned by $@ is logged here. | passwords.go:118:12:123:2 | composite literal | an access to password |
|
||||
| passwords.go:125:14:125:19 | config | passwords.go:121:13:121:20 | password [string] | passwords.go:125:14:125:19 | config | Sensitive data returned by $@ is logged here. | passwords.go:121:13:121:20 | password | an access to password |
|
||||
| passwords.go:125:14:125:19 | config | passwords.go:122:13:122:25 | call to getPassword [string] | passwords.go:125:14:125:19 | config | Sensitive data returned by $@ is logged here. | passwords.go:122:13:122:25 | call to getPassword | a call to getPassword |
|
||||
| passwords.go:126:14:126:21 | selection of x | passwords.go:121:13:121:20 | password [string] | passwords.go:126:14:126:21 | selection of x | Sensitive data returned by $@ is logged here. | passwords.go:121:13:121:20 | password | an access to password |
|
||||
| passwords.go:127:14:127:21 | selection of y | passwords.go:122:13:122:25 | call to getPassword [string] | passwords.go:127:14:127:21 | selection of y | Sensitive data returned by $@ is logged here. | passwords.go:122:13:122:25 | call to getPassword | a call to getPassword |
|
||||
| passwords.go:9:14:9:14 | x | passwords.go:30:8:30:15 | password : string | passwords.go:9:14:9:14 | x | Sensitive data returned by $@ is logged here. | passwords.go:30:8:30:15 | password | an access to password |
|
||||
| passwords.go:25:14:25:21 | password | passwords.go:25:14:25:21 | password | passwords.go:25:14:25:21 | password | Sensitive data returned by $@ is logged here. | passwords.go:25:14:25:21 | password | an access to password |
|
||||
| passwords.go:26:14:26:23 | selection of password | passwords.go:26:14:26:23 | selection of password | passwords.go:26:14:26:23 | selection of password | Sensitive data returned by $@ is logged here. | passwords.go:26:14:26:23 | selection of password | an access to password |
|
||||
| passwords.go:27:14:27:26 | call to getPassword | passwords.go:27:14:27:26 | call to getPassword | passwords.go:27:14:27:26 | call to getPassword | Sensitive data returned by $@ is logged here. | passwords.go:27:14:27:26 | call to getPassword | a call to getPassword |
|
||||
| passwords.go:28:14:28:28 | call to getPassword | passwords.go:28:14:28:28 | call to getPassword | passwords.go:28:14:28:28 | call to getPassword | Sensitive data returned by $@ is logged here. | passwords.go:28:14:28:28 | call to getPassword | a call to getPassword |
|
||||
| passwords.go:28:14:28:28 | call to getPassword | util.go:14:9:14:18 | selection of password : string | passwords.go:28:14:28:28 | call to getPassword | Sensitive data returned by $@ is logged here. | util.go:14:9:14:18 | selection of password | an access to password |
|
||||
| passwords.go:32:12:32:19 | password | passwords.go:32:12:32:19 | password | passwords.go:32:12:32:19 | password | Sensitive data returned by $@ is logged here. | passwords.go:32:12:32:19 | password | an access to password |
|
||||
| passwords.go:34:14:34:35 | ...+... | passwords.go:34:28:34:35 | password : string | passwords.go:34:14:34:35 | ...+... | Sensitive data returned by $@ is logged here. | passwords.go:34:28:34:35 | password | an access to password |
|
||||
| passwords.go:39:14:39:17 | obj1 | passwords.go:36:10:38:2 | composite literal : passStruct | passwords.go:39:14:39:17 | obj1 | Sensitive data returned by $@ is logged here. | passwords.go:36:10:38:2 | composite literal | an access to password |
|
||||
| passwords.go:44:14:44:17 | obj2 | passwords.go:42:6:42:13 | password : string | passwords.go:44:14:44:17 | obj2 | Sensitive data returned by $@ is logged here. | passwords.go:42:6:42:13 | password | an access to password |
|
||||
| passwords.go:47:14:47:17 | obj3 | passwords.go:48:11:48:18 | password : string | passwords.go:47:14:47:17 | obj3 | Sensitive data returned by $@ is logged here. | passwords.go:48:11:48:18 | password | an access to password |
|
||||
| passwords.go:51:14:51:27 | fixed_password | passwords.go:51:14:51:27 | fixed_password | passwords.go:51:14:51:27 | fixed_password | Sensitive data returned by $@ is logged here. | passwords.go:51:14:51:27 | fixed_password | an access to fixed_password |
|
||||
| passwords.go:88:14:88:26 | utilityObject | passwords.go:85:19:87:2 | composite literal : passSetStruct | passwords.go:88:14:88:26 | utilityObject | Sensitive data returned by $@ is logged here. | passwords.go:85:19:87:2 | composite literal | an access to passwordSet |
|
||||
| passwords.go:91:23:91:28 | secret | passwords.go:90:12:90:19 | password : string | passwords.go:91:23:91:28 | secret | Sensitive data returned by $@ is logged here. | passwords.go:90:12:90:19 | password | an access to password |
|
||||
| passwords.go:101:15:101:40 | ...+... | passwords.go:101:33:101:40 | password : string | passwords.go:101:15:101:40 | ...+... | Sensitive data returned by $@ is logged here. | passwords.go:101:33:101:40 | password | an access to password |
|
||||
| passwords.go:107:16:107:41 | ...+... | passwords.go:107:34:107:41 | password : string | passwords.go:107:16:107:41 | ...+... | Sensitive data returned by $@ is logged here. | passwords.go:107:34:107:41 | password | an access to password |
|
||||
| passwords.go:112:15:112:40 | ...+... | passwords.go:112:33:112:40 | password : string | passwords.go:112:15:112:40 | ...+... | Sensitive data returned by $@ is logged here. | passwords.go:112:33:112:40 | password | an access to password |
|
||||
| passwords.go:116:14:116:45 | ...+... | passwords.go:116:28:116:36 | password1 : stringable | passwords.go:116:14:116:45 | ...+... | Sensitive data returned by $@ is logged here. | passwords.go:116:28:116:36 | password1 | an access to password1 |
|
||||
| passwords.go:125:14:125:19 | config | passwords.go:118:12:123:2 | composite literal : Config | passwords.go:125:14:125:19 | config | Sensitive data returned by $@ is logged here. | passwords.go:118:12:123:2 | composite literal | an access to password |
|
||||
| passwords.go:125:14:125:19 | config | passwords.go:121:13:121:20 | password : string | passwords.go:125:14:125:19 | config | Sensitive data returned by $@ is logged here. | passwords.go:121:13:121:20 | password | an access to password |
|
||||
| passwords.go:125:14:125:19 | config | passwords.go:122:13:122:25 | call to getPassword : string | passwords.go:125:14:125:19 | config | Sensitive data returned by $@ is logged here. | passwords.go:122:13:122:25 | call to getPassword | a call to getPassword |
|
||||
| passwords.go:126:14:126:21 | selection of x | passwords.go:121:13:121:20 | password : string | passwords.go:126:14:126:21 | selection of x | Sensitive data returned by $@ is logged here. | passwords.go:121:13:121:20 | password | an access to password |
|
||||
| passwords.go:127:14:127:21 | selection of y | passwords.go:122:13:122:25 | call to getPassword : string | passwords.go:127:14:127:21 | selection of y | Sensitive data returned by $@ is logged here. | passwords.go:122:13:122:25 | call to getPassword | a call to getPassword |
|
||||
|
||||
@@ -1,16 +1,31 @@
|
||||
edges
|
||||
| OpenUrlRedirect.go:10:23:10:28 | selection of Form [Values] | OpenUrlRedirect.go:10:23:10:42 | call to Get |
|
||||
| stdlib.go:12:13:12:18 | selection of Form [Values] | stdlib.go:14:30:14:35 | target |
|
||||
| stdlib.go:21:13:21:18 | selection of Form [Values] | stdlib.go:23:30:23:35 | target |
|
||||
| stdlib.go:30:13:30:18 | selection of Form [Values] | stdlib.go:34:30:34:39 | ...+... |
|
||||
| stdlib.go:43:13:43:18 | selection of Form [Values] | stdlib.go:45:23:45:28 | target |
|
||||
| stdlib.go:63:13:63:18 | selection of Form [Values] | stdlib.go:66:23:66:40 | ...+... |
|
||||
| stdlib.go:88:13:88:18 | selection of Form [Values] | stdlib.go:91:23:91:28 | target |
|
||||
| OpenUrlRedirect.go:10:23:10:28 | selection of Form : Values | OpenUrlRedirect.go:10:23:10:42 | call to Get |
|
||||
| stdlib.go:12:13:12:18 | selection of Form : Values | stdlib.go:14:30:14:35 | target |
|
||||
| stdlib.go:21:13:21:18 | selection of Form : Values | stdlib.go:23:30:23:35 | target |
|
||||
| stdlib.go:30:13:30:18 | selection of Form : Values | stdlib.go:34:30:34:39 | ...+... |
|
||||
| stdlib.go:43:13:43:18 | selection of Form : Values | stdlib.go:45:23:45:28 | target |
|
||||
| stdlib.go:63:13:63:18 | selection of Form : Values | stdlib.go:66:23:66:40 | ...+... |
|
||||
| stdlib.go:88:13:88:18 | selection of Form : Values | stdlib.go:91:23:91:28 | target |
|
||||
nodes
|
||||
| OpenUrlRedirect.go:10:23:10:28 | selection of Form : Values | semmle.label | selection of Form : Values |
|
||||
| OpenUrlRedirect.go:10:23:10:42 | call to Get | semmle.label | call to Get |
|
||||
| stdlib.go:12:13:12:18 | selection of Form : Values | semmle.label | selection of Form : Values |
|
||||
| stdlib.go:14:30:14:35 | target | semmle.label | target |
|
||||
| stdlib.go:21:13:21:18 | selection of Form : Values | semmle.label | selection of Form : Values |
|
||||
| stdlib.go:23:30:23:35 | target | semmle.label | target |
|
||||
| stdlib.go:30:13:30:18 | selection of Form : Values | semmle.label | selection of Form : Values |
|
||||
| stdlib.go:34:30:34:39 | ...+... | semmle.label | ...+... |
|
||||
| stdlib.go:43:13:43:18 | selection of Form : Values | semmle.label | selection of Form : Values |
|
||||
| stdlib.go:45:23:45:28 | target | semmle.label | target |
|
||||
| stdlib.go:63:13:63:18 | selection of Form : Values | semmle.label | selection of Form : Values |
|
||||
| stdlib.go:66:23:66:40 | ...+... | semmle.label | ...+... |
|
||||
| stdlib.go:88:13:88:18 | selection of Form : Values | semmle.label | selection of Form : Values |
|
||||
| stdlib.go:91:23:91:28 | target | semmle.label | target |
|
||||
#select
|
||||
| OpenUrlRedirect.go:10:23:10:42 | call to Get | OpenUrlRedirect.go:10:23:10:28 | selection of Form [Values] | OpenUrlRedirect.go:10:23:10:42 | call to Get | Untrusted URL redirection due to $@. | OpenUrlRedirect.go:10:23:10:28 | selection of Form | user-provided value |
|
||||
| stdlib.go:14:30:14:35 | target | stdlib.go:12:13:12:18 | selection of Form [Values] | stdlib.go:14:30:14:35 | target | Untrusted URL redirection due to $@. | stdlib.go:12:13:12:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:23:30:23:35 | target | stdlib.go:21:13:21:18 | selection of Form [Values] | stdlib.go:23:30:23:35 | target | Untrusted URL redirection due to $@. | stdlib.go:21:13:21:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:34:30:34:39 | ...+... | stdlib.go:30:13:30:18 | selection of Form [Values] | stdlib.go:34:30:34:39 | ...+... | Untrusted URL redirection due to $@. | stdlib.go:30:13:30:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:45:23:45:28 | target | stdlib.go:43:13:43:18 | selection of Form [Values] | stdlib.go:45:23:45:28 | target | Untrusted URL redirection due to $@. | stdlib.go:43:13:43:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:66:23:66:40 | ...+... | stdlib.go:63:13:63:18 | selection of Form [Values] | stdlib.go:66:23:66:40 | ...+... | Untrusted URL redirection due to $@. | stdlib.go:63:13:63:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:91:23:91:28 | target | stdlib.go:88:13:88:18 | selection of Form [Values] | stdlib.go:91:23:91:28 | target | Untrusted URL redirection due to $@. | stdlib.go:88:13:88:18 | selection of Form | user-provided value |
|
||||
| OpenUrlRedirect.go:10:23:10:42 | call to Get | OpenUrlRedirect.go:10:23:10:28 | selection of Form : Values | OpenUrlRedirect.go:10:23:10:42 | call to Get | Untrusted URL redirection due to $@. | OpenUrlRedirect.go:10:23:10:28 | selection of Form | user-provided value |
|
||||
| stdlib.go:14:30:14:35 | target | stdlib.go:12:13:12:18 | selection of Form : Values | stdlib.go:14:30:14:35 | target | Untrusted URL redirection due to $@. | stdlib.go:12:13:12:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:23:30:23:35 | target | stdlib.go:21:13:21:18 | selection of Form : Values | stdlib.go:23:30:23:35 | target | Untrusted URL redirection due to $@. | stdlib.go:21:13:21:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:34:30:34:39 | ...+... | stdlib.go:30:13:30:18 | selection of Form : Values | stdlib.go:34:30:34:39 | ...+... | Untrusted URL redirection due to $@. | stdlib.go:30:13:30:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:45:23:45:28 | target | stdlib.go:43:13:43:18 | selection of Form : Values | stdlib.go:45:23:45:28 | target | Untrusted URL redirection due to $@. | stdlib.go:43:13:43:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:66:23:66:40 | ...+... | stdlib.go:63:13:63:18 | selection of Form : Values | stdlib.go:66:23:66:40 | ...+... | Untrusted URL redirection due to $@. | stdlib.go:63:13:63:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:91:23:91:28 | target | stdlib.go:88:13:88:18 | selection of Form : Values | stdlib.go:91:23:91:28 | target | Untrusted URL redirection due to $@. | stdlib.go:88:13:88:18 | selection of Form | user-provided value |
|
||||
|
||||
Reference in New Issue
Block a user