Swift: First version swift/regex-injection query.

This commit is contained in:
Geoffrey White
2023-07-03 09:44:45 +01:00
parent ca71d48e4a
commit b41fd52be5
3 changed files with 98 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
/**
* Provides classes and predicates to reason about regular expression injection
* vulnerabilities.
*/
import swift
import codeql.swift.dataflow.DataFlow
import codeql.swift.dataflow.ExternalFlow
import codeql.swift.regex.Regex
/**
* A data flow sink for regular expression injection vulnerabilities.
*/
abstract class RegexInjectionSink extends DataFlow::Node { }
/**
* A barrier for regular expression injection vulnerabilities.
*/
abstract class RegexInjectionBarrier extends DataFlow::Node { }
/**
* A unit class for adding additional flow steps.
*/
class RegexInjectionAdditionalFlowStep extends Unit {
/**
* Holds if the step from `node1` to `node2` should be considered a flow
* step for paths related to regular expression injection vulnerabilities.
*/
abstract predicate step(DataFlow::Node node1, DataFlow::Node node2);
}
/**
* A sink that is a regular expression evaluation defined in the Regex library.
*/
private class EvalRegexInjectionSink extends RegexInjectionSink {
EvalRegexInjectionSink() { this.asExpr() = any(RegexEval e).getRegexInput() }
}
/**
* A sink that is a regular expression use defined in a CSV model.
*/
private class DefaultRegexInjectionSink extends RegexInjectionSink {
DefaultRegexInjectionSink() { sinkNode(this, "regex-use") }
}

View File

@@ -0,0 +1,30 @@
/**
* Provides a taint-tracking configuration for detecting regular expression
* injection vulnerabilities.
*/
import swift
import codeql.swift.dataflow.DataFlow
import codeql.swift.dataflow.TaintTracking
import codeql.swift.dataflow.FlowSources
import codeql.swift.security.regex.RegexInjectionExtensions
/**
* A taint configuration for detecting regular expression injection vulnerabilities.
*/
module RegexInjectionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof FlowSource }
predicate isSink(DataFlow::Node sink) { sink instanceof RegexInjectionSink }
predicate isBarrier(DataFlow::Node barrier) { barrier instanceof RegexInjectionBarrier }
predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
any(RegexInjectionAdditionalFlowStep s).step(nodeFrom, nodeTo)
}
}
/**
* Detect taint flow of tainted data that reaches a regular expression sink.
*/
module RegexInjectionFlow = TaintTracking::Global<RegexInjectionConfig>;

View File

@@ -0,0 +1,24 @@
/**
* @name Regular expression injection
* @description User input should not be used in regular expressions without first being escaped,
* otherwise a malicious user may be able to provide a regex that could require
* exponential time on certain inputs.
* @kind path-problem
* @problem.severity error
* @security-severity 7.5
* @precision high
* @id swift/regex-injection
* @tags security
* external/cwe/cwe-730
* external/cwe/cwe-400
*/
import swift
import codeql.swift.dataflow.DataFlow
import codeql.swift.security.regex.RegexInjectionQuery
import RegexInjectionFlow::PathGraph
from RegexInjectionFlow::PathNode sourceNode, RegexInjectionFlow::PathNode sinkNode
where RegexInjectionFlow::flowPath(sourceNode, sinkNode)
select sinkNode.getNode(), sourceNode, sinkNode,
"This regular expression is constructed from a $@.", sourceNode.getNode(), "user-provided value"