mirror of
https://github.com/github/codeql.git
synced 2026-04-28 10:15:14 +02:00
Merge branch 'rc/1.21' into 'master'
This commit is contained in:
@@ -28,14 +28,17 @@ private newtype PropertyName =
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the representation of the property name of `pacc`, if any.
|
||||
* Gets an access to property `name` of access path `base` in basic block `bb`.
|
||||
*/
|
||||
private PropertyName getPropertyName(PropAccess pacc) {
|
||||
result = StaticPropertyName(pacc.getPropertyName())
|
||||
or
|
||||
exists(SsaVariable var |
|
||||
pacc.getPropertyNameExpr() = var.getAUse() and
|
||||
result = DynamicPropertyName(var)
|
||||
private PropAccess namedPropAccess(AccessPath base, PropertyName name, BasicBlock bb) {
|
||||
result.getBase() = base.getAnInstanceIn(bb) and
|
||||
(
|
||||
name = StaticPropertyName(result.getPropertyName())
|
||||
or
|
||||
exists(SsaVariable var |
|
||||
result.getPropertyNameExpr() = var.getAUse() and
|
||||
name = DynamicPropertyName(var)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -76,10 +79,7 @@ private newtype TAccessPath =
|
||||
* A property access on an access path.
|
||||
*/
|
||||
MkAccessStep(AccessPath base, PropertyName name) {
|
||||
exists(PropAccess pacc |
|
||||
pacc.getBase() = base.getAnInstance() and
|
||||
getPropertyName(pacc) = name
|
||||
)
|
||||
exists(namedPropAccess(base, name, _))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -108,24 +108,9 @@ class AccessPath extends TAccessPath {
|
||||
this_.getBasicBlock() = bb
|
||||
)
|
||||
or
|
||||
exists(PropertyName name |
|
||||
result = getABaseInstanceIn(bb, name) and
|
||||
getPropertyName(result) = name
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a property access in `bb` whose base is represented by the
|
||||
* base of this access path, and where `name` is bound to the last
|
||||
* component of this access path.
|
||||
*
|
||||
* This is an auxiliary predicate that's needed to enforce a better
|
||||
* join order in `getAnInstanceIn` above.
|
||||
*/
|
||||
pragma[noinline]
|
||||
private PropAccess getABaseInstanceIn(BasicBlock bb, PropertyName name) {
|
||||
exists(AccessPath base | this = MkAccessStep(base, name) |
|
||||
result.getBase() = base.getAnInstanceIn(bb)
|
||||
exists(AccessPath base, PropertyName name |
|
||||
this = MkAccessStep(base, name) and
|
||||
result = namedPropAccess(base, name, bb)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -271,16 +271,19 @@ module ReflectedXss {
|
||||
* a content type that does not (case-insensitively) contain the string "html". This
|
||||
* is to prevent us from flagging plain-text or JSON responses as vulnerable.
|
||||
*/
|
||||
private class HttpResponseSink extends Sink {
|
||||
HttpResponseSink() {
|
||||
exists(HTTP::ResponseSendArgument sendarg | sendarg = asExpr() |
|
||||
forall(HTTP::HeaderDefinition hd |
|
||||
hd = sendarg.getRouteHandler().getAResponseHeader("content-type")
|
||||
|
|
||||
exists(string tp | hd.defines("content-type", tp) | tp.toLowerCase().matches("%html%"))
|
||||
)
|
||||
)
|
||||
}
|
||||
private class HttpResponseSink extends Sink, DataFlow::ValueNode {
|
||||
override HTTP::ResponseSendArgument astNode;
|
||||
|
||||
HttpResponseSink() { not nonHtmlContentType(astNode.getRouteHandler()) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `h` may send a response with a content type other than HTML.
|
||||
*/
|
||||
private predicate nonHtmlContentType(HTTP::RouteHandler h) {
|
||||
exists(HTTP::HeaderDefinition hd | hd = h.getAResponseHeader("content-type") |
|
||||
not exists(string tp | hd.defines("content-type", tp) | tp.regexpMatch("(?i).*html.*"))
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user