mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
Merge pull request #11070 from jcogs33/java-regex-injection
Java: Promote regex injection query from experimental
This commit is contained in:
@@ -2,6 +2,27 @@
|
||||
|
||||
private import semmle.code.java.dataflow.ExternalFlow
|
||||
|
||||
/** The class `java.util.regex.Pattern`. */
|
||||
class TypeRegexPattern extends Class {
|
||||
TypeRegexPattern() { this.hasQualifiedName("java.util.regex", "Pattern") }
|
||||
}
|
||||
|
||||
/** The `quote` method of the `java.util.regex.Pattern` class. */
|
||||
class PatternQuoteMethod extends Method {
|
||||
PatternQuoteMethod() {
|
||||
this.getDeclaringType() instanceof TypeRegexPattern and
|
||||
this.hasName("quote")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `LITERAL` field of the `java.util.regex.Pattern` class. */
|
||||
class PatternLiteralField extends Field {
|
||||
PatternLiteralField() {
|
||||
this.getDeclaringType() instanceof TypeRegexPattern and
|
||||
this.hasName("LITERAL")
|
||||
}
|
||||
}
|
||||
|
||||
private class RegexModel extends SummaryModelCsv {
|
||||
override predicate row(string s) {
|
||||
s =
|
||||
|
||||
@@ -27,6 +27,12 @@ private class RegexSinkCsv extends SinkModelCsv {
|
||||
"com.google.common.base;Splitter;false;split;(CharSequence);;Argument[-1];regex-use[0];manual",
|
||||
"com.google.common.base;Splitter;false;splitToList;(CharSequence);;Argument[-1];regex-use[0];manual",
|
||||
"com.google.common.base;Splitter$MapSplitter;false;split;(CharSequence);;Argument[-1];regex-use[0];manual",
|
||||
"org.apache.commons.lang3;RegExUtils;false;removeAll;(String,String);;Argument[1];regex-use;manual",
|
||||
"org.apache.commons.lang3;RegExUtils;false;removeFirst;(String,String);;Argument[1];regex-use;manual",
|
||||
"org.apache.commons.lang3;RegExUtils;false;removePattern;(String,String);;Argument[1];regex-use;manual",
|
||||
"org.apache.commons.lang3;RegExUtils;false;replaceAll;(String,String,String);;Argument[1];regex-use;manual",
|
||||
"org.apache.commons.lang3;RegExUtils;false;replaceFirst;(String,String,String);;Argument[1];regex-use;manual",
|
||||
"org.apache.commons.lang3;RegExUtils;false;replacePattern;(String,String,String);;Argument[1];regex-use;manual",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/** Provides classes and predicates related to regex injection in Java. */
|
||||
|
||||
import java
|
||||
private import semmle.code.java.dataflow.DataFlow
|
||||
private import semmle.code.java.frameworks.Regex
|
||||
private import semmle.code.java.regex.RegexFlowModels
|
||||
|
||||
/** A data flow sink for untrusted user input used to construct regular expressions. */
|
||||
abstract class RegexInjectionSink extends DataFlow::ExprNode { }
|
||||
|
||||
/** A sanitizer for untrusted user input used to construct regular expressions. */
|
||||
abstract class RegexInjectionSanitizer extends DataFlow::ExprNode { }
|
||||
|
||||
/** A method call that takes a regular expression as an argument. */
|
||||
private class DefaultRegexInjectionSink extends RegexInjectionSink {
|
||||
DefaultRegexInjectionSink() {
|
||||
// we only select sinks where there is direct regex creation, not regex uses
|
||||
sinkNode(this, ["regex-use[]", "regex-use[f1]", "regex-use[f-1]", "regex-use[-1]", "regex-use"])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to the `Pattern.quote` method, which gives metacharacters or escape sequences
|
||||
* no special meaning.
|
||||
*/
|
||||
private class PatternQuoteCall extends RegexInjectionSanitizer {
|
||||
PatternQuoteCall() {
|
||||
exists(MethodAccess ma, Method m | m = ma.getMethod() |
|
||||
ma.getArgument(0) = this.asExpr() and
|
||||
m instanceof PatternQuoteMethod
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use of the `Pattern.LITERAL` flag with `Pattern.compile`, which gives metacharacters
|
||||
* or escape sequences no special meaning.
|
||||
*/
|
||||
private class PatternLiteralFlag extends RegexInjectionSanitizer {
|
||||
PatternLiteralFlag() {
|
||||
exists(MethodAccess ma, Method m, PatternLiteralField field | m = ma.getMethod() |
|
||||
ma.getArgument(0) = this.asExpr() and
|
||||
m.getDeclaringType() instanceof TypeRegexPattern and
|
||||
m.hasName("compile") and
|
||||
ma.getArgument(1) = field.getAnAccess()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/** Provides configurations to be used in queries related to regex injection. */
|
||||
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.security.regexp.RegexInjection
|
||||
|
||||
/** A taint-tracking configuration for untrusted user input used to construct regular expressions. */
|
||||
class RegexInjectionConfiguration extends TaintTracking::Configuration {
|
||||
RegexInjectionConfiguration() { this = "RegexInjection" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof RegexInjectionSink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) { node instanceof RegexInjectionSanitizer }
|
||||
}
|
||||
Reference in New Issue
Block a user