Merge pull request #11070 from jcogs33/java-regex-injection

Java: Promote regex injection query from experimental
This commit is contained in:
Jami
2022-11-21 15:04:26 -05:00
committed by GitHub
17 changed files with 225 additions and 245 deletions

View File

@@ -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 =

View File

@@ -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",
]
}
}

View File

@@ -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()
)
}
}

View File

@@ -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 }
}