Skip to content

Commit 5006b81

Browse files
author
Alvaro Muñoz
authored
Merge pull request #65 from github/query/vulnerable_versions
feat(queries): Improve Use Of Vulnerable Actions query
2 parents a05dd49 + 6cfec0d commit 5006b81

File tree

12 files changed

+738
-149
lines changed

12 files changed

+738
-149
lines changed

ql/lib/codeql/actions/ast/internal/Ast.qll

+7-7
Original file line numberDiff line numberDiff line change
@@ -1146,7 +1146,9 @@ abstract class UsesImpl extends AstNodeImpl {
11461146

11471147
abstract string getVersion();
11481148

1149-
int getMajorVersion() { result = this.getVersion().regexpReplaceAll("\\..*", "").toInt() }
1149+
int getMajorVersion() {
1150+
result = this.getVersion().regexpReplaceAll("^v", "").regexpReplaceAll("\\..*", "").toInt()
1151+
}
11501152

11511153
/** Gets the argument expression for the given key. */
11521154
string getArgument(string key) {
@@ -1192,10 +1194,8 @@ class UsesStepImpl extends StepImpl, UsesImpl {
11921194
else result = u.getValue()
11931195
}
11941196

1195-
/** Gets the version reference used when checking out the Action, e.g. `2` in `actions/checkout@v2`. */
1196-
override string getVersion() {
1197-
result = u.getValue().regexpCapture(usesParser(), 3).regexpReplaceAll("^v", "")
1198-
}
1197+
/** Gets the version reference used when checking out the Action, e.g. `v2` in `actions/checkout@v2`. */
1198+
override string getVersion() { result = u.getValue().regexpCapture(usesParser(), 3) }
11991199

12001200
override string toString() {
12011201
if exists(this.getId()) then result = "Uses Step: " + this.getId() else result = "Uses Step"
@@ -1227,12 +1227,12 @@ class ExternalJobImpl extends JobImpl, UsesImpl {
12271227
u.getValue().regexpCapture(repoUsesParser(), 3)
12281228
}
12291229

1230-
/** Gets the version reference used when checking out the Action, e.g. `2` in `actions/checkout@v2`. */
1230+
/** Gets the version reference used when checking out the Action, e.g. `v2` in `actions/checkout@v2`. */
12311231
override string getVersion() {
12321232
exists(YamlString name |
12331233
n.lookup("uses") = name and
12341234
if not name.getValue().matches("\\.%")
1235-
then result = name.getValue().regexpCapture(repoUsesParser(), 4).regexpReplaceAll("^v", "")
1235+
then result = name.getValue().regexpCapture(repoUsesParser(), 4)
12361236
else none()
12371237
)
12381238
}

ql/lib/codeql/actions/config/Config.qll

+14
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,17 @@ predicate poisonableActionsDataModel(string action) {
114114
predicate untrustedEventPropertiesDataModel(string property, string kind) {
115115
Extensions::untrustedEventPropertiesDataModel(property, kind)
116116
}
117+
118+
/**
119+
* MaD models for vulnerable actions
120+
* Fields:
121+
* - action: action name
122+
* - vulnerable_version: vulnerable version
123+
* - vulnerable_sha: vulnerable sha
124+
* - fixed_version: fixed version
125+
*/
126+
predicate vulnerableActionsDataModel(
127+
string action, string vulnerable_version, string vulnerable_sha, string fixed_version
128+
) {
129+
Extensions::vulnerableActionsDataModel(action, vulnerable_version, vulnerable_sha, fixed_version)
130+
}

ql/lib/codeql/actions/config/ConfigExtensions.qll

+7
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,10 @@ extensible predicate untrustedEventPropertiesDataModel(string property, string k
5050
extensible predicate argumentInjectionSinksDataModel(
5151
string regexp, int command_group, int argument_group
5252
);
53+
54+
/**
55+
* Holds for actions that are known to be vulnerable.
56+
*/
57+
extensible predicate vulnerableActionsDataModel(
58+
string action, string vulnerable_version, string vulnerable_sha, string fixed_version
59+
);

ql/lib/codeql/actions/dataflow/FlowSources.qll

+12-66
Original file line numberDiff line numberDiff line change
@@ -142,58 +142,14 @@ class DornyPathsFilterSource extends RemoteFlowSource {
142142
*/
143143
class TJActionsChangedFilesSource extends RemoteFlowSource {
144144
TJActionsChangedFilesSource() {
145-
exists(UsesStep u |
145+
exists(UsesStep u, string vulnerable_action, string vulnerable_version, string vulnerable_sha |
146+
vulnerableActionsDataModel(vulnerable_action, vulnerable_version, vulnerable_sha, _) and
146147
u.getCallee() = "tj-actions/changed-files" and
148+
u.getCallee() = vulnerable_action and
147149
(
148-
u.getArgument("safe_output") = "false" or
149-
u.getMajorVersion() < 41 or
150-
u.getVersion()
151-
.matches([
152-
"56284d8", "9454999", "1c93849", "da093c1", "25ef392", "18c8a4e", "4052680",
153-
"bfc49f4", "af292f1", "56284d8", "fea790c", "95690f9", "408093d", "db153ba",
154-
"8238a41", "4196030", "a21a533", "8e79ba7", "76c4d81", "6ee9cdc", "246636f",
155-
"48566bb", "fea790c", "1aee362", "2f7246c", "0fc9663", "c860b5c", "2f8b802",
156-
"b7f1b73", "1c26215", "17f3fec", "1aee362", "a0585ff", "87697c0", "85c8b82",
157-
"a96679d", "920e7b9", "de0eba3", "3928317", "68b429d", "2a968ff", "1f20fb8",
158-
"87e23c4", "54849de", "bb33761", "ec1e14c", "2106eb4", "e5efec4", "5817a9e",
159-
"a0585ff", "54479c3", "e1754a4", "9bf0914", "c912451", "174a2a6", "fb20f4d",
160-
"07e0177", "b137868", "1aae160", "5d2fcdb", "9ecc6e7", "8c9ee56", "5978e5a",
161-
"17c3e9e", "3f7b5c9", "cf4fe87", "043929e", "4e2535f", "652648a", "9ad1a5b",
162-
"c798a4e", "25eaddf", "abef388", "1c2673b", "53c377a", "54479c3", "039afcd",
163-
"b2d17f5", "4a0aac0", "ce810b2", "7ecfc67", "b109d83", "79adacd", "6e426e6",
164-
"5e2d64b", "e9b5807", "db5dd7c", "07f86bc", "3a3ec49", "ee13744", "cda2902",
165-
"9328bab", "4e680e1", "bd376fb", "84ed30e", "74b06ca", "5ce975c", "04124ef",
166-
"3ee6abf", "23e3c43", "5a331a4", "7433886", "d5414fd", "7f2aa19", "210cc83",
167-
"db3ea27", "57d9664", "0953088", "0562b9f", "487675b", "9a6dabf", "7839ede",
168-
"c2296c1", "ea251d4", "1d1287f", "392359f", "7f33882", "1d8a2f9", "0626c3f",
169-
"a2b1e5d", "110b9ba", "039afcd", "ce4b8e3", "3b6c057", "4f64429", "3f1e44a",
170-
"74dc2e8", "8356a01", "baaf598", "8a4cc4f", "8a7336f", "3996bc3", "ef0a290",
171-
"3ebdc42", "94e6fba", "3dbb79f", "991e8b3", "72d3bb8", "72d3bb8", "5f89dc7",
172-
"734bb16", "d2e030b", "6ba3c59", "d0e4477", "b91acef", "1263363", "7184077",
173-
"cbfb0fd", "932dad3", "9f28968", "c4d29bf", "ce4b8e3", "aa52cfc", "aa52cfc",
174-
"1d6e210", "8953e85", "8de562e", "7c640bd", "2706452", "1d6e210", "dd7c814",
175-
"528984a", "75af1a4", "5184a75", "dd7c814", "402f382", "402f382", "f7a5640",
176-
"df4daca", "602081b", "6e12407", "c5c9b6f", "c41b715", "60f4aab", "82edb42",
177-
"18edda7", "bec82eb", "f7a5640", "28ac672", "602cf94", "5e56dca", "58ae566",
178-
"7394701", "36e65a1", "bf6ddb7", "6c44eb8", "b2ee165", "34a865a", "fb1fe28",
179-
"ae90a0b", "bc1dc8f", "3de1f9a", "0edfedf", "2054502", "944a8b8", "581eef0",
180-
"e55f7fb", "07b38ce", "d262520", "a6d456f", "a59f800", "a2f1692", "72aab29",
181-
"e35d0af", "081ee9c", "1f30bd2", "227e314", "ffd30e8", "f5a8de7", "0bc7d40",
182-
"a53d74f", "9335416", "4daffba", "4b1f26a", "09441d3", "e44053b", "c0dba81",
183-
"fd2e991", "2a8a501", "a8ea720", "88edda5", "be68c10", "b59431b", "68bd279",
184-
"2c85495", "f276697", "00f80ef", "f56e736", "019a09d", "3b638a9", "b42f932",
185-
"8dfe0ee", "aae164d", "09a8797", "b54a7ae", "902e607", "2b51570", "040111b",
186-
"3b638a9", "1d34e69", "b86b537", "2a771ad", "75933dc", "2c0d12b", "7abdbc9",
187-
"675ab58", "8c6f276", "d825b1f", "0bd70b7", "0fe67a1", "7bfa539", "d679de9",
188-
"1e10ed4", "0754fda", "d290bdd", "15b1769", "2ecd06d", "5fe8e4d", "7c66aa2",
189-
"2ecd06d", "e95bba8", "7852058", "81f32e2", "450eadf", "0e956bb", "300e935",
190-
"fcb2ab8", "271bbd6", "e8ace01", "473984b", "032f37f", "3a35bdf", "c2216f6",
191-
"0f16c26", "271468e", "fb063fc", "a05436f", "c061ef1", "489e2d5", "8d5a33c",
192-
"fbfaba5", "1980f55", "a86b560", "f917cc3", "e18ccae", "e1d275d", "00f80ef",
193-
"9c1a181", "5eaa2d8", "188487d", "3098891", "467d26c", "d9eb683", "09a8797",
194-
"8e7cc77", "81ad4b8", "5e2a2f1", "1af9ab3", "55a857d", "62a9200", "b915d09",
195-
"f0751de", "eef9423"
196-
] + "%")
150+
u.getArgument("safe_output") = "false"
151+
or
152+
(u.getVersion() = vulnerable_version or u.getVersion() = vulnerable_sha)
197153
) and
198154
this.asExpr() = u
199155
)
@@ -207,24 +163,14 @@ class TJActionsChangedFilesSource extends RemoteFlowSource {
207163
*/
208164
class TJActionsVerifyChangedFilesSource extends RemoteFlowSource {
209165
TJActionsVerifyChangedFilesSource() {
210-
exists(UsesStep u |
166+
exists(UsesStep u, string vulnerable_action, string vulnerable_version, string vulnerable_sha |
167+
vulnerableActionsDataModel(vulnerable_action, vulnerable_version, vulnerable_sha, _) and
211168
u.getCallee() = "tj-actions/verify-changed-files" and
169+
u.getCallee() = vulnerable_action and
212170
(
213-
u.getArgument("safe_output") = "false" or
214-
u.getMajorVersion() < 17 or
215-
u.getVersion()
216-
.matches([
217-
"54e20d3", "a9b6fd3", "30aa174", "7f1b21c", "54e20d3", "0409e18", "7da22d0",
218-
"7016858", "0409e18", "7517b83", "bad2f5d", "3b573ac", "7517b83", "f557547",
219-
"9ed3155", "f557547", "a3391b5", "a3391b5", "1d7ee97", "c432297", "6e986df",
220-
"fa6ea30", "6f40ee1", "1b13d25", "c09bcad", "fda469d", "bd1e271", "367ba21",
221-
"9dea97e", "c154cc6", "527ff75", "e8756d5", "bcb4e76", "25267f5", "ea24bfd",
222-
"f2a40ba", "197e121", "a8f1b11", "95c26dd", "97ba4cc", "68310bb", "720ba6a",
223-
"cedd709", "d68d3d2", "2e1153b", "c3dd635", "81bd1de", "31a9c74", "e981d37",
224-
"e7f801c", "e86d0b9", "ad255a4", "3a8aed1", "de910b5", "d31b2a1", "e61c6fc",
225-
"380890d", "873cfd6", "b0c60c8", "7183183", "6555389", "9828a95", "8150cee",
226-
"48ddf88"
227-
] + "%")
171+
u.getArgument("safe_output") = "false"
172+
or
173+
(u.getVersion() = vulnerable_version or u.getVersion() = vulnerable_sha)
228174
) and
229175
this.asExpr() = u
230176
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import actions
2+
import codeql.actions.config.Config
3+
4+
class KnownVulnerableAction extends UsesStep {
5+
string vulnerable_action;
6+
string fixed_version;
7+
string vulnerable_version;
8+
string vulnerable_sha;
9+
10+
KnownVulnerableAction() {
11+
vulnerableActionsDataModel(vulnerable_action, vulnerable_version, vulnerable_sha, fixed_version) and
12+
this.getCallee() = vulnerable_action and
13+
(this.getVersion() = vulnerable_version or this.getVersion() = vulnerable_sha)
14+
}
15+
16+
string getFixedVersion() { result = fixed_version }
17+
18+
string getVulnerableAction() { result = vulnerable_action }
19+
20+
string getVulnerableVersion() { result = vulnerable_version }
21+
22+
string getVulnerableSha() { result = vulnerable_sha }
23+
}

0 commit comments

Comments
 (0)