mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
JS: introduce near-empty RegularExpressions.qll
This commit is contained in:
@@ -11,7 +11,6 @@
|
||||
*/
|
||||
|
||||
import javascript
|
||||
import semmle.javascript.security.dataflow.RegExpInjection
|
||||
|
||||
module IncompleteUrlRegExpTracking {
|
||||
|
||||
@@ -28,7 +27,7 @@ module IncompleteUrlRegExpTracking {
|
||||
|
||||
override
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
sink instanceof RegExpInjection::Sink
|
||||
isInterpretedAsRegExp(sink)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
/**
|
||||
* Provides classes for working with regular expression literals.
|
||||
* Provides classes for working with regular expressions.
|
||||
*
|
||||
* Regular expressions are represented as an abstract syntax tree of regular expression
|
||||
* Regular expression literals are represented as an abstract syntax tree of regular expression
|
||||
* terms.
|
||||
*/
|
||||
|
||||
import javascript
|
||||
private import semmle.javascript.dataflow.InferredTypes
|
||||
|
||||
/**
|
||||
* An element containing a regular expression term, that is, either
|
||||
@@ -484,3 +485,27 @@ class RegExpParseError extends Error, @regexp_parse_error {
|
||||
result = getMessage()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `source` may be interpreted as a regular expression.
|
||||
*/
|
||||
predicate isInterpretedAsRegExp(DataFlow::Node source) {
|
||||
// The first argument to an invocation of `RegExp` (with or without `new`).
|
||||
source = DataFlow::globalVarRef("RegExp").getAnInvocation().getArgument(0)
|
||||
or
|
||||
// The argument of a call that coerces the argument to a regular expression.
|
||||
exists(MethodCallExpr mce, string methodName |
|
||||
mce.getReceiver().analyze().getAType() = TTString() and
|
||||
mce.getMethodName() = methodName
|
||||
|
|
||||
(methodName = "match" and source.asExpr() = mce.getArgument(0) and mce.getNumArgument() = 1)
|
||||
or
|
||||
(
|
||||
methodName = "search" and
|
||||
source.asExpr() = mce.getArgument(0) and
|
||||
mce.getNumArgument() = 1 and
|
||||
// `String.prototype.search` returns a number, so exclude chained accesses
|
||||
not exists(PropAccess p | p.getBase() = mce)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
*/
|
||||
|
||||
import javascript
|
||||
private import semmle.javascript.dataflow.InferredTypes
|
||||
|
||||
module RegExpInjection {
|
||||
/**
|
||||
@@ -51,36 +50,14 @@ module RegExpInjection {
|
||||
}
|
||||
|
||||
/**
|
||||
* The first argument to an invocation of `RegExp` (with or without `new`).
|
||||
* The source string of a regular expression.
|
||||
*/
|
||||
class RegExpObjectCreationSink extends Sink, DataFlow::ValueNode {
|
||||
RegExpObjectCreationSink() {
|
||||
this = DataFlow::globalVarRef("RegExp").getAnInvocation().getArgument(0)
|
||||
class RegularExpressionSourceAsSink extends Sink {
|
||||
RegularExpressionSourceAsSink() {
|
||||
isInterpretedAsRegExp(this)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The argument of a call that coerces the argument to a regular expression.
|
||||
*/
|
||||
class RegExpObjectCoercionSink extends Sink {
|
||||
|
||||
RegExpObjectCoercionSink() {
|
||||
exists (MethodCallExpr mce, string methodName |
|
||||
mce.getReceiver().analyze().getAType() = TTString() and
|
||||
mce.getMethodName() = methodName |
|
||||
(methodName = "match" and this.asExpr() = mce.getArgument(0) and mce.getNumArgument() = 1) or
|
||||
(
|
||||
methodName = "search" and
|
||||
this.asExpr() = mce.getArgument(0) and
|
||||
mce.getNumArgument() = 1 and
|
||||
// `String.prototype.search` returns a number, so exclude chained accesses
|
||||
not exists(PropAccess p | p.getBase() = mce)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to a function whose name suggests that it escapes regular
|
||||
* expression meta-characters.
|
||||
|
||||
Reference in New Issue
Block a user