@@ -19,12 +19,7 @@ class CodeInjectionSink extends DataFlow::Node {
1919Event getRelevantCriticalEventForSink ( DataFlow:: Node sink ) {
2020 inPrivilegedContext ( sink .asExpr ( ) , result ) and
2121 not exists ( ControlCheck check | check .protects ( sink .asExpr ( ) , result , "code-injection" ) ) and
22- // exclude cases where the sink is a JS script and the expression uses toJson
23- not exists ( UsesStep script |
24- script .getCallee ( ) = "actions/github-script" and
25- script .getArgumentExpr ( "script" ) = sink .asExpr ( ) and
26- exists ( getAToJsonReferenceExpression ( sink .asExpr ( ) .( Expression ) .getExpression ( ) , _) )
27- )
22+ not isGithubScriptUsingToJson ( sink .asExpr ( ) )
2823}
2924
3025/**
@@ -91,3 +86,38 @@ private module CodeInjectionConfig implements DataFlow::ConfigSig {
9186
9287/** Tracks flow of unsafe user input that is used to construct and evaluate a code script. */
9388module CodeInjectionFlow = TaintTracking:: Global< CodeInjectionConfig > ;
89+
90+ /**
91+ * Holds if there is a code injection flow from `source` to `sink` with
92+ * critical severity, linked by `event`.
93+ */
94+ predicate criticalSeverityCodeInjection (
95+ CodeInjectionFlow:: PathNode source , CodeInjectionFlow:: PathNode sink , Event event
96+ ) {
97+ CodeInjectionFlow:: flowPath ( source , sink ) and
98+ event = getRelevantCriticalEventForSink ( sink .getNode ( ) ) and
99+ source .getNode ( ) .( RemoteFlowSource ) .getEventName ( ) = event .getName ( )
100+ }
101+
102+ /**
103+ * Holds if there is a code injection flow from `source` to `sink` with medium severity.
104+ */
105+ predicate mediumSeverityCodeInjection (
106+ CodeInjectionFlow:: PathNode source , CodeInjectionFlow:: PathNode sink
107+ ) {
108+ CodeInjectionFlow:: flowPath ( source , sink ) and
109+ not criticalSeverityCodeInjection ( source , sink , _) and
110+ not isGithubScriptUsingToJson ( sink .getNode ( ) .asExpr ( ) )
111+ }
112+
113+ /**
114+ * Holds if `expr` is the `script` input to `actions/github-script` and it uses
115+ * `toJson`.
116+ */
117+ predicate isGithubScriptUsingToJson ( Expression expr ) {
118+ exists ( UsesStep script |
119+ script .getCallee ( ) = "actions/github-script" and
120+ script .getArgumentExpr ( "script" ) = expr and
121+ exists ( getAToJsonReferenceExpression ( expr .getExpression ( ) , _) )
122+ )
123+ }
0 commit comments