@@ -64,6 +64,88 @@ class GitHubEventCtxSource extends RemoteFlowSource {
6464 override string getSourceType ( ) { result = flag }
6565}
6666
67+ abstract class CommandSource extends RemoteFlowSource {
68+ abstract string getCommand ( ) ;
69+
70+ abstract Run getEnclosingRun ( ) ;
71+ }
72+
73+ class GitCommandSource extends RemoteFlowSource , CommandSource {
74+ Run run ;
75+ string cmd ;
76+ string flag ;
77+
78+ GitCommandSource ( ) {
79+ exists ( Step checkout , string cmd_regex |
80+ // This shoould be:
81+ // source instanceof PRHeadCheckoutStep
82+ // but PRHeadCheckoutStep uses Taint Tracking anc causes a non-Monolitic Recursion error
83+ // so we list all the subclasses of PRHeadCheckoutStep here and use actions/checkout as a workaround
84+ // instead of using ActionsMutableRefCheckout and ActionsSHACheckout
85+ (
86+ exists ( Uses uses |
87+ checkout = uses and
88+ uses .getCallee ( ) = "actions/checkout" and
89+ exists ( uses .getArgument ( "ref" ) )
90+ )
91+ or
92+ checkout instanceof GitMutableRefCheckout
93+ or
94+ checkout instanceof GitSHACheckout
95+ or
96+ checkout instanceof GhMutableRefCheckout
97+ or
98+ checkout instanceof GhSHACheckout
99+ ) and
100+ this .asExpr ( ) = run .getScriptScalar ( ) and
101+ checkout .getAFollowingStep ( ) = run and
102+ run .getACommand ( ) = cmd and
103+ cmd .indexOf ( "git" ) = 0 and
104+ untrustedGitCommandsDataModel ( cmd_regex , flag ) and
105+ cmd .regexpMatch ( cmd_regex )
106+ )
107+ }
108+
109+ override string getSourceType ( ) { result = flag }
110+
111+ override string getCommand ( ) { result = cmd }
112+
113+ override Run getEnclosingRun ( ) { result = run }
114+ }
115+
116+ class GitHubEventPathSource extends RemoteFlowSource , CommandSource {
117+ string cmd ;
118+ string flag ;
119+ string access_path ;
120+ Run run ;
121+
122+ // Examples
123+ // COMMENT_AUTHOR=$(jq -r .comment.user.login "$GITHUB_EVENT_PATH")
124+ // CURRENT_COMMENT=$(jq -r .comment.body "$GITHUB_EVENT_PATH")
125+ // PR_HEAD=$(jq --raw-output .pull_request.head.ref ${GITHUB_EVENT_PATH})
126+ // PR_NUMBER=$(jq --raw-output .pull_request.number ${GITHUB_EVENT_PATH})
127+ // PR_TITLE=$(jq --raw-output .pull_request.title ${GITHUB_EVENT_PATH})
128+ // BODY=$(jq -r '.issue.body' "$GITHUB_EVENT_PATH" | sed -n '3p')
129+ GitHubEventPathSource ( ) {
130+ this .asExpr ( ) = run .getScriptScalar ( ) and
131+ run .getACommand ( ) = cmd and
132+ cmd .matches ( "jq%" ) and
133+ cmd .matches ( "%GITHUB_EVENT_PATH%" ) and
134+ exists ( string regexp |
135+ untrustedEventPropertiesDataModel ( regexp , flag ) and
136+ not flag = "json" and
137+ access_path = "github.event" + cmd .regexpCapture ( ".*\\s+([^\\s]+)\\s+.*" , 1 ) and
138+ normalizeExpr ( access_path ) .regexpMatch ( "(?i)\\s*" + wrapRegexp ( regexp ) + ".*" )
139+ )
140+ }
141+
142+ override string getSourceType ( ) { result = flag }
143+
144+ override string getCommand ( ) { result = cmd }
145+
146+ override Run getEnclosingRun ( ) { result = run }
147+ }
148+
67149class GitHubEventJsonSource extends RemoteFlowSource {
68150 string flag ;
69151
@@ -104,10 +186,12 @@ class MaDSource extends RemoteFlowSource {
104186 override string getSourceType ( ) { result = sourceType }
105187}
106188
189+ abstract class FileSource extends RemoteFlowSource { }
190+
107191/**
108192 * A downloaded artifact.
109193 */
110- class ArtifactSource extends RemoteFlowSource {
194+ class ArtifactSource extends RemoteFlowSource , FileSource {
111195 ArtifactSource ( ) { this .asExpr ( ) instanceof UntrustedArtifactDownloadStep }
112196
113197 override string getSourceType ( ) { result = "artifact" }
@@ -116,8 +200,27 @@ class ArtifactSource extends RemoteFlowSource {
116200/**
117201 * A file from an untrusted checkout.
118202 */
119- private class CheckoutSource extends RemoteFlowSource {
120- CheckoutSource ( ) { this .asExpr ( ) instanceof PRHeadCheckoutStep }
203+ private class CheckoutSource extends RemoteFlowSource , FileSource {
204+ CheckoutSource ( ) {
205+ // This shoould be:
206+ // source instanceof PRHeadCheckoutStep
207+ // but PRHeadCheckoutStep uses Taint Tracking anc causes a non-Monolitic Recursion error
208+ // so we list all the subclasses of PRHeadCheckoutStep here and use actions/checkout as a workaround
209+ // instead of using ActionsMutableRefCheckout and ActionsSHACheckout
210+ exists ( Uses u |
211+ this .asExpr ( ) = u and
212+ u .getCallee ( ) = "actions/checkout" and
213+ exists ( u .getArgument ( "ref" ) )
214+ )
215+ or
216+ this .asExpr ( ) instanceof GitMutableRefCheckout
217+ or
218+ this .asExpr ( ) instanceof GitSHACheckout
219+ or
220+ this .asExpr ( ) instanceof GhMutableRefCheckout
221+ or
222+ this .asExpr ( ) instanceof GhSHACheckout
223+ }
121224
122225 override string getSourceType ( ) { result = "artifact" }
123226}
0 commit comments