Merge branch 'main' into p--ruby-kernel-open-addition

This commit is contained in:
Peter Stöckli
2022-11-29 10:19:36 +01:00
committed by GitHub
65 changed files with 1535 additions and 990 deletions

View File

@@ -497,6 +497,7 @@ private module Cached {
FlowSummaryImplSpecific::ParsePositions::isParsedKeywordParameterPosition(_, name)
} or
THashSplatArgumentPosition() or
TSplatAllArgumentPosition() or
TAnyArgumentPosition() or
TAnyKeywordArgumentPosition()
@@ -518,6 +519,7 @@ private module Cached {
FlowSummaryImplSpecific::ParsePositions::isParsedKeywordArgumentPosition(_, name)
} or
THashSplatParameterPosition() or
TSplatAllParameterPosition() or
TAnyParameterPosition() or
TAnyKeywordParameterPosition()
}
@@ -1149,6 +1151,8 @@ class ParameterPosition extends TParameterPosition {
/** Holds if this position represents a hash-splat parameter. */
predicate isHashSplat() { this = THashSplatParameterPosition() }
predicate isSplatAll() { this = TSplatAllParameterPosition() }
/**
* Holds if this position represents any parameter, except `self` parameters. This
* includes both positional, named, and block parameters.
@@ -1172,6 +1176,8 @@ class ParameterPosition extends TParameterPosition {
or
this.isHashSplat() and result = "**"
or
this.isSplatAll() and result = "*"
or
this.isAny() and result = "any"
or
this.isAnyNamed() and result = "any-named"
@@ -1207,6 +1213,8 @@ class ArgumentPosition extends TArgumentPosition {
*/
predicate isHashSplat() { this = THashSplatArgumentPosition() }
predicate isSplatAll() { this = TSplatAllArgumentPosition() }
/** Gets a textual representation of this position. */
string toString() {
this.isSelf() and result = "self"
@@ -1222,6 +1230,8 @@ class ArgumentPosition extends TArgumentPosition {
this.isAnyNamed() and result = "any-named"
or
this.isHashSplat() and result = "**"
or
this.isSplatAll() and result = "*"
}
}
@@ -1248,6 +1258,8 @@ predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) {
or
ppos.isHashSplat() and apos.isHashSplat()
or
ppos.isSplatAll() and apos.isSplatAll()
or
ppos.isAny() and argumentPositionIsNotSelf(apos)
or
apos.isAny() and parameterPositionIsNotSelf(ppos)

View File

@@ -241,6 +241,10 @@ private class Argument extends CfgNodes::ExprCfgNode {
this = call.getAnArgument() and
this.getExpr() instanceof HashSplatExpr and
arg.isHashSplat()
or
this = call.getArgument(0) and
this.getExpr() instanceof SplatExpr and
arg.isSplatAll()
}
/** Holds if this expression is the `i`th argument of `c`. */
@@ -276,7 +280,8 @@ private module Cached {
p instanceof SimpleParameter or
p instanceof OptionalParameter or
p instanceof KeywordParameter or
p instanceof HashSplatParameter
p instanceof HashSplatParameter or
p instanceof SplatParameter
} or
TSelfParameterNode(MethodBase m) or
TBlockParameterNode(MethodBase m) or
@@ -616,6 +621,9 @@ private module ParameterNodes {
or
parameter = callable.getAParameter().(HashSplatParameter) and
pos.isHashSplat()
or
parameter = callable.getParameter(0).(SplatParameter) and
pos.isSplatAll()
)
}

View File

@@ -0,0 +1,55 @@
/**
* Provides default sources, sinks and sanitizers for detecting stack trace
* exposure vulnerabilities, as well as extension points for adding your own.
*/
private import codeql.ruby.AST
private import codeql.ruby.Concepts
private import codeql.ruby.DataFlow
private import codeql.ruby.controlflow.CfgNodes
private import codeql.ruby.frameworks.core.Kernel
/**
* Provides default sources, sinks and sanitizers for detecting stack trace
* exposure vulnerabilities, as well as extension points for adding your own.
*/
module StackTraceExposure {
/** A data flow source for stack trace exposure vulnerabilities. */
abstract class Source extends DataFlow::Node { }
/** A data flow sink for stack trace exposure vulnerabilities. */
abstract class Sink extends DataFlow::Node { }
/** A data flow sanitizer for stack trace exposure vulnerabilities. */
abstract class Sanitizer extends DataFlow::Node { }
/**
* A call to `backtrace` or `backtrace_locations` on a `rescue` variable,
* considered as a flow source.
*/
class BacktraceCall extends Source, DataFlow::CallNode {
BacktraceCall() {
exists(DataFlow::LocalSourceNode varAccess |
varAccess.asExpr().(ExprNodes::VariableReadAccessCfgNode).getExpr().getVariable() =
any(RescueClause rc).getVariableExpr().(VariableAccess).getVariable() and
varAccess.flowsTo(this.getReceiver())
) and
this.getMethodName() = ["backtrace", "backtrace_locations"]
}
}
/**
* A call to `Kernel#caller`, considered as a flow source.
*/
class KernelCallerCall extends Source, Kernel::KernelMethodCall {
KernelCallerCall() { this.getMethodName() = "caller" }
}
/**
* The body of an HTTP response that will be returned from a server,
* considered as a flow sink.
*/
class ServerHttpResponseBodyAsSink extends Sink {
ServerHttpResponseBodyAsSink() { this = any(Http::Server::HttpResponse response).getBody() }
}
}

View File

@@ -0,0 +1,25 @@
/**
* Provides a taint-tracking configuration for detecting stack-trace exposure
* vulnerabilities.
*
* Note, for performance reasons: only import this file if
* `StackTraceExposure::Configuration` is needed; otherwise,
* `StackTraceExposureCustomizations` should be imported instead.
*/
private import codeql.ruby.DataFlow
private import codeql.ruby.TaintTracking
private import StackTraceExposureCustomizations::StackTraceExposure
/**
* A taint-tracking configuration for detecting "stack trace exposure" vulnerabilities.
*/
class Configuration extends TaintTracking::Configuration {
Configuration() { this = "StackTraceExposure" }
override predicate isSource(DataFlow::Node source) { source instanceof Source }
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
}