mirror of
https://github.com/github/codeql.git
synced 2026-04-29 02:35:15 +02:00
Merge branch 'jorgectf/python/headerInjection' into jorgectf/python/insecure-cookie
This commit is contained in:
@@ -213,21 +213,26 @@ class SQLEscape extends DataFlow::Node {
|
||||
/** Provides classes for modeling HTTP Header APIs. */
|
||||
module HeaderDeclaration {
|
||||
/**
|
||||
* A data-flow node that collects functions setting HTTP Headers' content.
|
||||
* A data-flow node that collects functions setting HTTP Headers.
|
||||
*
|
||||
* Extend this class to model new APIs. If you want to refine existing API models,
|
||||
* extend `HeaderDeclaration` instead.
|
||||
*/
|
||||
abstract class Range extends DataFlow::Node {
|
||||
/**
|
||||
* Gets the argument containing the header name.
|
||||
*/
|
||||
abstract DataFlow::Node getNameArg();
|
||||
|
||||
/**
|
||||
* Gets the argument containing the header value.
|
||||
*/
|
||||
abstract DataFlow::Node getAnInput();
|
||||
abstract DataFlow::Node getValueArg();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data-flow node that collects functions setting HTTP Headers' content.
|
||||
* A data-flow node that collects functions setting HTTP Headers.
|
||||
*
|
||||
* Extend this class to model new APIs. If you want to refine existing API models,
|
||||
* extend `HeaderDeclaration` instead.
|
||||
@@ -238,7 +243,12 @@ class HeaderDeclaration extends DataFlow::Node {
|
||||
HeaderDeclaration() { this = range }
|
||||
|
||||
/**
|
||||
* Gets the argument containing the header value.
|
||||
* Gets the argument containing the header name.
|
||||
*/
|
||||
DataFlow::Node getAnInput() { result = range.getAnInput() }
|
||||
DataFlow::Node getNameArg() { result = range.getNameArg() }
|
||||
|
||||
/**
|
||||
* Gets the argument containing the header name.
|
||||
*/
|
||||
DataFlow::Node getValueArg() { result = range.getValueArg() }
|
||||
}
|
||||
|
||||
@@ -56,7 +56,9 @@ private module PrivateDjango {
|
||||
class DjangoResponseSetItemCall extends DataFlow::CallCfgNode, HeaderDeclaration::Range {
|
||||
DjangoResponseSetItemCall() { this.getFunction() = headerSetItemCall() }
|
||||
|
||||
override DataFlow::Node getAnInput() { result = this.getArg([0, 1]) }
|
||||
override DataFlow::Node getNameArg() { result = this.getArg(0) }
|
||||
|
||||
override DataFlow::Node getValueArg() { result = this.getArg(1) }
|
||||
}
|
||||
|
||||
class DjangoResponseDefinition extends DataFlow::Node, HeaderDeclaration::Range {
|
||||
@@ -67,9 +69,11 @@ private module PrivateDjango {
|
||||
headerInput.asCfgNode() = this.asCfgNode().(DefinitionNode).getValue()
|
||||
}
|
||||
|
||||
override DataFlow::Node getAnInput() {
|
||||
result.asExpr() in [headerInput.asExpr(), this.asExpr().(Subscript).getIndex()]
|
||||
override DataFlow::Node getNameArg() {
|
||||
result.asExpr() = this.asExpr().(Subscript).getIndex()
|
||||
}
|
||||
|
||||
override DataFlow::Node getValueArg() { result = headerInput }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,20 +54,31 @@ module ExperimentalFlask {
|
||||
headerInput.asCfgNode() = this.asCfgNode().(DefinitionNode).getValue()
|
||||
}
|
||||
|
||||
override DataFlow::Node getAnInput() {
|
||||
result.asExpr() in [headerInput.asExpr(), this.asExpr().(Subscript).getIndex()]
|
||||
}
|
||||
override DataFlow::Node getNameArg() { result.asExpr() = this.asExpr().(Subscript).getIndex() }
|
||||
|
||||
override DataFlow::Node getValueArg() { result = headerInput }
|
||||
}
|
||||
|
||||
private class FlaskMakeResponseExtend extends DataFlow::CallCfgNode, HeaderDeclaration::Range {
|
||||
FlaskMakeResponseExtend() { this.getFunction() = headerInstanceCall() }
|
||||
KeyValuePair item;
|
||||
|
||||
override DataFlow::Node getAnInput() { result = this.getArg(_) }
|
||||
FlaskMakeResponseExtend() {
|
||||
this.getFunction() = headerInstanceCall() and
|
||||
item = this.getArg(_).asExpr().(Dict).getAnItem()
|
||||
}
|
||||
|
||||
override DataFlow::Node getNameArg() { result.asExpr() = item.getKey() }
|
||||
|
||||
override DataFlow::Node getValueArg() { result.asExpr() = item.getValue() }
|
||||
}
|
||||
|
||||
private class FlaskResponse extends DataFlow::CallCfgNode, HeaderDeclaration::Range {
|
||||
KeyValuePair item;
|
||||
|
||||
FlaskResponse() { this = Flask::Response::classRef().getACall() }
|
||||
|
||||
override DataFlow::Node getAnInput() { result = this.getArgByName("headers") }
|
||||
override DataFlow::Node getNameArg() { result.asExpr() = item.getKey() }
|
||||
|
||||
override DataFlow::Node getValueArg() { result.asExpr() = item.getValue() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,9 @@ private module Werkzeug {
|
||||
this.getFunction().(DataFlow::AttrRead).getAttributeName() = "add"
|
||||
}
|
||||
|
||||
override DataFlow::Node getAnInput() { result = this.getArg(_) }
|
||||
override DataFlow::Node getNameArg() { result = this.getArg(0) }
|
||||
|
||||
override DataFlow::Node getValueArg() { result = this.getArg(1) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ class HeaderInjectionFlowConfig extends TaintTracking::Configuration {
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
sink = any(HeaderDeclaration headerDeclaration).getAnInput()
|
||||
exists(HeaderDeclaration headerDeclaration |
|
||||
sink in [headerDeclaration.getNameArg(), headerDeclaration.getValueArg()]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user