@@ -11,60 +11,81 @@ private import codeql.rust.dataflow.FlowSink
1111private import codeql.rust.Concepts
1212
1313/**
14- * A data flow sink for regular expression injection vulnerabilities.
14+ * Provides default sources, sinks and barriers for detecting regular expression
15+ * injection vulnerabilities, as well as extension points for adding your own.
1516 */
16- abstract class RegexInjectionSink extends QuerySink:: Range {
17- override string getSinkType ( ) { result = "RegexInjection" }
18- }
17+ module RegexInjection {
18+ /**
19+ * A data flow source for regular expression injection vulnerabilities.
20+ */
21+ abstract class Source extends DataFlow:: Node { }
1922
20- /**
21- * A barrier for regular expression injection vulnerabilities.
22- */
23- abstract class RegexInjectionBarrier extends DataFlow:: Node { }
23+ /**
24+ * A data flow sink for regular expression injection vulnerabilities.
25+ */
26+ abstract class Sink extends QuerySink:: Range {
27+ override string getSinkType ( ) { result = "RegexInjection" }
28+ }
2429
25- /** A sink for `a` in `Regex::new(a)` when `a` is not a literal. */
26- private class NewRegexInjectionSink extends RegexInjectionSink {
27- NewRegexInjectionSink ( ) {
28- exists ( CallExprCfgNode call , PathExpr path |
29- path = call .getFunction ( ) .getExpr ( ) and
30- path .getResolvedCrateOrigin ( ) = "repo:https://github.com/rust-lang/regex:regex" and
31- path .getResolvedPath ( ) = "<crate::regex::string::Regex>::new" and
32- this .asExpr ( ) = call .getArgument ( 0 ) and
33- not this .asExpr ( ) instanceof LiteralExprCfgNode
34- )
30+ /**
31+ * A barrier for regular expression injection vulnerabilities.
32+ */
33+ abstract class Barrier extends DataFlow:: Node { }
34+
35+ /**
36+ * A unit class for adding additional flow steps.
37+ */
38+ class AdditionalFlowStep extends Unit {
39+ /**
40+ * Holds if the step from `node1` to `node2` should be considered a flow
41+ * step for paths related to regular expression injection vulnerabilities.
42+ */
43+ abstract predicate step ( DataFlow:: Node node1 , DataFlow:: Node node2 ) ;
3544 }
36- }
3745
38- private class MadRegexInjectionSink extends RegexInjectionSink {
39- MadRegexInjectionSink ( ) { sinkNode ( this , "regex-use" ) }
40- }
46+ /**
47+ * An active threat-model source, considered as a flow source.
48+ */
49+ private class ActiveThreatModelSourceAsSource extends Source , ActiveThreatModelSource { }
4150
42- /**
43- * A unit class for adding additional flow steps.
44- */
45- class RegexInjectionAdditionalFlowStep extends Unit {
4651 /**
47- * Holds if the step from `node1` to `node2` should be considered a flow
48- * step for paths related to regular expression injection vulnerabilities.
52+ * A sink for `a` in `Regex::new(a)` when `a` is not a literal.
4953 */
50- abstract predicate step ( DataFlow:: Node node1 , DataFlow:: Node node2 ) ;
51- }
54+ private class NewSink extends Sink {
55+ NewSink ( ) {
56+ exists ( CallExprCfgNode call , PathExpr path |
57+ path = call .getFunction ( ) .getExpr ( ) and
58+ path .getResolvedCrateOrigin ( ) = "repo:https://github.com/rust-lang/regex:regex" and
59+ path .getResolvedPath ( ) = "<crate::regex::string::Regex>::new" and
60+ this .asExpr ( ) = call .getArgument ( 0 ) and
61+ not this .asExpr ( ) instanceof LiteralExprCfgNode
62+ )
63+ }
64+ }
5265
53- /**
54- * An escape barrier for regular expression injection vulnerabilities.
55- */
56- private class RegexInjectionDefaultBarrier extends RegexInjectionBarrier {
57- RegexInjectionDefaultBarrier ( ) {
58- // A barrier is any call to a function named `escape`, in particular this
59- // makes calls to `regex::escape` a barrier.
60- this .asExpr ( )
61- .getExpr ( )
62- .( CallExpr )
63- .getFunction ( )
64- .( PathExpr )
65- .getPath ( )
66- .getSegment ( )
67- .getIdentifier ( )
68- .getText ( ) = "escape"
66+ /**
67+ * A sink for regular expression injection from model data.
68+ */
69+ private class ModelsAsDataSink extends Sink {
70+ ModelsAsDataSink ( ) { sinkNode ( this , "regex-use" ) }
71+ }
72+
73+ /**
74+ * An escape barrier for regular expression injection vulnerabilities.
75+ */
76+ private class DefaultBarrier extends Barrier {
77+ DefaultBarrier ( ) {
78+ // A barrier is any call to a function named `escape`, in particular this
79+ // makes calls to `regex::escape` a barrier.
80+ this .asExpr ( )
81+ .getExpr ( )
82+ .( CallExpr )
83+ .getFunction ( )
84+ .( PathExpr )
85+ .getPath ( )
86+ .getSegment ( )
87+ .getIdentifier ( )
88+ .getText ( ) = "escape"
89+ }
6990 }
7091}
0 commit comments