From 397eb2a762ae15ff89237c7b8db0f8443ef9fdb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvaro=20Mu=C3=B1oz?= Date: Mon, 5 Aug 2024 23:44:20 +0200 Subject: [PATCH 1/7] Add getPath() to PRHeadCheckout and CacheWriting classes Add getPath() methods to get the path where a checkout step writes the code and where a Cache write reads the files from. --- .../actions/security/CachePoisoningQuery.qll | 34 ++++++++++++++++++- .../security/UntrustedCheckoutQuery.qll | 30 +++++++++++++++- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/ql/lib/codeql/actions/security/CachePoisoningQuery.qll b/ql/lib/codeql/actions/security/CachePoisoningQuery.qll index 29c0ed4feed..8c1a9ee0fd7 100644 --- a/ql/lib/codeql/actions/security/CachePoisoningQuery.qll +++ b/ql/lib/codeql/actions/security/CachePoisoningQuery.qll @@ -44,14 +44,28 @@ predicate runsOnDefaultBranch(Event e) { ) } -abstract class CacheWritingStep extends Step { } +abstract class CacheWritingStep extends Step { + abstract string getPath(); +} class CacheActionUsesStep extends CacheWritingStep, UsesStep { CacheActionUsesStep() { this.getCallee() = "actions/cache" } + + override string getPath() { + if exists(this.(UsesStep).getArgument("path")) + then result = this.(UsesStep).getArgument("path").splitAt("\n") + else result = "?" + } } class CacheActionSaveUsesStep extends CacheWritingStep, UsesStep { CacheActionSaveUsesStep() { this.getCallee() = "actions/cache/save" } + + override string getPath() { + if exists(this.(UsesStep).getArgument("path")) + then result = this.(UsesStep).getArgument("path").splitAt("\n") + else result = "?" + } } class SetupJavaUsesStep extends CacheWritingStep, UsesStep { @@ -62,6 +76,9 @@ class SetupJavaUsesStep extends CacheWritingStep, UsesStep { exists(this.getArgument("cache-dependency-path")) ) } + + // TODO: Try to get the actual path being cached + override string getPath() { result = "?" } } class SetupGoUsesStep extends CacheWritingStep, UsesStep { @@ -73,6 +90,9 @@ class SetupGoUsesStep extends CacheWritingStep, UsesStep { this.getArgument("cache") = "true" ) } + + // TODO: Try to get the actual path being cached + override string getPath() { result = "?" } } class SetupNodeUsesStep extends CacheWritingStep, UsesStep { @@ -83,6 +103,9 @@ class SetupNodeUsesStep extends CacheWritingStep, UsesStep { exists(this.getArgument("cache-dependency-path")) ) } + + // TODO: Try to get the actual path being cached + override string getPath() { result = "?" } } class SetupPythonUsesStep extends CacheWritingStep, UsesStep { @@ -93,6 +116,9 @@ class SetupPythonUsesStep extends CacheWritingStep, UsesStep { exists(this.getArgument("cache-dependency-path")) ) } + + // TODO: Try to get the actual path being cached + override string getPath() { result = "?" } } class SetupDotnetUsesStep extends CacheWritingStep, UsesStep { @@ -103,6 +129,9 @@ class SetupDotnetUsesStep extends CacheWritingStep, UsesStep { exists(this.getArgument("cache-dependency-path")) ) } + + // TODO: Try to get the actual path being cached + override string getPath() { result = "?" } } class SetupRubyUsesStep extends CacheWritingStep, UsesStep { @@ -110,4 +139,7 @@ class SetupRubyUsesStep extends CacheWritingStep, UsesStep { this.getCallee() = ["actions/setup-ruby", "ruby/setup-ruby"] and this.getArgument("bundler-cache") = "true" } + + // TODO: Try to get the actual path being cached + override string getPath() { result = "?" } } diff --git a/ql/lib/codeql/actions/security/UntrustedCheckoutQuery.qll b/ql/lib/codeql/actions/security/UntrustedCheckoutQuery.qll index fba33bb8bc8..7cfda4da49c 100644 --- a/ql/lib/codeql/actions/security/UntrustedCheckoutQuery.qll +++ b/ql/lib/codeql/actions/security/UntrustedCheckoutQuery.qll @@ -1,6 +1,12 @@ import actions import codeql.actions.DataFlow +string getStepCWD() { + // TODO: This should be the path of the git command. + // Read if from the step's CWD, workspace or look for a cd command. + result = "?" +} + bindingset[s] predicate containsPullRequestNumber(string s) { exists( @@ -68,7 +74,9 @@ predicate containsHeadRef(string s) { } /** Checkout of a Pull Request HEAD */ -abstract class PRHeadCheckoutStep extends Step { } +abstract class PRHeadCheckoutStep extends Step { + abstract string getPath(); +} /** Checkout of a Pull Request HEAD ref */ abstract class MutableRefCheckoutStep extends PRHeadCheckoutStep { } @@ -138,6 +146,12 @@ class ActionsMutableRefCheckout extends MutableRefCheckoutStep instanceof UsesSt ) ) } + + override string getPath() { + if exists(this.(UsesStep).getArgument("path")) + then result = this.(UsesStep).getArgument("path") + else result = "?" + } } /** Checkout of a Pull Request HEAD ref using actions/checkout action */ @@ -194,6 +208,12 @@ class ActionsSHACheckout extends SHACheckoutStep instanceof UsesStep { ) ) } + + override string getPath() { + if exists(this.(UsesStep).getArgument("path")) + then result = this.(UsesStep).getArgument("path") + else result = "?" + } } /** Checkout of a Pull Request HEAD ref using git within a Run step */ @@ -216,6 +236,8 @@ class GitMutableRefCheckout extends MutableRefCheckoutStep instanceof Run { ) ) } + + override string getPath() { result = getStepCWD() } } /** Checkout of a Pull Request HEAD ref using git within a Run step */ @@ -235,6 +257,8 @@ class GitSHACheckout extends SHACheckoutStep instanceof Run { ) ) } + + override string getPath() { result = getStepCWD() } } /** Checkout of a Pull Request HEAD ref using gh within a Run step */ @@ -256,6 +280,8 @@ class GhMutableRefCheckout extends MutableRefCheckoutStep instanceof Run { ) ) } + + override string getPath() { result = getStepCWD() } } /** Checkout of a Pull Request HEAD ref using gh within a Run step */ @@ -274,4 +300,6 @@ class GhSHACheckout extends SHACheckoutStep instanceof Run { ) ) } + + override string getPath() { result = getStepCWD() } } From c5314aeb6c1e7497733f539c783ce5d7ec083bc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvaro=20Mu=C3=B1oz?= Date: Mon, 5 Aug 2024 23:44:27 +0200 Subject: [PATCH 2/7] Add new tests --- .../CWE-349/.github/workflows/test22.yml | 35 +++++++++++++++++++ .../CWE-349/.github/workflows/test23.yml | 35 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 ql/test/query-tests/Security/CWE-349/.github/workflows/test22.yml create mode 100644 ql/test/query-tests/Security/CWE-349/.github/workflows/test23.yml diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test22.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/test22.yml new file mode 100644 index 00000000000..f8e1dabf565 --- /dev/null +++ b/ql/test/query-tests/Security/CWE-349/.github/workflows/test22.yml @@ -0,0 +1,35 @@ +name: Test + +on: + issue_comment: + +permissions: + actions: write + +jobs: + generate-results: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + - name: Cache pip dependencies + uses: actions/cache@v4 + id: cache-pip + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml') }} + restore-keys: ${{ runner.os }}-pip- + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: results + path: results/ + - name: Upload results + uses: actions/upload-artifact@v4 + with: + name: results + path: results/ + if-no-files-found: ignore diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test23.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/test23.yml new file mode 100644 index 00000000000..3f35068eb7d --- /dev/null +++ b/ql/test/query-tests/Security/CWE-349/.github/workflows/test23.yml @@ -0,0 +1,35 @@ +name: Test + +on: + issue_comment: + +permissions: + actions: write + +jobs: + generate-results: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + - name: Cache pip dependencies + uses: actions/cache@v4 + id: cache-pip + with: + path: ./results/pip + key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml') }} + restore-keys: ${{ runner.os }}-pip- + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: results + path: results/ + - name: Upload results + uses: actions/upload-artifact@v4 + with: + name: results + path: results/ + if-no-files-found: ignore From 34b48d559b17536e9274f0bcf9e462ab5a8aeb57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvaro=20Mu=C3=B1oz?= Date: Mon, 5 Aug 2024 23:45:51 +0200 Subject: [PATCH 3/7] Add expected tests results --- .../Security/CWE-349/CachePoisoning.expected | 52 +++++++++++-------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/ql/test/query-tests/Security/CWE-349/CachePoisoning.expected b/ql/test/query-tests/Security/CWE-349/CachePoisoning.expected index 994beb3b74f..2ad477a2a8b 100644 --- a/ql/test/query-tests/Security/CWE-349/CachePoisoning.expected +++ b/ql/test/query-tests/Security/CWE-349/CachePoisoning.expected @@ -64,26 +64,34 @@ edges | .github/workflows/test20.yml:41:7:42:4 | Run Step | .github/workflows/test20.yml:42:7:43:4 | Run Step | | .github/workflows/test20.yml:42:7:43:4 | Run Step | .github/workflows/test20.yml:43:7:46:39 | Uses Step | | .github/workflows/test21.yml:20:9:26:6 | Uses Step | .github/workflows/test21.yml:26:9:29:2 | Run Step | +| .github/workflows/test22.yml:13:9:14:6 | Uses Step | .github/workflows/test22.yml:14:9:18:6 | Uses Step | +| .github/workflows/test22.yml:14:9:18:6 | Uses Step | .github/workflows/test22.yml:18:9:25:6 | Uses Step: cache-pip | +| .github/workflows/test22.yml:18:9:25:6 | Uses Step: cache-pip | .github/workflows/test22.yml:25:9:30:6 | Uses Step | +| .github/workflows/test22.yml:25:9:30:6 | Uses Step | .github/workflows/test22.yml:30:9:35:36 | Uses Step | +| .github/workflows/test23.yml:13:9:14:6 | Uses Step | .github/workflows/test23.yml:14:9:18:6 | Uses Step | +| .github/workflows/test23.yml:14:9:18:6 | Uses Step | .github/workflows/test23.yml:18:9:25:6 | Uses Step: cache-pip | +| .github/workflows/test23.yml:18:9:25:6 | Uses Step: cache-pip | .github/workflows/test23.yml:25:9:30:6 | Uses Step | +| .github/workflows/test23.yml:25:9:30:6 | Uses Step | .github/workflows/test23.yml:30:9:35:36 | Uses Step | #select -| .github/workflows/poc3.yml:33:7:38:4 | Uses Step | .github/workflows/poc3.yml:18:7:25:4 | Uses Step | .github/workflows/poc3.yml:33:7:38:4 | Uses Step | Potential cache poisoning in the context of the default branch | -| .github/workflows/poc3.yml:38:7:40:4 | Run Step | .github/workflows/poc3.yml:18:7:25:4 | Uses Step | .github/workflows/poc3.yml:38:7:40:4 | Run Step | Potential cache poisoning in the context of the default branch | -| .github/workflows/poc3.yml:41:7:42:4 | Run Step | .github/workflows/poc3.yml:18:7:25:4 | Uses Step | .github/workflows/poc3.yml:41:7:42:4 | Run Step | Potential cache poisoning in the context of the default branch | -| .github/workflows/poc3.yml:42:7:43:4 | Run Step | .github/workflows/poc3.yml:18:7:25:4 | Uses Step | .github/workflows/poc3.yml:42:7:43:4 | Run Step | Potential cache poisoning in the context of the default branch | -| .github/workflows/poc.yml:38:9:43:6 | Uses Step | .github/workflows/poc.yml:30:9:36:6 | Uses Step | .github/workflows/poc.yml:38:9:43:6 | Uses Step | Potential cache poisoning in the context of the default branch | -| .github/workflows/test1.yml:18:9:22:6 | Uses Step | .github/workflows/test1.yml:13:9:18:6 | Uses Step | .github/workflows/test1.yml:18:9:22:6 | Uses Step | Potential cache poisoning in the context of the default branch | -| .github/workflows/test2.yml:14:9:18:6 | Uses Step | .github/workflows/test2.yml:11:9:14:6 | Uses Step | .github/workflows/test2.yml:14:9:18:6 | Uses Step | Potential cache poisoning in the context of the default branch | -| .github/workflows/test3.yml:14:9:22:6 | Uses Step | .github/workflows/test3.yml:11:9:14:6 | Uses Step | .github/workflows/test3.yml:14:9:22:6 | Uses Step | Potential cache poisoning in the context of the default branch | -| .github/workflows/test6.yml:13:9:17:6 | Uses Step | .github/workflows/test6.yml:10:9:13:6 | Uses Step | .github/workflows/test6.yml:13:9:17:6 | Uses Step | Potential cache poisoning in the context of the default branch | -| .github/workflows/test7.yml:13:9:16:6 | Uses Step | .github/workflows/test7.yml:10:9:13:6 | Uses Step | .github/workflows/test7.yml:13:9:16:6 | Uses Step | Potential cache poisoning in the context of the default branch | -| .github/workflows/test8.yml:15:9:17:2 | Run Step | .github/workflows/test8.yml:12:9:15:6 | Uses Step | .github/workflows/test8.yml:15:9:17:2 | Run Step | Potential cache poisoning in the context of the default branch | -| .github/workflows/test8.yml:26:9:28:2 | Uses Step | .github/workflows/test8.yml:23:9:26:6 | Uses Step | .github/workflows/test8.yml:26:9:28:2 | Uses Step | Potential cache poisoning in the context of the default branch | -| .github/workflows/test8.yml:37:9:37:75 | Run Step | .github/workflows/test8.yml:34:9:37:6 | Uses Step | .github/workflows/test8.yml:37:9:37:75 | Run Step | Potential cache poisoning in the context of the default branch | -| .github/workflows/test11.yml:19:9:23:6 | Uses Step | .github/workflows/test11.yml:14:9:19:6 | Uses Step | .github/workflows/test11.yml:19:9:23:6 | Uses Step | Potential cache poisoning in the context of the default branch | -| .github/workflows/test15.yml:17:9:21:6 | Uses Step | .github/workflows/test15.yml:14:9:17:6 | Uses Step | .github/workflows/test15.yml:17:9:21:6 | Uses Step | Potential cache poisoning in the context of the default branch | -| .github/workflows/test16.yml:17:9:21:6 | Uses Step | .github/workflows/test16.yml:14:9:17:6 | Uses Step | .github/workflows/test16.yml:17:9:21:6 | Uses Step | Potential cache poisoning in the context of the default branch | -| .github/workflows/test17.yml:22:9:26:31 | Uses Step | .github/workflows/test17.yml:15:9:20:6 | Uses Step | .github/workflows/test17.yml:22:9:26:31 | Uses Step | Potential cache poisoning in the context of the default branch | -| .github/workflows/test20.yml:33:7:38:4 | Uses Step | .github/workflows/test20.yml:18:7:25:4 | Uses Step | .github/workflows/test20.yml:33:7:38:4 | Uses Step | Potential cache poisoning in the context of the default branch | -| .github/workflows/test20.yml:38:7:40:4 | Run Step | .github/workflows/test20.yml:18:7:25:4 | Uses Step | .github/workflows/test20.yml:38:7:40:4 | Run Step | Potential cache poisoning in the context of the default branch | -| .github/workflows/test20.yml:41:7:42:4 | Run Step | .github/workflows/test20.yml:18:7:25:4 | Uses Step | .github/workflows/test20.yml:41:7:42:4 | Run Step | Potential cache poisoning in the context of the default branch | -| .github/workflows/test20.yml:42:7:43:4 | Run Step | .github/workflows/test20.yml:18:7:25:4 | Uses Step | .github/workflows/test20.yml:42:7:43:4 | Run Step | Potential cache poisoning in the context of the default branch | -| .github/workflows/test21.yml:26:9:29:2 | Run Step | .github/workflows/test21.yml:20:9:26:6 | Uses Step | .github/workflows/test21.yml:26:9:29:2 | Run Step | Potential cache poisoning in the context of the default branch | +| .github/workflows/poc3.yml:33:7:38:4 | Uses Step | .github/workflows/poc3.yml:18:7:25:4 | Uses Step | .github/workflows/poc3.yml:33:7:38:4 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | +| .github/workflows/poc3.yml:38:7:40:4 | Run Step | .github/workflows/poc3.yml:18:7:25:4 | Uses Step | .github/workflows/poc3.yml:38:7:40:4 | Run Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | +| .github/workflows/poc3.yml:41:7:42:4 | Run Step | .github/workflows/poc3.yml:18:7:25:4 | Uses Step | .github/workflows/poc3.yml:41:7:42:4 | Run Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | +| .github/workflows/poc3.yml:42:7:43:4 | Run Step | .github/workflows/poc3.yml:18:7:25:4 | Uses Step | .github/workflows/poc3.yml:42:7:43:4 | Run Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | +| .github/workflows/poc.yml:38:9:43:6 | Uses Step | .github/workflows/poc.yml:30:9:36:6 | Uses Step | .github/workflows/poc.yml:38:9:43:6 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | +| .github/workflows/test1.yml:18:9:22:6 | Uses Step | .github/workflows/test1.yml:13:9:18:6 | Uses Step | .github/workflows/test1.yml:18:9:22:6 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | +| .github/workflows/test2.yml:14:9:18:6 | Uses Step | .github/workflows/test2.yml:11:9:14:6 | Uses Step | .github/workflows/test2.yml:14:9:18:6 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | +| .github/workflows/test3.yml:14:9:22:6 | Uses Step | .github/workflows/test3.yml:11:9:14:6 | Uses Step | .github/workflows/test3.yml:14:9:22:6 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | +| .github/workflows/test6.yml:13:9:17:6 | Uses Step | .github/workflows/test6.yml:10:9:13:6 | Uses Step | .github/workflows/test6.yml:13:9:17:6 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | +| .github/workflows/test7.yml:13:9:16:6 | Uses Step | .github/workflows/test7.yml:10:9:13:6 | Uses Step | .github/workflows/test7.yml:13:9:16:6 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | +| .github/workflows/test8.yml:15:9:17:2 | Run Step | .github/workflows/test8.yml:12:9:15:6 | Uses Step | .github/workflows/test8.yml:15:9:17:2 | Run Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | +| .github/workflows/test8.yml:26:9:28:2 | Uses Step | .github/workflows/test8.yml:23:9:26:6 | Uses Step | .github/workflows/test8.yml:26:9:28:2 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | +| .github/workflows/test8.yml:37:9:37:75 | Run Step | .github/workflows/test8.yml:34:9:37:6 | Uses Step | .github/workflows/test8.yml:37:9:37:75 | Run Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | +| .github/workflows/test11.yml:19:9:23:6 | Uses Step | .github/workflows/test11.yml:14:9:19:6 | Uses Step | .github/workflows/test11.yml:19:9:23:6 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | +| .github/workflows/test15.yml:17:9:21:6 | Uses Step | .github/workflows/test15.yml:14:9:17:6 | Uses Step | .github/workflows/test15.yml:17:9:21:6 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | +| .github/workflows/test16.yml:17:9:21:6 | Uses Step | .github/workflows/test16.yml:14:9:17:6 | Uses Step | .github/workflows/test16.yml:17:9:21:6 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | +| .github/workflows/test17.yml:22:9:26:31 | Uses Step | .github/workflows/test17.yml:15:9:20:6 | Uses Step | .github/workflows/test17.yml:22:9:26:31 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | +| .github/workflows/test20.yml:33:7:38:4 | Uses Step | .github/workflows/test20.yml:18:7:25:4 | Uses Step | .github/workflows/test20.yml:33:7:38:4 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | +| .github/workflows/test20.yml:38:7:40:4 | Run Step | .github/workflows/test20.yml:18:7:25:4 | Uses Step | .github/workflows/test20.yml:38:7:40:4 | Run Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | +| .github/workflows/test20.yml:41:7:42:4 | Run Step | .github/workflows/test20.yml:18:7:25:4 | Uses Step | .github/workflows/test20.yml:41:7:42:4 | Run Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | +| .github/workflows/test20.yml:42:7:43:4 | Run Step | .github/workflows/test20.yml:18:7:25:4 | Uses Step | .github/workflows/test20.yml:42:7:43:4 | Run Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | +| .github/workflows/test21.yml:26:9:29:2 | Run Step | .github/workflows/test21.yml:20:9:26:6 | Uses Step | .github/workflows/test21.yml:26:9:29:2 | Run Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | From 2273aadb4bc0b80bc48eec448de0b6405a5e32ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvaro=20Mu=C3=B1oz?= Date: Mon, 5 Aug 2024 23:47:00 +0200 Subject: [PATCH 4/7] Improve Cache Poisoning query The untrusted files path is compared with the path written to the cache to check if the cache can really be poisoned --- ql/src/Security/CWE-349/CachePoisoning.ql | 52 ++++++++++++++++++++--- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/ql/src/Security/CWE-349/CachePoisoning.ql b/ql/src/Security/CWE-349/CachePoisoning.ql index 6609dae2b7f..3f2bb8db472 100644 --- a/ql/src/Security/CWE-349/CachePoisoning.ql +++ b/ql/src/Security/CWE-349/CachePoisoning.ql @@ -18,19 +18,47 @@ import codeql.actions.security.CachePoisoningQuery import codeql.actions.security.PoisonableSteps import codeql.actions.security.ControlChecks +/** + * Holds if the path cache_path is a subpath of the path untrusted_path. + */ +bindingset[cache_path, untrusted_path] +predicate controlledCachePath(string cache_path, string untrusted_path) { + exists(string normalized_cache_path, string normalized_untrusted_path | + ( + cache_path.regexpMatch("^[a-zA-Z0-9_-].*") and + normalized_cache_path = "./" + cache_path.regexpReplaceAll("/$", "") + or + normalized_cache_path = cache_path.regexpReplaceAll("/$", "") + ) and + ( + untrusted_path.regexpMatch("^[a-zA-Z0-9_-].*") and + normalized_untrusted_path = "./" + untrusted_path.regexpReplaceAll("/$", "") + or + normalized_untrusted_path = untrusted_path.regexpReplaceAll("/$", "") + ) and + normalized_cache_path.substring(0, normalized_untrusted_path.length()) = + normalized_untrusted_path + ) +} + query predicate edges(Step a, Step b) { a.getNextStep() = b } -from LocalJob j, Event e, Step artifact, Step s +from LocalJob j, Event e, Step source, Step s, string message, string path where ( - artifact instanceof PRHeadCheckoutStep or - artifact instanceof UntrustedArtifactDownloadStep + source instanceof PRHeadCheckoutStep and + message = "due to privilege checkout of untrusted code." and + path = source.(PRHeadCheckoutStep).getPath() + or + source instanceof UntrustedArtifactDownloadStep and + message = "due to downloading an untrusted artifact." and + path = source.(UntrustedArtifactDownloadStep).getPath() ) and j.getATriggerEvent() = e and // job can be triggered by an external user e.isExternallyTriggerable() and // the checkout is not controlled by an access check - not exists(ControlCheck check | check.protects(artifact, j.getATriggerEvent())) and + not exists(ControlCheck check | check.protects(source, j.getATriggerEvent())) and ( // the workflow runs in the context of the default branch runsOnDefaultBranch(e) @@ -43,19 +71,29 @@ where ) ) and // the job checkouts untrusted code from a pull request - j.getAStep() = artifact and + j.getAStep() = source and ( // the job writes to the cache // (No need to follow the checkout step as the cache writing is normally done after the job completes) j.getAStep() = s and s instanceof CacheWritingStep and + ( + // we dont know what code can be controlled by the attacker + path = "?" + or + // we dont know what files are being cached + s.(CacheWritingStep).getPath() = "?" + or + // the cache writing step reads from the path the attacker can control + not path = "?" and controlledCachePath(s.(CacheWritingStep).getPath(), path) + ) and not s instanceof PoisonableStep or // the job executes checked-out code // (The cache specific token can be leaked even for non-privileged workflows) - artifact.getAFollowingStep() = s and + source.getAFollowingStep() = s and s instanceof PoisonableStep and // excluding privileged workflows since they can be exploited in easier circumstances not j.isPrivileged() ) -select s, artifact, s, "Potential cache poisoning in the context of the default branch" +select s, source, s, "Potential cache poisoning in the context of the default branch" + message From 14f1672e740dae8beb881e5b895c73f443e5437c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvaro=20Mu=C3=B1oz?= Date: Mon, 5 Aug 2024 23:54:26 +0200 Subject: [PATCH 5/7] Fix query message --- ql/src/Security/CWE-349/CachePoisoning.ql | 2 +- .../Security/CWE-349/CachePoisoning.expected | 45 ++++++++++--------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/ql/src/Security/CWE-349/CachePoisoning.ql b/ql/src/Security/CWE-349/CachePoisoning.ql index 3f2bb8db472..3807cb4b592 100644 --- a/ql/src/Security/CWE-349/CachePoisoning.ql +++ b/ql/src/Security/CWE-349/CachePoisoning.ql @@ -96,4 +96,4 @@ where // excluding privileged workflows since they can be exploited in easier circumstances not j.isPrivileged() ) -select s, source, s, "Potential cache poisoning in the context of the default branch" + message +select s, source, s, "Potential cache poisoning in the context of the default branch " + message diff --git a/ql/test/query-tests/Security/CWE-349/CachePoisoning.expected b/ql/test/query-tests/Security/CWE-349/CachePoisoning.expected index 2ad477a2a8b..fdaf0cf25ad 100644 --- a/ql/test/query-tests/Security/CWE-349/CachePoisoning.expected +++ b/ql/test/query-tests/Security/CWE-349/CachePoisoning.expected @@ -73,25 +73,26 @@ edges | .github/workflows/test23.yml:18:9:25:6 | Uses Step: cache-pip | .github/workflows/test23.yml:25:9:30:6 | Uses Step | | .github/workflows/test23.yml:25:9:30:6 | Uses Step | .github/workflows/test23.yml:30:9:35:36 | Uses Step | #select -| .github/workflows/poc3.yml:33:7:38:4 | Uses Step | .github/workflows/poc3.yml:18:7:25:4 | Uses Step | .github/workflows/poc3.yml:33:7:38:4 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | -| .github/workflows/poc3.yml:38:7:40:4 | Run Step | .github/workflows/poc3.yml:18:7:25:4 | Uses Step | .github/workflows/poc3.yml:38:7:40:4 | Run Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | -| .github/workflows/poc3.yml:41:7:42:4 | Run Step | .github/workflows/poc3.yml:18:7:25:4 | Uses Step | .github/workflows/poc3.yml:41:7:42:4 | Run Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | -| .github/workflows/poc3.yml:42:7:43:4 | Run Step | .github/workflows/poc3.yml:18:7:25:4 | Uses Step | .github/workflows/poc3.yml:42:7:43:4 | Run Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | -| .github/workflows/poc.yml:38:9:43:6 | Uses Step | .github/workflows/poc.yml:30:9:36:6 | Uses Step | .github/workflows/poc.yml:38:9:43:6 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | -| .github/workflows/test1.yml:18:9:22:6 | Uses Step | .github/workflows/test1.yml:13:9:18:6 | Uses Step | .github/workflows/test1.yml:18:9:22:6 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | -| .github/workflows/test2.yml:14:9:18:6 | Uses Step | .github/workflows/test2.yml:11:9:14:6 | Uses Step | .github/workflows/test2.yml:14:9:18:6 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | -| .github/workflows/test3.yml:14:9:22:6 | Uses Step | .github/workflows/test3.yml:11:9:14:6 | Uses Step | .github/workflows/test3.yml:14:9:22:6 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | -| .github/workflows/test6.yml:13:9:17:6 | Uses Step | .github/workflows/test6.yml:10:9:13:6 | Uses Step | .github/workflows/test6.yml:13:9:17:6 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | -| .github/workflows/test7.yml:13:9:16:6 | Uses Step | .github/workflows/test7.yml:10:9:13:6 | Uses Step | .github/workflows/test7.yml:13:9:16:6 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | -| .github/workflows/test8.yml:15:9:17:2 | Run Step | .github/workflows/test8.yml:12:9:15:6 | Uses Step | .github/workflows/test8.yml:15:9:17:2 | Run Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | -| .github/workflows/test8.yml:26:9:28:2 | Uses Step | .github/workflows/test8.yml:23:9:26:6 | Uses Step | .github/workflows/test8.yml:26:9:28:2 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | -| .github/workflows/test8.yml:37:9:37:75 | Run Step | .github/workflows/test8.yml:34:9:37:6 | Uses Step | .github/workflows/test8.yml:37:9:37:75 | Run Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | -| .github/workflows/test11.yml:19:9:23:6 | Uses Step | .github/workflows/test11.yml:14:9:19:6 | Uses Step | .github/workflows/test11.yml:19:9:23:6 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | -| .github/workflows/test15.yml:17:9:21:6 | Uses Step | .github/workflows/test15.yml:14:9:17:6 | Uses Step | .github/workflows/test15.yml:17:9:21:6 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | -| .github/workflows/test16.yml:17:9:21:6 | Uses Step | .github/workflows/test16.yml:14:9:17:6 | Uses Step | .github/workflows/test16.yml:17:9:21:6 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | -| .github/workflows/test17.yml:22:9:26:31 | Uses Step | .github/workflows/test17.yml:15:9:20:6 | Uses Step | .github/workflows/test17.yml:22:9:26:31 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | -| .github/workflows/test20.yml:33:7:38:4 | Uses Step | .github/workflows/test20.yml:18:7:25:4 | Uses Step | .github/workflows/test20.yml:33:7:38:4 | Uses Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | -| .github/workflows/test20.yml:38:7:40:4 | Run Step | .github/workflows/test20.yml:18:7:25:4 | Uses Step | .github/workflows/test20.yml:38:7:40:4 | Run Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | -| .github/workflows/test20.yml:41:7:42:4 | Run Step | .github/workflows/test20.yml:18:7:25:4 | Uses Step | .github/workflows/test20.yml:41:7:42:4 | Run Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | -| .github/workflows/test20.yml:42:7:43:4 | Run Step | .github/workflows/test20.yml:18:7:25:4 | Uses Step | .github/workflows/test20.yml:42:7:43:4 | Run Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | -| .github/workflows/test21.yml:26:9:29:2 | Run Step | .github/workflows/test21.yml:20:9:26:6 | Uses Step | .github/workflows/test21.yml:26:9:29:2 | Run Step | Potential cache poisoning in the context of the default branchdue to privilege checkout of untrusted code. | +| .github/workflows/poc3.yml:33:7:38:4 | Uses Step | .github/workflows/poc3.yml:18:7:25:4 | Uses Step | .github/workflows/poc3.yml:33:7:38:4 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/poc3.yml:38:7:40:4 | Run Step | .github/workflows/poc3.yml:18:7:25:4 | Uses Step | .github/workflows/poc3.yml:38:7:40:4 | Run Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/poc3.yml:41:7:42:4 | Run Step | .github/workflows/poc3.yml:18:7:25:4 | Uses Step | .github/workflows/poc3.yml:41:7:42:4 | Run Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/poc3.yml:42:7:43:4 | Run Step | .github/workflows/poc3.yml:18:7:25:4 | Uses Step | .github/workflows/poc3.yml:42:7:43:4 | Run Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/poc.yml:38:9:43:6 | Uses Step | .github/workflows/poc.yml:30:9:36:6 | Uses Step | .github/workflows/poc.yml:38:9:43:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/test1.yml:18:9:22:6 | Uses Step | .github/workflows/test1.yml:13:9:18:6 | Uses Step | .github/workflows/test1.yml:18:9:22:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/test2.yml:14:9:18:6 | Uses Step | .github/workflows/test2.yml:11:9:14:6 | Uses Step | .github/workflows/test2.yml:14:9:18:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/test3.yml:14:9:22:6 | Uses Step | .github/workflows/test3.yml:11:9:14:6 | Uses Step | .github/workflows/test3.yml:14:9:22:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/test6.yml:13:9:17:6 | Uses Step | .github/workflows/test6.yml:10:9:13:6 | Uses Step | .github/workflows/test6.yml:13:9:17:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/test7.yml:13:9:16:6 | Uses Step | .github/workflows/test7.yml:10:9:13:6 | Uses Step | .github/workflows/test7.yml:13:9:16:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/test8.yml:15:9:17:2 | Run Step | .github/workflows/test8.yml:12:9:15:6 | Uses Step | .github/workflows/test8.yml:15:9:17:2 | Run Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/test8.yml:26:9:28:2 | Uses Step | .github/workflows/test8.yml:23:9:26:6 | Uses Step | .github/workflows/test8.yml:26:9:28:2 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/test8.yml:37:9:37:75 | Run Step | .github/workflows/test8.yml:34:9:37:6 | Uses Step | .github/workflows/test8.yml:37:9:37:75 | Run Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/test11.yml:19:9:23:6 | Uses Step | .github/workflows/test11.yml:14:9:19:6 | Uses Step | .github/workflows/test11.yml:19:9:23:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/test15.yml:17:9:21:6 | Uses Step | .github/workflows/test15.yml:14:9:17:6 | Uses Step | .github/workflows/test15.yml:17:9:21:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/test16.yml:17:9:21:6 | Uses Step | .github/workflows/test16.yml:14:9:17:6 | Uses Step | .github/workflows/test16.yml:17:9:21:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/test17.yml:22:9:26:31 | Uses Step | .github/workflows/test17.yml:15:9:20:6 | Uses Step | .github/workflows/test17.yml:22:9:26:31 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/test20.yml:33:7:38:4 | Uses Step | .github/workflows/test20.yml:18:7:25:4 | Uses Step | .github/workflows/test20.yml:33:7:38:4 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/test20.yml:38:7:40:4 | Run Step | .github/workflows/test20.yml:18:7:25:4 | Uses Step | .github/workflows/test20.yml:38:7:40:4 | Run Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/test20.yml:41:7:42:4 | Run Step | .github/workflows/test20.yml:18:7:25:4 | Uses Step | .github/workflows/test20.yml:41:7:42:4 | Run Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/test20.yml:42:7:43:4 | Run Step | .github/workflows/test20.yml:18:7:25:4 | Uses Step | .github/workflows/test20.yml:42:7:43:4 | Run Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/test21.yml:26:9:29:2 | Run Step | .github/workflows/test21.yml:20:9:26:6 | Uses Step | .github/workflows/test21.yml:26:9:29:2 | Run Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/test23.yml:18:9:25:6 | Uses Step: cache-pip | .github/workflows/test23.yml:25:9:30:6 | Uses Step | .github/workflows/test23.yml:18:9:25:6 | Uses Step: cache-pip | Potential cache poisoning in the context of the default branch due to downloading an untrusted artifact. | From fbc2e1e7e807de23e871df121b71b4a41cfc3ec1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvaro=20Mu=C3=B1oz?= Date: Tue, 6 Aug 2024 10:47:12 +0200 Subject: [PATCH 6/7] Remove caching actions that cache files outside of the CWD --- .../actions/security/CachePoisoningQuery.qll | 81 +------------------ 1 file changed, 3 insertions(+), 78 deletions(-) diff --git a/ql/lib/codeql/actions/security/CachePoisoningQuery.qll b/ql/lib/codeql/actions/security/CachePoisoningQuery.qll index 8c1a9ee0fd7..56002cb2b16 100644 --- a/ql/lib/codeql/actions/security/CachePoisoningQuery.qll +++ b/ql/lib/codeql/actions/security/CachePoisoningQuery.qll @@ -51,87 +51,13 @@ abstract class CacheWritingStep extends Step { class CacheActionUsesStep extends CacheWritingStep, UsesStep { CacheActionUsesStep() { this.getCallee() = "actions/cache" } - override string getPath() { - if exists(this.(UsesStep).getArgument("path")) - then result = this.(UsesStep).getArgument("path").splitAt("\n") - else result = "?" - } + override string getPath() { result = this.(UsesStep).getArgument("path").splitAt("\n") } } class CacheActionSaveUsesStep extends CacheWritingStep, UsesStep { CacheActionSaveUsesStep() { this.getCallee() = "actions/cache/save" } - override string getPath() { - if exists(this.(UsesStep).getArgument("path")) - then result = this.(UsesStep).getArgument("path").splitAt("\n") - else result = "?" - } -} - -class SetupJavaUsesStep extends CacheWritingStep, UsesStep { - SetupJavaUsesStep() { - this.getCallee() = "actions/setup-java" and - ( - exists(this.getArgument("cache")) or - exists(this.getArgument("cache-dependency-path")) - ) - } - - // TODO: Try to get the actual path being cached - override string getPath() { result = "?" } -} - -class SetupGoUsesStep extends CacheWritingStep, UsesStep { - SetupGoUsesStep() { - this.getCallee() = "actions/setup-go" and - ( - not exists(this.getArgument("cache")) - or - this.getArgument("cache") = "true" - ) - } - - // TODO: Try to get the actual path being cached - override string getPath() { result = "?" } -} - -class SetupNodeUsesStep extends CacheWritingStep, UsesStep { - SetupNodeUsesStep() { - this.getCallee() = "actions/setup-node" and - ( - exists(this.getArgument("cache")) or - exists(this.getArgument("cache-dependency-path")) - ) - } - - // TODO: Try to get the actual path being cached - override string getPath() { result = "?" } -} - -class SetupPythonUsesStep extends CacheWritingStep, UsesStep { - SetupPythonUsesStep() { - this.getCallee() = "actions/setup-python" and - ( - exists(this.getArgument("cache")) or - exists(this.getArgument("cache-dependency-path")) - ) - } - - // TODO: Try to get the actual path being cached - override string getPath() { result = "?" } -} - -class SetupDotnetUsesStep extends CacheWritingStep, UsesStep { - SetupDotnetUsesStep() { - this.getCallee() = "actions/setup-dotnet" and - ( - this.getArgument("cache") = "true" or - exists(this.getArgument("cache-dependency-path")) - ) - } - - // TODO: Try to get the actual path being cached - override string getPath() { result = "?" } + override string getPath() { result = this.(UsesStep).getArgument("path").splitAt("\n") } } class SetupRubyUsesStep extends CacheWritingStep, UsesStep { @@ -140,6 +66,5 @@ class SetupRubyUsesStep extends CacheWritingStep, UsesStep { this.getArgument("bundler-cache") = "true" } - // TODO: Try to get the actual path being cached - override string getPath() { result = "?" } + override string getPath() { result = "vendor/bundle" } } From d18179850d6fc9557172372376dfc81aa993c939 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvaro=20Mu=C3=B1oz?= Date: Tue, 6 Aug 2024 12:04:34 +0200 Subject: [PATCH 7/7] Split Cache Poisoning queries in 3 Split them into 3 queries depending of how the cache can be poisoned: - control of cached files - execution of controlled code - code injection Remove `setup-XXX` actions from CacheWriting class since the cached files are not in the CWD --- ...n.ql => CachePoisoningViaCodeInjection.ql} | 2 +- ...ing.ql => CachePoisoningViaDirectCache.ql} | 49 ++++------ .../CachePoisoningViaPoisonableStep.ql | 58 +++++++++++ .../{test9.yml => code_injection1.yml} | 0 .../.github/workflows/code_injection2.yml | 16 +++ .../{test1.yml => direct_cache1.yml} | 0 .../{test2.yml => direct_cache2.yml} | 0 .../{test11.yml => direct_cache3.yml} | 0 .../{test15.yml => direct_cache4.yml} | 0 .../{test16.yml => direct_cache5.yml} | 0 .../{test23.yml => direct_cache6.yml} | 0 .../{test10.yml => neg_code_injection1.yml} | 0 .../{test13.yml => neg_direct_cache1.yml} | 0 .../{test14.yml => neg_direct_cache2.yml} | 0 .../{test22.yml => neg_direct_cache3.yml} | 0 .../{test12.yml => neg_poisonable_step1.yml} | 0 .../{test18.yml => neg_poisonable_step2.yml} | 16 +-- .../CWE-349/.github/workflows/poc.yml | 63 ------------ .../CWE-349/.github/workflows/poc2.yml | 58 ----------- .../CWE-349/.github/workflows/poc3.yml | 64 ------------ .../{test8.yml => poisonable_step1.yml} | 0 .../{test17.yml => poisonable_step2.yml} | 0 .../.github/workflows/poisonable_step3.yml | 19 ++++ .../.github/workflows/poisonable_step4.yml | 18 ++++ .../.github/workflows/poisonable_step5.yml | 28 ++++++ .../CWE-349/.github/workflows/test19.yml | 42 -------- .../CWE-349/.github/workflows/test20.yml | 46 --------- .../CWE-349/.github/workflows/test21.yml | 44 --------- .../CWE-349/.github/workflows/test3.yml | 23 ----- .../CWE-349/.github/workflows/test4.yml | 21 ---- .../CWE-349/.github/workflows/test5.yml | 19 ---- .../CWE-349/.github/workflows/test6.yml | 18 ---- .../CWE-349/.github/workflows/test7.yml | 17 ---- .../Security/CWE-349/CachePoisoning.expected | 98 ------------------- .../Security/CWE-349/CachePoisoning.qlref | 2 - .../CachePoisoningByCodeInjection.expected | 20 ---- .../CachePoisoningByCodeInjection.qlref | 2 - .../CachePoisoningViaCodeInjection.expected | 11 +++ .../CachePoisoningViaCodeInjection.qlref | 2 + .../CachePoisoningViaDirectCache.expected | 48 +++++++++ .../CachePoisoningViaDirectCache.qlref | 2 + .../CachePoisoningViaPoisonableStep.expected | 49 ++++++++++ .../CachePoisoningViaPoisonableStep.qlref | 2 + 43 files changed, 275 insertions(+), 582 deletions(-) rename ql/src/Security/CWE-349/{CachePoisoningByCodeInjection.ql => CachePoisoningViaCodeInjection.ql} (96%) rename ql/src/Security/CWE-349/{CachePoisoning.ql => CachePoisoningViaDirectCache.ql} (68%) create mode 100644 ql/src/Security/CWE-349/CachePoisoningViaPoisonableStep.ql rename ql/test/query-tests/Security/CWE-349/.github/workflows/{test9.yml => code_injection1.yml} (100%) create mode 100644 ql/test/query-tests/Security/CWE-349/.github/workflows/code_injection2.yml rename ql/test/query-tests/Security/CWE-349/.github/workflows/{test1.yml => direct_cache1.yml} (100%) rename ql/test/query-tests/Security/CWE-349/.github/workflows/{test2.yml => direct_cache2.yml} (100%) rename ql/test/query-tests/Security/CWE-349/.github/workflows/{test11.yml => direct_cache3.yml} (100%) rename ql/test/query-tests/Security/CWE-349/.github/workflows/{test15.yml => direct_cache4.yml} (100%) rename ql/test/query-tests/Security/CWE-349/.github/workflows/{test16.yml => direct_cache5.yml} (100%) rename ql/test/query-tests/Security/CWE-349/.github/workflows/{test23.yml => direct_cache6.yml} (100%) rename ql/test/query-tests/Security/CWE-349/.github/workflows/{test10.yml => neg_code_injection1.yml} (100%) rename ql/test/query-tests/Security/CWE-349/.github/workflows/{test13.yml => neg_direct_cache1.yml} (100%) rename ql/test/query-tests/Security/CWE-349/.github/workflows/{test14.yml => neg_direct_cache2.yml} (100%) rename ql/test/query-tests/Security/CWE-349/.github/workflows/{test22.yml => neg_direct_cache3.yml} (100%) rename ql/test/query-tests/Security/CWE-349/.github/workflows/{test12.yml => neg_poisonable_step1.yml} (100%) rename ql/test/query-tests/Security/CWE-349/.github/workflows/{test18.yml => neg_poisonable_step2.yml} (54%) delete mode 100644 ql/test/query-tests/Security/CWE-349/.github/workflows/poc.yml delete mode 100644 ql/test/query-tests/Security/CWE-349/.github/workflows/poc2.yml delete mode 100644 ql/test/query-tests/Security/CWE-349/.github/workflows/poc3.yml rename ql/test/query-tests/Security/CWE-349/.github/workflows/{test8.yml => poisonable_step1.yml} (100%) rename ql/test/query-tests/Security/CWE-349/.github/workflows/{test17.yml => poisonable_step2.yml} (100%) create mode 100644 ql/test/query-tests/Security/CWE-349/.github/workflows/poisonable_step3.yml create mode 100644 ql/test/query-tests/Security/CWE-349/.github/workflows/poisonable_step4.yml create mode 100644 ql/test/query-tests/Security/CWE-349/.github/workflows/poisonable_step5.yml delete mode 100644 ql/test/query-tests/Security/CWE-349/.github/workflows/test19.yml delete mode 100644 ql/test/query-tests/Security/CWE-349/.github/workflows/test20.yml delete mode 100644 ql/test/query-tests/Security/CWE-349/.github/workflows/test21.yml delete mode 100644 ql/test/query-tests/Security/CWE-349/.github/workflows/test3.yml delete mode 100644 ql/test/query-tests/Security/CWE-349/.github/workflows/test4.yml delete mode 100644 ql/test/query-tests/Security/CWE-349/.github/workflows/test5.yml delete mode 100644 ql/test/query-tests/Security/CWE-349/.github/workflows/test6.yml delete mode 100644 ql/test/query-tests/Security/CWE-349/.github/workflows/test7.yml delete mode 100644 ql/test/query-tests/Security/CWE-349/CachePoisoning.expected delete mode 100644 ql/test/query-tests/Security/CWE-349/CachePoisoning.qlref delete mode 100644 ql/test/query-tests/Security/CWE-349/CachePoisoningByCodeInjection.expected delete mode 100644 ql/test/query-tests/Security/CWE-349/CachePoisoningByCodeInjection.qlref create mode 100644 ql/test/query-tests/Security/CWE-349/CachePoisoningViaCodeInjection.expected create mode 100644 ql/test/query-tests/Security/CWE-349/CachePoisoningViaCodeInjection.qlref create mode 100644 ql/test/query-tests/Security/CWE-349/CachePoisoningViaDirectCache.expected create mode 100644 ql/test/query-tests/Security/CWE-349/CachePoisoningViaDirectCache.qlref create mode 100644 ql/test/query-tests/Security/CWE-349/CachePoisoningViaPoisonableStep.expected create mode 100644 ql/test/query-tests/Security/CWE-349/CachePoisoningViaPoisonableStep.qlref diff --git a/ql/src/Security/CWE-349/CachePoisoningByCodeInjection.ql b/ql/src/Security/CWE-349/CachePoisoningViaCodeInjection.ql similarity index 96% rename from ql/src/Security/CWE-349/CachePoisoningByCodeInjection.ql rename to ql/src/Security/CWE-349/CachePoisoningViaCodeInjection.ql index e7f1385f3cd..685bdcca401 100644 --- a/ql/src/Security/CWE-349/CachePoisoningByCodeInjection.ql +++ b/ql/src/Security/CWE-349/CachePoisoningViaCodeInjection.ql @@ -1,5 +1,5 @@ /** - * @name Cache Poisoning via low-privilege code injection + * @name Cache Poisoning via low-privileged code injection * @description The cache can be poisoned by untrusted code, leading to a cache poisoning attack. * @kind path-problem * @problem.severity error diff --git a/ql/src/Security/CWE-349/CachePoisoning.ql b/ql/src/Security/CWE-349/CachePoisoningViaDirectCache.ql similarity index 68% rename from ql/src/Security/CWE-349/CachePoisoning.ql rename to ql/src/Security/CWE-349/CachePoisoningViaDirectCache.ql index 3807cb4b592..ea36bcf0be1 100644 --- a/ql/src/Security/CWE-349/CachePoisoning.ql +++ b/ql/src/Security/CWE-349/CachePoisoningViaDirectCache.ql @@ -1,11 +1,11 @@ /** - * @name Cache Poisoning + * @name Cache Poisoning via caching of untrusted files * @description The cache can be poisoned by untrusted code, leading to a cache poisoning attack. * @kind path-problem * @problem.severity error * @precision high * @security-severity 7.5 - * @id actions/cache-poisoning + * @id actions/cache-poisoning/direct-cache * @tags actions * security * external/cwe/cwe-349 @@ -45,6 +45,8 @@ query predicate edges(Step a, Step b) { a.getNextStep() = b } from LocalJob j, Event e, Step source, Step s, string message, string path where + // the job checkouts untrusted code from a pull request or downloads an untrusted artifact + j.getAStep() = source and ( source instanceof PRHeadCheckoutStep and message = "due to privilege checkout of untrusted code." and @@ -54,46 +56,35 @@ where message = "due to downloading an untrusted artifact." and path = source.(UntrustedArtifactDownloadStep).getPath() ) and + // the checkout/download is not controlled by an access check + not exists(ControlCheck check | check.protects(source, j.getATriggerEvent())) and j.getATriggerEvent() = e and // job can be triggered by an external user e.isExternallyTriggerable() and - // the checkout is not controlled by an access check - not exists(ControlCheck check | check.protects(source, j.getATriggerEvent())) and ( // the workflow runs in the context of the default branch runsOnDefaultBranch(e) or - // the workflow caller runs in the context of the default branch + // the workflow's caller runs in the context of the default branch e.getName() = "workflow_call" and exists(ExternalJob caller | caller.getCallee() = j.getLocation().getFile().getRelativePath() and runsOnDefaultBranch(caller.getATriggerEvent()) ) ) and - // the job checkouts untrusted code from a pull request - j.getAStep() = source and + // the job writes to the cache + // (No need to follow the checkout/download step since the cache is normally write after the job completes) + j.getAStep() = s and + s instanceof CacheWritingStep and ( - // the job writes to the cache - // (No need to follow the checkout step as the cache writing is normally done after the job completes) - j.getAStep() = s and - s instanceof CacheWritingStep and - ( - // we dont know what code can be controlled by the attacker - path = "?" - or - // we dont know what files are being cached - s.(CacheWritingStep).getPath() = "?" - or - // the cache writing step reads from the path the attacker can control - not path = "?" and controlledCachePath(s.(CacheWritingStep).getPath(), path) - ) and - not s instanceof PoisonableStep + // we dont know what code can be controlled by the attacker + path = "?" or - // the job executes checked-out code - // (The cache specific token can be leaked even for non-privileged workflows) - source.getAFollowingStep() = s and - s instanceof PoisonableStep and - // excluding privileged workflows since they can be exploited in easier circumstances - not j.isPrivileged() - ) + // we dont know what files are being cached + s.(CacheWritingStep).getPath() = "?" + or + // the cache writing step reads from a path the attacker can control + not path = "?" and controlledCachePath(s.(CacheWritingStep).getPath(), path) + ) and + not s instanceof PoisonableStep select s, source, s, "Potential cache poisoning in the context of the default branch " + message diff --git a/ql/src/Security/CWE-349/CachePoisoningViaPoisonableStep.ql b/ql/src/Security/CWE-349/CachePoisoningViaPoisonableStep.ql new file mode 100644 index 00000000000..ee2719f0611 --- /dev/null +++ b/ql/src/Security/CWE-349/CachePoisoningViaPoisonableStep.ql @@ -0,0 +1,58 @@ +/** + * @name Cache Poisoning via execution of untrusted code + * @description The cache can be poisoned by untrusted code, leading to a cache poisoning attack. + * @kind path-problem + * @problem.severity error + * @precision high + * @security-severity 7.5 + * @id actions/cache-poisoning/poisonable-step + * @tags actions + * security + * external/cwe/cwe-349 + */ + +import actions +import codeql.actions.security.ArtifactPoisoningQuery +import codeql.actions.security.UntrustedCheckoutQuery +import codeql.actions.security.CachePoisoningQuery +import codeql.actions.security.PoisonableSteps +import codeql.actions.security.ControlChecks + +query predicate edges(Step a, Step b) { a.getNextStep() = b } + +from LocalJob j, Event e, Step source, Step s, string message, string path +where + // the job checkouts untrusted code from a pull request or downloads an untrusted artifact + j.getAStep() = source and + ( + source instanceof PRHeadCheckoutStep and + message = "due to privilege checkout of untrusted code." and + path = source.(PRHeadCheckoutStep).getPath() + or + source instanceof UntrustedArtifactDownloadStep and + message = "due to downloading an untrusted artifact." and + path = source.(UntrustedArtifactDownloadStep).getPath() + ) and + // the checkout/download is not controlled by an access check + not exists(ControlCheck check | check.protects(source, j.getATriggerEvent())) and + j.getATriggerEvent() = e and + // job can be triggered by an external user + e.isExternallyTriggerable() and + ( + // the workflow runs in the context of the default branch + runsOnDefaultBranch(e) + or + // the workflow's caller runs in the context of the default branch + e.getName() = "workflow_call" and + exists(ExternalJob caller | + caller.getCallee() = j.getLocation().getFile().getRelativePath() and + runsOnDefaultBranch(caller.getATriggerEvent()) + ) + ) and + // the job executes checked-out code + // (The cache specific token can be leaked even for non-privileged workflows) + source.getAFollowingStep() = s and + s instanceof PoisonableStep and + // excluding privileged workflows since they can be exploited in easier circumstances + not j.isPrivileged() +select s, source, s, "Potential cache poisoning in the context of the default branch " + message diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test9.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/code_injection1.yml similarity index 100% rename from ql/test/query-tests/Security/CWE-349/.github/workflows/test9.yml rename to ql/test/query-tests/Security/CWE-349/.github/workflows/code_injection1.yml diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/code_injection2.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/code_injection2.yml new file mode 100644 index 00000000000..9c87340d7ab --- /dev/null +++ b/ql/test/query-tests/Security/CWE-349/.github/workflows/code_injection2.yml @@ -0,0 +1,16 @@ +name: Test + +on: + pull_request_target: + branches: [ master, main, dev ] + +jobs: + test: + name: Test + runs-on: ubuntu-latest + steps: + - id: modified_files + uses: trilom/file-changes-action@v1.2.4 + with: + output: "," + - run: echo "${{ steps.modified_files.outputs.files_modified }}" diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test1.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/direct_cache1.yml similarity index 100% rename from ql/test/query-tests/Security/CWE-349/.github/workflows/test1.yml rename to ql/test/query-tests/Security/CWE-349/.github/workflows/direct_cache1.yml diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test2.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/direct_cache2.yml similarity index 100% rename from ql/test/query-tests/Security/CWE-349/.github/workflows/test2.yml rename to ql/test/query-tests/Security/CWE-349/.github/workflows/direct_cache2.yml diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test11.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/direct_cache3.yml similarity index 100% rename from ql/test/query-tests/Security/CWE-349/.github/workflows/test11.yml rename to ql/test/query-tests/Security/CWE-349/.github/workflows/direct_cache3.yml diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test15.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/direct_cache4.yml similarity index 100% rename from ql/test/query-tests/Security/CWE-349/.github/workflows/test15.yml rename to ql/test/query-tests/Security/CWE-349/.github/workflows/direct_cache4.yml diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test16.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/direct_cache5.yml similarity index 100% rename from ql/test/query-tests/Security/CWE-349/.github/workflows/test16.yml rename to ql/test/query-tests/Security/CWE-349/.github/workflows/direct_cache5.yml diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test23.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/direct_cache6.yml similarity index 100% rename from ql/test/query-tests/Security/CWE-349/.github/workflows/test23.yml rename to ql/test/query-tests/Security/CWE-349/.github/workflows/direct_cache6.yml diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test10.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/neg_code_injection1.yml similarity index 100% rename from ql/test/query-tests/Security/CWE-349/.github/workflows/test10.yml rename to ql/test/query-tests/Security/CWE-349/.github/workflows/neg_code_injection1.yml diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test13.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/neg_direct_cache1.yml similarity index 100% rename from ql/test/query-tests/Security/CWE-349/.github/workflows/test13.yml rename to ql/test/query-tests/Security/CWE-349/.github/workflows/neg_direct_cache1.yml diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test14.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/neg_direct_cache2.yml similarity index 100% rename from ql/test/query-tests/Security/CWE-349/.github/workflows/test14.yml rename to ql/test/query-tests/Security/CWE-349/.github/workflows/neg_direct_cache2.yml diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test22.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/neg_direct_cache3.yml similarity index 100% rename from ql/test/query-tests/Security/CWE-349/.github/workflows/test22.yml rename to ql/test/query-tests/Security/CWE-349/.github/workflows/neg_direct_cache3.yml diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test12.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/neg_poisonable_step1.yml similarity index 100% rename from ql/test/query-tests/Security/CWE-349/.github/workflows/test12.yml rename to ql/test/query-tests/Security/CWE-349/.github/workflows/neg_poisonable_step1.yml diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test18.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/neg_poisonable_step2.yml similarity index 54% rename from ql/test/query-tests/Security/CWE-349/.github/workflows/test18.yml rename to ql/test/query-tests/Security/CWE-349/.github/workflows/neg_poisonable_step2.yml index 6bfdc5b7d50..be1533f2231 100644 --- a/ql/test/query-tests/Security/CWE-349/.github/workflows/test18.yml +++ b/ql/test/query-tests/Security/CWE-349/.github/workflows/neg_poisonable_step2.yml @@ -5,27 +5,13 @@ on: push: branches: - main - - 'releases/*' jobs: - verify-build: + test: runs-on: ubuntu-latest - steps: - uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.sha }} - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version-file: .nvmrc - - - name: Install NPM dependencies - run: npm ci - - - name: Rebuild the dist/ directory - run: npm run build - - name: Compare the expected and actual dist/ directories run: bin/check-build-output-in-dist-directory diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/poc.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/poc.yml deleted file mode 100644 index 6900c3bc23f..00000000000 --- a/ql/test/query-tests/Security/CWE-349/.github/workflows/poc.yml +++ /dev/null @@ -1,63 +0,0 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. - -# Sample workflow for building and deploying a Jekyll site to GitHub Pages -name: Deploy Jekyll site to Pages preview environment -on: - # Runs on pull requests targeting the default branch - pull_request_target: - branches: ["main"] -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - contents: read - pages: write - id-token: write -# Allow only one concurrent deployment per PR, skipping runs queued between the run in-progress and latest queued. -# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. -concurrency: - group: 'pages-preview @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}' - cancel-in-progress: false -jobs: - # Build job - build: - # Limit permissions of the GITHUB_TOKEN for untrusted code - permissions: - contents: read - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 - with: - # For PRs make sure to checkout the PR branch - ref: ${{ github.event.pull_request.head.ref }} - repository: ${{ github.event.pull_request.head.repo.full_name }} - - name: Setup Pages - uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5 - - name: Build with Jekyll - uses: actions/jekyll-build-pages@b178f9334b208360999a0a57b523613563698c66 # v1 - with: - source: ./ - destination: ./_site - - name: Upload artifact - # Automatically uploads an artifact from the './_site' directory by default - uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3 - # Deployment job - deploy: - environment: - name: 'Pages Preview' - url: ${{ steps.deployment.outputs.page_url }} - # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages - permissions: - contents: read - pages: write - id-token: write - runs-on: ubuntu-latest - needs: build - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4 - with: - preview: 'true' diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/poc2.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/poc2.yml deleted file mode 100644 index 5501beb9ea2..00000000000 --- a/ql/test/query-tests/Security/CWE-349/.github/workflows/poc2.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: branch-deploy - -on: - issue_comment: - types: [created] - -# Permissions needed for reacting and adding comments for IssueOps commands -permissions: - pull-requests: write - deployments: write - contents: write - checks: read - -jobs: - branch-deploy: - name: branch-deploy - if: # only run on pull request comments and very specific comment body string as defined in our branch-deploy settings - ${{ github.event.issue.pull_request && - (startsWith(github.event.comment.body, '.deploy') || - startsWith(github.event.comment.body, '.noop') || - startsWith(github.event.comment.body, '.lock') || - startsWith(github.event.comment.body, '.help') || - startsWith(github.event.comment.body, '.wcid') || - startsWith(github.event.comment.body, '.unlock')) }} - runs-on: ubuntu-latest - - steps: - - name: branch-deploy - id: branch-deploy - uses: github/branch-deploy@v9 - with: - trigger: ".deploy" - environment: "production" - sticky_locks: "true" # https://github.com/github/branch-deploy/blob/1f6516ef5092890ce75d9e97ca7cbdb628e38bdd/docs/hubot-style-deployment-locks.md - - # Check out the ref from the output of the IssueOps command - - uses: actions/checkout@v4 - if: ${{ steps.branch-deploy.outputs.continue == 'true' }} - with: - ref: ${{ steps.branch-deploy.outputs.ref }} - - - uses: ruby/setup-ruby@d4526a55538b775af234ba4af27118ed6f8f6677 # pin@v1.172.0 - if: ${{ steps.branch-deploy.outputs.continue == 'true' }} - with: - bundler-cache: true - - - name: bootstrap - if: ${{ steps.branch-deploy.outputs.continue == 'true' }} - run: script/bootstrap - - # Here we run a deploy. It is "gated" by the IssueOps logic and will only run if the outputs from our branch-deploy step indicate that the workflow should continue - - name: deploy - if: ${{ steps.branch-deploy.outputs.continue == 'true' && steps.branch-deploy.outputs.noop != 'true' }} - run: | - set -o pipefail - script/deploy | tee deploy.out - bundle exec ruby script/ci/render_deploy_message.rb - rm deploy.out diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/poc3.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/poc3.yml deleted file mode 100644 index 4d5ae1f528c..00000000000 --- a/ql/test/query-tests/Security/CWE-349/.github/workflows/poc3.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: Publish - -on: - push: - branches: - - main - pull_request_target: - workflow_dispatch: - workflow_call: - -jobs: - build-and-upload: - runs-on: ubuntu-latest - permissions: - contents: read - steps: - - - name: Checkout PR - if: ${{ github.event_name == 'pull_request_target' }} - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.ref }} - repository: ${{ github.event.pull_request.head.repo.full_name }} - - - name: Checkout - if: ${{ github.event_name != 'pull_request_target' }} - uses: actions/checkout@v3 - with: - ref: main - - - name: Setup Pages - uses: actions/configure-pages@v1 - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: 18 - cache: npm - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund --package-lock - - run: npm run build -w www - - name: Upload artifact - uses: actions/upload-pages-artifact@v1 - with: - path: './workspaces/www/build' - - deploy: - runs-on: ubuntu-latest - needs: build-and-upload - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - permissions: - pages: write - id-token: write - outputs: - deployment_url: ${{ steps.deployment.outputs.page_url }} - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v1 - with: - preview: ${{ github.event_name == 'pull_request_target' }} diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test8.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/poisonable_step1.yml similarity index 100% rename from ql/test/query-tests/Security/CWE-349/.github/workflows/test8.yml rename to ql/test/query-tests/Security/CWE-349/.github/workflows/poisonable_step1.yml diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test17.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/poisonable_step2.yml similarity index 100% rename from ql/test/query-tests/Security/CWE-349/.github/workflows/test17.yml rename to ql/test/query-tests/Security/CWE-349/.github/workflows/poisonable_step2.yml diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/poisonable_step3.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/poisonable_step3.yml new file mode 100644 index 00000000000..8539bf2bda4 --- /dev/null +++ b/ql/test/query-tests/Security/CWE-349/.github/workflows/poisonable_step3.yml @@ -0,0 +1,19 @@ +name: Publish + +on: + pull_request_target: + +jobs: + build-and-upload: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + + - name: Checkout PR + uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.ref }} + repository: ${{ github.event.pull_request.head.repo.full_name }} + + - run: npm run build -w www diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/poisonable_step4.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/poisonable_step4.yml new file mode 100644 index 00000000000..6e2351c1744 --- /dev/null +++ b/ql/test/query-tests/Security/CWE-349/.github/workflows/poisonable_step4.yml @@ -0,0 +1,18 @@ +name: OpenAPI +on: + pull_request_target: + +permissions: {} + +jobs: + + openapi-base: + runs-on: ubuntu-latest + permissions: read-all + steps: + - name: Checkout repository + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + with: + ref: ${{ github.event.pull_request.head.sha }} + repository: ${{ github.event.pull_request.head.repo.full_name }} + - run: ./foo diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/poisonable_step5.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/poisonable_step5.yml new file mode 100644 index 00000000000..9742bd01a48 --- /dev/null +++ b/ql/test/query-tests/Security/CWE-349/.github/workflows/poisonable_step5.yml @@ -0,0 +1,28 @@ +name: Test +on: + pull_request_target: + branches: ["main"] + +permissions: + contents: read + pages: write + id-token: write + +jobs: + build: + permissions: + contents: read + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 + with: + ref: ${{ github.event.pull_request.head.ref }} + repository: ${{ github.event.pull_request.head.repo.full_name }} + - name: Setup Pages + uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5 + - name: Build with Jekyll + uses: actions/jekyll-build-pages@b178f9334b208360999a0a57b523613563698c66 # v1 + with: + source: ./ + destination: ./_site diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test19.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/test19.yml deleted file mode 100644 index 1f0e7291442..00000000000 --- a/ql/test/query-tests/Security/CWE-349/.github/workflows/test19.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: Close Translation Pull Requests - -on: - pull_request_target: - branches: [ master, main, dev ] - -jobs: - - close-translation-prs: - - name: Close Translation Pull Requests - runs-on: ubuntu-latest - - steps: - - name: Get changed files - id: modified_files - uses: trilom/file-changes-action@v1.2.4 - with: - output: "," - - - name: Check the PR for translations - id: check - run: | - shopt -s nocasematch - if [[ "${{ steps.modified_files.outputs.files_modified }}" == *"en_gb/strings.po"* ]]; then - echo "Found modified en_gb, likely a valid PR" - unset CLOSE - elif [[ "${{ steps.modified_files.outputs.files_modified }}" == *"strings.po"* ]]; then - echo "Found modified strings.po, unwanted." - CLOSE="true" - elif [[ "${{ steps.modified_files.outputs.files_added }}" == *"strings.po"* ]]; then - echo "Found added strings.po, unwanted." - CLOSE="true" - elif [[ "${{ steps.modified_files.outputs.files_removed }}" == *"strings.po"* ]]; then - echo "Found removed strings.po, unwanted." - CLOSE="true" - else - echo "No strings.po were modified or added, not a translation." - unset CLOSE - fi - echo ::set-output name=close::${CLOSE} - diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test20.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/test20.yml deleted file mode 100644 index a07f2922fd7..00000000000 --- a/ql/test/query-tests/Security/CWE-349/.github/workflows/test20.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: Publish - -on: - push: - branches: - - main - pull_request_target: - workflow_dispatch: - workflow_call: - -jobs: - build-and-upload: - runs-on: ubuntu-latest - permissions: - contents: read - steps: - - - name: Checkout PR - if: ${{ github.event_name == 'pull_request_target' }} - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.ref }} - repository: ${{ github.event.pull_request.head.repo.full_name }} - - - name: Checkout - if: ${{ github.event_name != 'pull_request_target' }} - uses: actions/checkout@v3 - with: - ref: main - - - name: Setup Pages - uses: actions/configure-pages@v1 - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: 18 - cache: npm - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund --package-lock - - run: npm run build -w www - - name: Upload artifact - uses: actions/upload-pages-artifact@v1 - with: - path: './workspaces/www/build' diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test21.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/test21.yml deleted file mode 100644 index 381cc16a6d1..00000000000 --- a/ql/test/query-tests/Security/CWE-349/.github/workflows/test21.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: OpenAPI -on: - push: - branches: - - master - tags: - - 'v*' - pull_request_target: - -permissions: {} - -jobs: - - openapi-base: - name: OpenAPI - BASE - if: ${{ github.base_ref != '' }} - runs-on: ubuntu-latest - permissions: read-all - steps: - - name: Checkout repository - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - with: - ref: ${{ github.event.pull_request.head.sha }} - repository: ${{ github.event.pull_request.head.repo.full_name }} - fetch-depth: 0 - - name: Generate openapi.json - run: dotnet test tests/Jellyfin.Server.Integration.Tests/Jellyfin.Server.Integration.Tests.csproj -c Release --filter "Jellyfin.Server.Integration.Tests.OpenApiSpecTests" - - publish-unstable: - name: OpenAPI - Publish Unstable Spec - if: ${{ github.event_name != 'pull_request_target' && !startsWith(github.ref, 'refs/tags/v') && contains(github.repository_owner, 'jellyfin') }} - runs-on: ubuntu-latest - needs: - - openapi-base - steps: - - name: Upload openapi.json (unstable) to repository server - uses: appleboy/scp-action@917f8b81dfc1ccd331fef9e2d61bdc6c8be94634 # v0.1.7 - with: - host: "${{ secrets.REPO_HOST }}" - username: "${{ secrets.REPO_USER }}" - key: "${{ secrets.REPO_KEY }}" - source: openapi-head/openapi.json - strip_components: 1 - target: "/srv/incoming/openapi/unstable/jellyfin-openapi-${{ env.JELLYFIN_VERSION }}" diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test3.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/test3.yml deleted file mode 100644 index fa56d074936..00000000000 --- a/ql/test/query-tests/Security/CWE-349/.github/workflows/test3.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Cache Poisoning - -on: pull_request_target - -permissions: {} - -jobs: - poison: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.sha }} - - uses: actions/setup-java@v2 - with: - distribution: 'zulu' - java-version: '21' - cache: 'gradle' - cache-dependency-path: | - sub-project/*.gradle* - sub-project/**/gradle-wrapper.properties - - run: | - java HelloWorldApp.java diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test4.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/test4.yml deleted file mode 100644 index 03eb9e99f0f..00000000000 --- a/ql/test/query-tests/Security/CWE-349/.github/workflows/test4.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Cache Poisoning - -on: pull_request_target - -permissions: - contents: read - -jobs: - poison: - runs-on: ubuntu-latest - permissions: read-all - steps: - - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.sha }} - - uses: actions/setup-java@v2 - with: - distribution: 'zulu' - java-version: '21' - - run: | - java HelloWorldApp.java diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test5.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/test5.yml deleted file mode 100644 index b7454d0a0dc..00000000000 --- a/ql/test/query-tests/Security/CWE-349/.github/workflows/test5.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Cache Poisoning - -on: pull_request_target - -jobs: - poison: - runs-on: ubuntu-latest - permissions: - contents: read - steps: - - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.sha }} - - uses: actions/setup-go@v2 - with: - go-version-file: 'go.mod' - cache: false - - run: do some go stuff - diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test6.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/test6.yml deleted file mode 100644 index 2fa898982bc..00000000000 --- a/ql/test/query-tests/Security/CWE-349/.github/workflows/test6.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Cache Poisoning - -on: pull_request_target - -jobs: - poison: - runs-on: ubuntu-latest - permissions: read-all - steps: - - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.sha }} - - uses: actions/setup-go@v2 - with: - go-version-file: 'go.mod' - cache: true - - run: do some go stuff - diff --git a/ql/test/query-tests/Security/CWE-349/.github/workflows/test7.yml b/ql/test/query-tests/Security/CWE-349/.github/workflows/test7.yml deleted file mode 100644 index be83f83cf30..00000000000 --- a/ql/test/query-tests/Security/CWE-349/.github/workflows/test7.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Cache Poisoning - -on: pull_request_target - -jobs: - poison: - runs-on: ubuntu-latest - permissions: read-all - steps: - - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.sha }} - - uses: actions/setup-go@v2 - with: - go-version-file: 'go.mod' - - run: do some go stuff - diff --git a/ql/test/query-tests/Security/CWE-349/CachePoisoning.expected b/ql/test/query-tests/Security/CWE-349/CachePoisoning.expected deleted file mode 100644 index fdaf0cf25ad..00000000000 --- a/ql/test/query-tests/Security/CWE-349/CachePoisoning.expected +++ /dev/null @@ -1,98 +0,0 @@ -edges -| .github/workflows/poc2.yml:28:9:37:6 | Uses Step: branch-deploy | .github/workflows/poc2.yml:37:9:42:6 | Uses Step | -| .github/workflows/poc2.yml:37:9:42:6 | Uses Step | .github/workflows/poc2.yml:42:9:47:6 | Uses Step | -| .github/workflows/poc2.yml:42:9:47:6 | Uses Step | .github/workflows/poc2.yml:47:9:52:6 | Run Step | -| .github/workflows/poc2.yml:47:9:52:6 | Run Step | .github/workflows/poc2.yml:52:9:58:24 | Run Step | -| .github/workflows/poc3.yml:18:7:25:4 | Uses Step | .github/workflows/poc3.yml:25:7:31:4 | Uses Step | -| .github/workflows/poc3.yml:25:7:31:4 | Uses Step | .github/workflows/poc3.yml:31:7:33:4 | Uses Step | -| .github/workflows/poc3.yml:31:7:33:4 | Uses Step | .github/workflows/poc3.yml:33:7:38:4 | Uses Step | -| .github/workflows/poc3.yml:33:7:38:4 | Uses Step | .github/workflows/poc3.yml:38:7:40:4 | Run Step | -| .github/workflows/poc3.yml:38:7:40:4 | Run Step | .github/workflows/poc3.yml:40:7:41:4 | Run Step | -| .github/workflows/poc3.yml:40:7:41:4 | Run Step | .github/workflows/poc3.yml:41:7:42:4 | Run Step | -| .github/workflows/poc3.yml:41:7:42:4 | Run Step | .github/workflows/poc3.yml:42:7:43:4 | Run Step | -| .github/workflows/poc3.yml:42:7:43:4 | Run Step | .github/workflows/poc3.yml:43:7:48:2 | Uses Step | -| .github/workflows/poc.yml:30:9:36:6 | Uses Step | .github/workflows/poc.yml:36:9:38:6 | Uses Step | -| .github/workflows/poc.yml:36:9:38:6 | Uses Step | .github/workflows/poc.yml:38:9:43:6 | Uses Step | -| .github/workflows/poc.yml:38:9:43:6 | Uses Step | .github/workflows/poc.yml:43:9:47:2 | Uses Step | -| .github/workflows/test1.yml:10:9:13:6 | Uses Step: comment-branch | .github/workflows/test1.yml:13:9:18:6 | Uses Step | -| .github/workflows/test1.yml:13:9:18:6 | Uses Step | .github/workflows/test1.yml:18:9:22:6 | Uses Step | -| .github/workflows/test1.yml:18:9:22:6 | Uses Step | .github/workflows/test1.yml:22:9:23:21 | Run Step | -| .github/workflows/test2.yml:11:9:14:6 | Uses Step | .github/workflows/test2.yml:14:9:18:6 | Uses Step | -| .github/workflows/test2.yml:14:9:18:6 | Uses Step | .github/workflows/test2.yml:18:9:19:21 | Run Step | -| .github/workflows/test3.yml:11:9:14:6 | Uses Step | .github/workflows/test3.yml:14:9:22:6 | Uses Step | -| .github/workflows/test3.yml:14:9:22:6 | Uses Step | .github/workflows/test3.yml:22:9:23:34 | Run Step | -| .github/workflows/test4.yml:13:9:16:6 | Uses Step | .github/workflows/test4.yml:16:9:20:6 | Uses Step | -| .github/workflows/test4.yml:16:9:20:6 | Uses Step | .github/workflows/test4.yml:20:9:21:34 | Run Step | -| .github/workflows/test5.yml:11:9:14:6 | Uses Step | .github/workflows/test5.yml:14:9:18:6 | Uses Step | -| .github/workflows/test5.yml:14:9:18:6 | Uses Step | .github/workflows/test5.yml:18:9:19:11 | Run Step | -| .github/workflows/test6.yml:10:9:13:6 | Uses Step | .github/workflows/test6.yml:13:9:17:6 | Uses Step | -| .github/workflows/test6.yml:13:9:17:6 | Uses Step | .github/workflows/test6.yml:17:9:18:11 | Run Step | -| .github/workflows/test7.yml:10:9:13:6 | Uses Step | .github/workflows/test7.yml:13:9:16:6 | Uses Step | -| .github/workflows/test7.yml:13:9:16:6 | Uses Step | .github/workflows/test7.yml:16:9:17:11 | Run Step | -| .github/workflows/test8.yml:10:9:12:6 | Uses Step: comment-branch | .github/workflows/test8.yml:12:9:15:6 | Uses Step | -| .github/workflows/test8.yml:12:9:15:6 | Uses Step | .github/workflows/test8.yml:15:9:17:2 | Run Step | -| .github/workflows/test8.yml:21:9:23:6 | Uses Step: comment-branch | .github/workflows/test8.yml:23:9:26:6 | Uses Step | -| .github/workflows/test8.yml:23:9:26:6 | Uses Step | .github/workflows/test8.yml:26:9:28:2 | Uses Step | -| .github/workflows/test8.yml:32:9:34:6 | Uses Step: comment-branch | .github/workflows/test8.yml:34:9:37:6 | Uses Step | -| .github/workflows/test8.yml:34:9:37:6 | Uses Step | .github/workflows/test8.yml:37:9:37:75 | Run Step | -| .github/workflows/test11.yml:11:9:14:6 | Uses Step: comment-branch | .github/workflows/test11.yml:14:9:19:6 | Uses Step | -| .github/workflows/test11.yml:14:9:19:6 | Uses Step | .github/workflows/test11.yml:19:9:23:6 | Uses Step | -| .github/workflows/test11.yml:19:9:23:6 | Uses Step | .github/workflows/test11.yml:23:9:24:21 | Run Step | -| .github/workflows/test12.yml:11:9:14:6 | Uses Step: comment-branch | .github/workflows/test12.yml:14:9:19:6 | Uses Step | -| .github/workflows/test12.yml:14:9:19:6 | Uses Step | .github/workflows/test12.yml:19:9:20:30 | Run Step | -| .github/workflows/test13.yml:14:9:17:6 | Uses Step | .github/workflows/test13.yml:17:9:21:6 | Uses Step | -| .github/workflows/test13.yml:17:9:21:6 | Uses Step | .github/workflows/test13.yml:21:9:22:21 | Run Step | -| .github/workflows/test14.yml:14:9:17:6 | Uses Step | .github/workflows/test14.yml:17:9:21:6 | Uses Step | -| .github/workflows/test14.yml:17:9:21:6 | Uses Step | .github/workflows/test14.yml:21:9:22:21 | Run Step | -| .github/workflows/test15.yml:14:9:17:6 | Uses Step | .github/workflows/test15.yml:17:9:21:6 | Uses Step | -| .github/workflows/test15.yml:17:9:21:6 | Uses Step | .github/workflows/test15.yml:21:9:22:21 | Run Step | -| .github/workflows/test16.yml:14:9:17:6 | Uses Step | .github/workflows/test16.yml:17:9:21:6 | Uses Step | -| .github/workflows/test16.yml:17:9:21:6 | Uses Step | .github/workflows/test16.yml:21:9:22:21 | Run Step | -| .github/workflows/test17.yml:15:9:20:6 | Uses Step | .github/workflows/test17.yml:20:9:22:6 | Uses Step | -| .github/workflows/test17.yml:20:9:22:6 | Uses Step | .github/workflows/test17.yml:22:9:26:31 | Uses Step | -| .github/workflows/test18.yml:15:9:19:6 | Uses Step | .github/workflows/test18.yml:19:9:24:6 | Uses Step | -| .github/workflows/test18.yml:19:9:24:6 | Uses Step | .github/workflows/test18.yml:24:9:27:6 | Run Step | -| .github/workflows/test18.yml:24:9:27:6 | Run Step | .github/workflows/test18.yml:27:9:30:6 | Run Step | -| .github/workflows/test18.yml:27:9:30:6 | Run Step | .github/workflows/test18.yml:30:9:31:54 | Run Step | -| .github/workflows/test19.yml:15:9:21:6 | Uses Step: modified_files | .github/workflows/test19.yml:21:9:41:49 | Run Step: check | -| .github/workflows/test20.yml:18:7:25:4 | Uses Step | .github/workflows/test20.yml:25:7:31:4 | Uses Step | -| .github/workflows/test20.yml:25:7:31:4 | Uses Step | .github/workflows/test20.yml:31:7:33:4 | Uses Step | -| .github/workflows/test20.yml:31:7:33:4 | Uses Step | .github/workflows/test20.yml:33:7:38:4 | Uses Step | -| .github/workflows/test20.yml:33:7:38:4 | Uses Step | .github/workflows/test20.yml:38:7:40:4 | Run Step | -| .github/workflows/test20.yml:38:7:40:4 | Run Step | .github/workflows/test20.yml:40:7:41:4 | Run Step | -| .github/workflows/test20.yml:40:7:41:4 | Run Step | .github/workflows/test20.yml:41:7:42:4 | Run Step | -| .github/workflows/test20.yml:41:7:42:4 | Run Step | .github/workflows/test20.yml:42:7:43:4 | Run Step | -| .github/workflows/test20.yml:42:7:43:4 | Run Step | .github/workflows/test20.yml:43:7:46:39 | Uses Step | -| .github/workflows/test21.yml:20:9:26:6 | Uses Step | .github/workflows/test21.yml:26:9:29:2 | Run Step | -| .github/workflows/test22.yml:13:9:14:6 | Uses Step | .github/workflows/test22.yml:14:9:18:6 | Uses Step | -| .github/workflows/test22.yml:14:9:18:6 | Uses Step | .github/workflows/test22.yml:18:9:25:6 | Uses Step: cache-pip | -| .github/workflows/test22.yml:18:9:25:6 | Uses Step: cache-pip | .github/workflows/test22.yml:25:9:30:6 | Uses Step | -| .github/workflows/test22.yml:25:9:30:6 | Uses Step | .github/workflows/test22.yml:30:9:35:36 | Uses Step | -| .github/workflows/test23.yml:13:9:14:6 | Uses Step | .github/workflows/test23.yml:14:9:18:6 | Uses Step | -| .github/workflows/test23.yml:14:9:18:6 | Uses Step | .github/workflows/test23.yml:18:9:25:6 | Uses Step: cache-pip | -| .github/workflows/test23.yml:18:9:25:6 | Uses Step: cache-pip | .github/workflows/test23.yml:25:9:30:6 | Uses Step | -| .github/workflows/test23.yml:25:9:30:6 | Uses Step | .github/workflows/test23.yml:30:9:35:36 | Uses Step | -#select -| .github/workflows/poc3.yml:33:7:38:4 | Uses Step | .github/workflows/poc3.yml:18:7:25:4 | Uses Step | .github/workflows/poc3.yml:33:7:38:4 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | -| .github/workflows/poc3.yml:38:7:40:4 | Run Step | .github/workflows/poc3.yml:18:7:25:4 | Uses Step | .github/workflows/poc3.yml:38:7:40:4 | Run Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | -| .github/workflows/poc3.yml:41:7:42:4 | Run Step | .github/workflows/poc3.yml:18:7:25:4 | Uses Step | .github/workflows/poc3.yml:41:7:42:4 | Run Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | -| .github/workflows/poc3.yml:42:7:43:4 | Run Step | .github/workflows/poc3.yml:18:7:25:4 | Uses Step | .github/workflows/poc3.yml:42:7:43:4 | Run Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | -| .github/workflows/poc.yml:38:9:43:6 | Uses Step | .github/workflows/poc.yml:30:9:36:6 | Uses Step | .github/workflows/poc.yml:38:9:43:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | -| .github/workflows/test1.yml:18:9:22:6 | Uses Step | .github/workflows/test1.yml:13:9:18:6 | Uses Step | .github/workflows/test1.yml:18:9:22:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | -| .github/workflows/test2.yml:14:9:18:6 | Uses Step | .github/workflows/test2.yml:11:9:14:6 | Uses Step | .github/workflows/test2.yml:14:9:18:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | -| .github/workflows/test3.yml:14:9:22:6 | Uses Step | .github/workflows/test3.yml:11:9:14:6 | Uses Step | .github/workflows/test3.yml:14:9:22:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | -| .github/workflows/test6.yml:13:9:17:6 | Uses Step | .github/workflows/test6.yml:10:9:13:6 | Uses Step | .github/workflows/test6.yml:13:9:17:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | -| .github/workflows/test7.yml:13:9:16:6 | Uses Step | .github/workflows/test7.yml:10:9:13:6 | Uses Step | .github/workflows/test7.yml:13:9:16:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | -| .github/workflows/test8.yml:15:9:17:2 | Run Step | .github/workflows/test8.yml:12:9:15:6 | Uses Step | .github/workflows/test8.yml:15:9:17:2 | Run Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | -| .github/workflows/test8.yml:26:9:28:2 | Uses Step | .github/workflows/test8.yml:23:9:26:6 | Uses Step | .github/workflows/test8.yml:26:9:28:2 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | -| .github/workflows/test8.yml:37:9:37:75 | Run Step | .github/workflows/test8.yml:34:9:37:6 | Uses Step | .github/workflows/test8.yml:37:9:37:75 | Run Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | -| .github/workflows/test11.yml:19:9:23:6 | Uses Step | .github/workflows/test11.yml:14:9:19:6 | Uses Step | .github/workflows/test11.yml:19:9:23:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | -| .github/workflows/test15.yml:17:9:21:6 | Uses Step | .github/workflows/test15.yml:14:9:17:6 | Uses Step | .github/workflows/test15.yml:17:9:21:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | -| .github/workflows/test16.yml:17:9:21:6 | Uses Step | .github/workflows/test16.yml:14:9:17:6 | Uses Step | .github/workflows/test16.yml:17:9:21:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | -| .github/workflows/test17.yml:22:9:26:31 | Uses Step | .github/workflows/test17.yml:15:9:20:6 | Uses Step | .github/workflows/test17.yml:22:9:26:31 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | -| .github/workflows/test20.yml:33:7:38:4 | Uses Step | .github/workflows/test20.yml:18:7:25:4 | Uses Step | .github/workflows/test20.yml:33:7:38:4 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | -| .github/workflows/test20.yml:38:7:40:4 | Run Step | .github/workflows/test20.yml:18:7:25:4 | Uses Step | .github/workflows/test20.yml:38:7:40:4 | Run Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | -| .github/workflows/test20.yml:41:7:42:4 | Run Step | .github/workflows/test20.yml:18:7:25:4 | Uses Step | .github/workflows/test20.yml:41:7:42:4 | Run Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | -| .github/workflows/test20.yml:42:7:43:4 | Run Step | .github/workflows/test20.yml:18:7:25:4 | Uses Step | .github/workflows/test20.yml:42:7:43:4 | Run Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | -| .github/workflows/test21.yml:26:9:29:2 | Run Step | .github/workflows/test21.yml:20:9:26:6 | Uses Step | .github/workflows/test21.yml:26:9:29:2 | Run Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | -| .github/workflows/test23.yml:18:9:25:6 | Uses Step: cache-pip | .github/workflows/test23.yml:25:9:30:6 | Uses Step | .github/workflows/test23.yml:18:9:25:6 | Uses Step: cache-pip | Potential cache poisoning in the context of the default branch due to downloading an untrusted artifact. | diff --git a/ql/test/query-tests/Security/CWE-349/CachePoisoning.qlref b/ql/test/query-tests/Security/CWE-349/CachePoisoning.qlref deleted file mode 100644 index 2cbd05800e6..00000000000 --- a/ql/test/query-tests/Security/CWE-349/CachePoisoning.qlref +++ /dev/null @@ -1,2 +0,0 @@ -Security/CWE-349/CachePoisoning.ql - diff --git a/ql/test/query-tests/Security/CWE-349/CachePoisoningByCodeInjection.expected b/ql/test/query-tests/Security/CWE-349/CachePoisoningByCodeInjection.expected deleted file mode 100644 index e0a5e8fd4b1..00000000000 --- a/ql/test/query-tests/Security/CWE-349/CachePoisoningByCodeInjection.expected +++ /dev/null @@ -1,20 +0,0 @@ -edges -| .github/workflows/test19.yml:15:9:21:6 | Uses Step: modified_files | .github/workflows/test19.yml:25:18:25:67 | steps.modified_files.outputs.files_modified | provenance | | -| .github/workflows/test19.yml:15:9:21:6 | Uses Step: modified_files | .github/workflows/test19.yml:28:20:28:69 | steps.modified_files.outputs.files_modified | provenance | | -| .github/workflows/test19.yml:15:9:21:6 | Uses Step: modified_files | .github/workflows/test19.yml:31:20:31:66 | steps.modified_files.outputs.files_added | provenance | | -| .github/workflows/test19.yml:15:9:21:6 | Uses Step: modified_files | .github/workflows/test19.yml:34:20:34:68 | steps.modified_files.outputs.files_removed | provenance | | -nodes -| .github/workflows/test9.yml:11:17:11:48 | github.event.comment.body | semmle.label | github.event.comment.body | -| .github/workflows/test10.yml:11:17:11:48 | github.event.comment.body | semmle.label | github.event.comment.body | -| .github/workflows/test19.yml:15:9:21:6 | Uses Step: modified_files | semmle.label | Uses Step: modified_files | -| .github/workflows/test19.yml:25:18:25:67 | steps.modified_files.outputs.files_modified | semmle.label | steps.modified_files.outputs.files_modified | -| .github/workflows/test19.yml:28:20:28:69 | steps.modified_files.outputs.files_modified | semmle.label | steps.modified_files.outputs.files_modified | -| .github/workflows/test19.yml:31:20:31:66 | steps.modified_files.outputs.files_added | semmle.label | steps.modified_files.outputs.files_added | -| .github/workflows/test19.yml:34:20:34:68 | steps.modified_files.outputs.files_removed | semmle.label | steps.modified_files.outputs.files_removed | -subpaths -#select -| .github/workflows/test9.yml:11:17:11:48 | github.event.comment.body | .github/workflows/test9.yml:11:17:11:48 | github.event.comment.body | .github/workflows/test9.yml:11:17:11:48 | github.event.comment.body | Unprivileged code injection in $@, which may lead to cache poisoning. | .github/workflows/test9.yml:11:17:11:48 | github.event.comment.body | ${{ github.event.comment.body }} | -| .github/workflows/test19.yml:25:18:25:67 | steps.modified_files.outputs.files_modified | .github/workflows/test19.yml:15:9:21:6 | Uses Step: modified_files | .github/workflows/test19.yml:25:18:25:67 | steps.modified_files.outputs.files_modified | Unprivileged code injection in $@, which may lead to cache poisoning. | .github/workflows/test19.yml:25:18:25:67 | steps.modified_files.outputs.files_modified | ${{ steps.modified_files.outputs.files_modified }} | -| .github/workflows/test19.yml:28:20:28:69 | steps.modified_files.outputs.files_modified | .github/workflows/test19.yml:15:9:21:6 | Uses Step: modified_files | .github/workflows/test19.yml:28:20:28:69 | steps.modified_files.outputs.files_modified | Unprivileged code injection in $@, which may lead to cache poisoning. | .github/workflows/test19.yml:28:20:28:69 | steps.modified_files.outputs.files_modified | ${{ steps.modified_files.outputs.files_modified }} | -| .github/workflows/test19.yml:31:20:31:66 | steps.modified_files.outputs.files_added | .github/workflows/test19.yml:15:9:21:6 | Uses Step: modified_files | .github/workflows/test19.yml:31:20:31:66 | steps.modified_files.outputs.files_added | Unprivileged code injection in $@, which may lead to cache poisoning. | .github/workflows/test19.yml:31:20:31:66 | steps.modified_files.outputs.files_added | ${{ steps.modified_files.outputs.files_added }} | -| .github/workflows/test19.yml:34:20:34:68 | steps.modified_files.outputs.files_removed | .github/workflows/test19.yml:15:9:21:6 | Uses Step: modified_files | .github/workflows/test19.yml:34:20:34:68 | steps.modified_files.outputs.files_removed | Unprivileged code injection in $@, which may lead to cache poisoning. | .github/workflows/test19.yml:34:20:34:68 | steps.modified_files.outputs.files_removed | ${{ steps.modified_files.outputs.files_removed }} | diff --git a/ql/test/query-tests/Security/CWE-349/CachePoisoningByCodeInjection.qlref b/ql/test/query-tests/Security/CWE-349/CachePoisoningByCodeInjection.qlref deleted file mode 100644 index cd1a90049a6..00000000000 --- a/ql/test/query-tests/Security/CWE-349/CachePoisoningByCodeInjection.qlref +++ /dev/null @@ -1,2 +0,0 @@ -Security/CWE-349/CachePoisoningByCodeInjection.ql - diff --git a/ql/test/query-tests/Security/CWE-349/CachePoisoningViaCodeInjection.expected b/ql/test/query-tests/Security/CWE-349/CachePoisoningViaCodeInjection.expected new file mode 100644 index 00000000000..d9f659cbcc3 --- /dev/null +++ b/ql/test/query-tests/Security/CWE-349/CachePoisoningViaCodeInjection.expected @@ -0,0 +1,11 @@ +edges +| .github/workflows/code_injection2.yml:12:9:16:6 | Uses Step: modified_files | .github/workflows/code_injection2.yml:16:21:16:70 | steps.modified_files.outputs.files_modified | provenance | | +nodes +| .github/workflows/code_injection1.yml:11:17:11:48 | github.event.comment.body | semmle.label | github.event.comment.body | +| .github/workflows/code_injection2.yml:12:9:16:6 | Uses Step: modified_files | semmle.label | Uses Step: modified_files | +| .github/workflows/code_injection2.yml:16:21:16:70 | steps.modified_files.outputs.files_modified | semmle.label | steps.modified_files.outputs.files_modified | +| .github/workflows/neg_code_injection1.yml:11:17:11:48 | github.event.comment.body | semmle.label | github.event.comment.body | +subpaths +#select +| .github/workflows/code_injection1.yml:11:17:11:48 | github.event.comment.body | .github/workflows/code_injection1.yml:11:17:11:48 | github.event.comment.body | .github/workflows/code_injection1.yml:11:17:11:48 | github.event.comment.body | Unprivileged code injection in $@, which may lead to cache poisoning. | .github/workflows/code_injection1.yml:11:17:11:48 | github.event.comment.body | ${{ github.event.comment.body }} | +| .github/workflows/code_injection2.yml:16:21:16:70 | steps.modified_files.outputs.files_modified | .github/workflows/code_injection2.yml:12:9:16:6 | Uses Step: modified_files | .github/workflows/code_injection2.yml:16:21:16:70 | steps.modified_files.outputs.files_modified | Unprivileged code injection in $@, which may lead to cache poisoning. | .github/workflows/code_injection2.yml:16:21:16:70 | steps.modified_files.outputs.files_modified | ${{ steps.modified_files.outputs.files_modified }} | diff --git a/ql/test/query-tests/Security/CWE-349/CachePoisoningViaCodeInjection.qlref b/ql/test/query-tests/Security/CWE-349/CachePoisoningViaCodeInjection.qlref new file mode 100644 index 00000000000..8ac48aad93e --- /dev/null +++ b/ql/test/query-tests/Security/CWE-349/CachePoisoningViaCodeInjection.qlref @@ -0,0 +1,2 @@ +Security/CWE-349/CachePoisoningViaCodeInjection.ql + diff --git a/ql/test/query-tests/Security/CWE-349/CachePoisoningViaDirectCache.expected b/ql/test/query-tests/Security/CWE-349/CachePoisoningViaDirectCache.expected new file mode 100644 index 00000000000..8bd69d8f245 --- /dev/null +++ b/ql/test/query-tests/Security/CWE-349/CachePoisoningViaDirectCache.expected @@ -0,0 +1,48 @@ +edges +| .github/workflows/code_injection2.yml:12:9:16:6 | Uses Step: modified_files | .github/workflows/code_injection2.yml:16:9:16:71 | Run Step | +| .github/workflows/direct_cache1.yml:10:9:13:6 | Uses Step: comment-branch | .github/workflows/direct_cache1.yml:13:9:18:6 | Uses Step | +| .github/workflows/direct_cache1.yml:13:9:18:6 | Uses Step | .github/workflows/direct_cache1.yml:18:9:22:6 | Uses Step | +| .github/workflows/direct_cache1.yml:18:9:22:6 | Uses Step | .github/workflows/direct_cache1.yml:22:9:23:21 | Run Step | +| .github/workflows/direct_cache2.yml:11:9:14:6 | Uses Step | .github/workflows/direct_cache2.yml:14:9:18:6 | Uses Step | +| .github/workflows/direct_cache2.yml:14:9:18:6 | Uses Step | .github/workflows/direct_cache2.yml:18:9:19:21 | Run Step | +| .github/workflows/direct_cache3.yml:11:9:14:6 | Uses Step: comment-branch | .github/workflows/direct_cache3.yml:14:9:19:6 | Uses Step | +| .github/workflows/direct_cache3.yml:14:9:19:6 | Uses Step | .github/workflows/direct_cache3.yml:19:9:23:6 | Uses Step | +| .github/workflows/direct_cache3.yml:19:9:23:6 | Uses Step | .github/workflows/direct_cache3.yml:23:9:24:21 | Run Step | +| .github/workflows/direct_cache4.yml:14:9:17:6 | Uses Step | .github/workflows/direct_cache4.yml:17:9:21:6 | Uses Step | +| .github/workflows/direct_cache4.yml:17:9:21:6 | Uses Step | .github/workflows/direct_cache4.yml:21:9:22:21 | Run Step | +| .github/workflows/direct_cache5.yml:14:9:17:6 | Uses Step | .github/workflows/direct_cache5.yml:17:9:21:6 | Uses Step | +| .github/workflows/direct_cache5.yml:17:9:21:6 | Uses Step | .github/workflows/direct_cache5.yml:21:9:22:21 | Run Step | +| .github/workflows/direct_cache6.yml:13:9:14:6 | Uses Step | .github/workflows/direct_cache6.yml:14:9:18:6 | Uses Step | +| .github/workflows/direct_cache6.yml:14:9:18:6 | Uses Step | .github/workflows/direct_cache6.yml:18:9:25:6 | Uses Step: cache-pip | +| .github/workflows/direct_cache6.yml:18:9:25:6 | Uses Step: cache-pip | .github/workflows/direct_cache6.yml:25:9:30:6 | Uses Step | +| .github/workflows/direct_cache6.yml:25:9:30:6 | Uses Step | .github/workflows/direct_cache6.yml:30:9:35:36 | Uses Step | +| .github/workflows/neg_direct_cache1.yml:14:9:17:6 | Uses Step | .github/workflows/neg_direct_cache1.yml:17:9:21:6 | Uses Step | +| .github/workflows/neg_direct_cache1.yml:17:9:21:6 | Uses Step | .github/workflows/neg_direct_cache1.yml:21:9:22:21 | Run Step | +| .github/workflows/neg_direct_cache2.yml:14:9:17:6 | Uses Step | .github/workflows/neg_direct_cache2.yml:17:9:21:6 | Uses Step | +| .github/workflows/neg_direct_cache2.yml:17:9:21:6 | Uses Step | .github/workflows/neg_direct_cache2.yml:21:9:22:21 | Run Step | +| .github/workflows/neg_direct_cache3.yml:13:9:14:6 | Uses Step | .github/workflows/neg_direct_cache3.yml:14:9:18:6 | Uses Step | +| .github/workflows/neg_direct_cache3.yml:14:9:18:6 | Uses Step | .github/workflows/neg_direct_cache3.yml:18:9:25:6 | Uses Step: cache-pip | +| .github/workflows/neg_direct_cache3.yml:18:9:25:6 | Uses Step: cache-pip | .github/workflows/neg_direct_cache3.yml:25:9:30:6 | Uses Step | +| .github/workflows/neg_direct_cache3.yml:25:9:30:6 | Uses Step | .github/workflows/neg_direct_cache3.yml:30:9:35:36 | Uses Step | +| .github/workflows/neg_poisonable_step1.yml:11:9:14:6 | Uses Step: comment-branch | .github/workflows/neg_poisonable_step1.yml:14:9:19:6 | Uses Step | +| .github/workflows/neg_poisonable_step1.yml:14:9:19:6 | Uses Step | .github/workflows/neg_poisonable_step1.yml:19:9:20:30 | Run Step | +| .github/workflows/neg_poisonable_step2.yml:13:9:16:6 | Uses Step | .github/workflows/neg_poisonable_step2.yml:16:9:17:54 | Run Step | +| .github/workflows/poisonable_step1.yml:10:9:12:6 | Uses Step: comment-branch | .github/workflows/poisonable_step1.yml:12:9:15:6 | Uses Step | +| .github/workflows/poisonable_step1.yml:12:9:15:6 | Uses Step | .github/workflows/poisonable_step1.yml:15:9:17:2 | Run Step | +| .github/workflows/poisonable_step1.yml:21:9:23:6 | Uses Step: comment-branch | .github/workflows/poisonable_step1.yml:23:9:26:6 | Uses Step | +| .github/workflows/poisonable_step1.yml:23:9:26:6 | Uses Step | .github/workflows/poisonable_step1.yml:26:9:28:2 | Uses Step | +| .github/workflows/poisonable_step1.yml:32:9:34:6 | Uses Step: comment-branch | .github/workflows/poisonable_step1.yml:34:9:37:6 | Uses Step | +| .github/workflows/poisonable_step1.yml:34:9:37:6 | Uses Step | .github/workflows/poisonable_step1.yml:37:9:37:75 | Run Step | +| .github/workflows/poisonable_step2.yml:15:9:20:6 | Uses Step | .github/workflows/poisonable_step2.yml:20:9:22:6 | Uses Step | +| .github/workflows/poisonable_step2.yml:20:9:22:6 | Uses Step | .github/workflows/poisonable_step2.yml:22:9:26:31 | Uses Step | +| .github/workflows/poisonable_step3.yml:13:7:19:4 | Uses Step | .github/workflows/poisonable_step3.yml:19:7:19:32 | Run Step | +| .github/workflows/poisonable_step4.yml:13:9:18:6 | Uses Step | .github/workflows/poisonable_step4.yml:18:9:18:19 | Run Step | +| .github/workflows/poisonable_step5.yml:17:9:22:6 | Uses Step | .github/workflows/poisonable_step5.yml:22:9:24:6 | Uses Step | +| .github/workflows/poisonable_step5.yml:22:9:24:6 | Uses Step | .github/workflows/poisonable_step5.yml:24:9:28:31 | Uses Step | +#select +| .github/workflows/direct_cache1.yml:18:9:22:6 | Uses Step | .github/workflows/direct_cache1.yml:13:9:18:6 | Uses Step | .github/workflows/direct_cache1.yml:18:9:22:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/direct_cache2.yml:14:9:18:6 | Uses Step | .github/workflows/direct_cache2.yml:11:9:14:6 | Uses Step | .github/workflows/direct_cache2.yml:14:9:18:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/direct_cache3.yml:19:9:23:6 | Uses Step | .github/workflows/direct_cache3.yml:14:9:19:6 | Uses Step | .github/workflows/direct_cache3.yml:19:9:23:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/direct_cache4.yml:17:9:21:6 | Uses Step | .github/workflows/direct_cache4.yml:14:9:17:6 | Uses Step | .github/workflows/direct_cache4.yml:17:9:21:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/direct_cache5.yml:17:9:21:6 | Uses Step | .github/workflows/direct_cache5.yml:14:9:17:6 | Uses Step | .github/workflows/direct_cache5.yml:17:9:21:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/direct_cache6.yml:18:9:25:6 | Uses Step: cache-pip | .github/workflows/direct_cache6.yml:25:9:30:6 | Uses Step | .github/workflows/direct_cache6.yml:18:9:25:6 | Uses Step: cache-pip | Potential cache poisoning in the context of the default branch due to downloading an untrusted artifact. | diff --git a/ql/test/query-tests/Security/CWE-349/CachePoisoningViaDirectCache.qlref b/ql/test/query-tests/Security/CWE-349/CachePoisoningViaDirectCache.qlref new file mode 100644 index 00000000000..9d1910990fc --- /dev/null +++ b/ql/test/query-tests/Security/CWE-349/CachePoisoningViaDirectCache.qlref @@ -0,0 +1,2 @@ +Security/CWE-349/CachePoisoningViaDirectCache.ql + diff --git a/ql/test/query-tests/Security/CWE-349/CachePoisoningViaPoisonableStep.expected b/ql/test/query-tests/Security/CWE-349/CachePoisoningViaPoisonableStep.expected new file mode 100644 index 00000000000..a515bd87334 --- /dev/null +++ b/ql/test/query-tests/Security/CWE-349/CachePoisoningViaPoisonableStep.expected @@ -0,0 +1,49 @@ +edges +| .github/workflows/code_injection2.yml:12:9:16:6 | Uses Step: modified_files | .github/workflows/code_injection2.yml:16:9:16:71 | Run Step | +| .github/workflows/direct_cache1.yml:10:9:13:6 | Uses Step: comment-branch | .github/workflows/direct_cache1.yml:13:9:18:6 | Uses Step | +| .github/workflows/direct_cache1.yml:13:9:18:6 | Uses Step | .github/workflows/direct_cache1.yml:18:9:22:6 | Uses Step | +| .github/workflows/direct_cache1.yml:18:9:22:6 | Uses Step | .github/workflows/direct_cache1.yml:22:9:23:21 | Run Step | +| .github/workflows/direct_cache2.yml:11:9:14:6 | Uses Step | .github/workflows/direct_cache2.yml:14:9:18:6 | Uses Step | +| .github/workflows/direct_cache2.yml:14:9:18:6 | Uses Step | .github/workflows/direct_cache2.yml:18:9:19:21 | Run Step | +| .github/workflows/direct_cache3.yml:11:9:14:6 | Uses Step: comment-branch | .github/workflows/direct_cache3.yml:14:9:19:6 | Uses Step | +| .github/workflows/direct_cache3.yml:14:9:19:6 | Uses Step | .github/workflows/direct_cache3.yml:19:9:23:6 | Uses Step | +| .github/workflows/direct_cache3.yml:19:9:23:6 | Uses Step | .github/workflows/direct_cache3.yml:23:9:24:21 | Run Step | +| .github/workflows/direct_cache4.yml:14:9:17:6 | Uses Step | .github/workflows/direct_cache4.yml:17:9:21:6 | Uses Step | +| .github/workflows/direct_cache4.yml:17:9:21:6 | Uses Step | .github/workflows/direct_cache4.yml:21:9:22:21 | Run Step | +| .github/workflows/direct_cache5.yml:14:9:17:6 | Uses Step | .github/workflows/direct_cache5.yml:17:9:21:6 | Uses Step | +| .github/workflows/direct_cache5.yml:17:9:21:6 | Uses Step | .github/workflows/direct_cache5.yml:21:9:22:21 | Run Step | +| .github/workflows/direct_cache6.yml:13:9:14:6 | Uses Step | .github/workflows/direct_cache6.yml:14:9:18:6 | Uses Step | +| .github/workflows/direct_cache6.yml:14:9:18:6 | Uses Step | .github/workflows/direct_cache6.yml:18:9:25:6 | Uses Step: cache-pip | +| .github/workflows/direct_cache6.yml:18:9:25:6 | Uses Step: cache-pip | .github/workflows/direct_cache6.yml:25:9:30:6 | Uses Step | +| .github/workflows/direct_cache6.yml:25:9:30:6 | Uses Step | .github/workflows/direct_cache6.yml:30:9:35:36 | Uses Step | +| .github/workflows/neg_direct_cache1.yml:14:9:17:6 | Uses Step | .github/workflows/neg_direct_cache1.yml:17:9:21:6 | Uses Step | +| .github/workflows/neg_direct_cache1.yml:17:9:21:6 | Uses Step | .github/workflows/neg_direct_cache1.yml:21:9:22:21 | Run Step | +| .github/workflows/neg_direct_cache2.yml:14:9:17:6 | Uses Step | .github/workflows/neg_direct_cache2.yml:17:9:21:6 | Uses Step | +| .github/workflows/neg_direct_cache2.yml:17:9:21:6 | Uses Step | .github/workflows/neg_direct_cache2.yml:21:9:22:21 | Run Step | +| .github/workflows/neg_direct_cache3.yml:13:9:14:6 | Uses Step | .github/workflows/neg_direct_cache3.yml:14:9:18:6 | Uses Step | +| .github/workflows/neg_direct_cache3.yml:14:9:18:6 | Uses Step | .github/workflows/neg_direct_cache3.yml:18:9:25:6 | Uses Step: cache-pip | +| .github/workflows/neg_direct_cache3.yml:18:9:25:6 | Uses Step: cache-pip | .github/workflows/neg_direct_cache3.yml:25:9:30:6 | Uses Step | +| .github/workflows/neg_direct_cache3.yml:25:9:30:6 | Uses Step | .github/workflows/neg_direct_cache3.yml:30:9:35:36 | Uses Step | +| .github/workflows/neg_poisonable_step1.yml:11:9:14:6 | Uses Step: comment-branch | .github/workflows/neg_poisonable_step1.yml:14:9:19:6 | Uses Step | +| .github/workflows/neg_poisonable_step1.yml:14:9:19:6 | Uses Step | .github/workflows/neg_poisonable_step1.yml:19:9:20:30 | Run Step | +| .github/workflows/neg_poisonable_step2.yml:13:9:16:6 | Uses Step | .github/workflows/neg_poisonable_step2.yml:16:9:17:54 | Run Step | +| .github/workflows/poisonable_step1.yml:10:9:12:6 | Uses Step: comment-branch | .github/workflows/poisonable_step1.yml:12:9:15:6 | Uses Step | +| .github/workflows/poisonable_step1.yml:12:9:15:6 | Uses Step | .github/workflows/poisonable_step1.yml:15:9:17:2 | Run Step | +| .github/workflows/poisonable_step1.yml:21:9:23:6 | Uses Step: comment-branch | .github/workflows/poisonable_step1.yml:23:9:26:6 | Uses Step | +| .github/workflows/poisonable_step1.yml:23:9:26:6 | Uses Step | .github/workflows/poisonable_step1.yml:26:9:28:2 | Uses Step | +| .github/workflows/poisonable_step1.yml:32:9:34:6 | Uses Step: comment-branch | .github/workflows/poisonable_step1.yml:34:9:37:6 | Uses Step | +| .github/workflows/poisonable_step1.yml:34:9:37:6 | Uses Step | .github/workflows/poisonable_step1.yml:37:9:37:75 | Run Step | +| .github/workflows/poisonable_step2.yml:15:9:20:6 | Uses Step | .github/workflows/poisonable_step2.yml:20:9:22:6 | Uses Step | +| .github/workflows/poisonable_step2.yml:20:9:22:6 | Uses Step | .github/workflows/poisonable_step2.yml:22:9:26:31 | Uses Step | +| .github/workflows/poisonable_step3.yml:13:7:19:4 | Uses Step | .github/workflows/poisonable_step3.yml:19:7:19:32 | Run Step | +| .github/workflows/poisonable_step4.yml:13:9:18:6 | Uses Step | .github/workflows/poisonable_step4.yml:18:9:18:19 | Run Step | +| .github/workflows/poisonable_step5.yml:17:9:22:6 | Uses Step | .github/workflows/poisonable_step5.yml:22:9:24:6 | Uses Step | +| .github/workflows/poisonable_step5.yml:22:9:24:6 | Uses Step | .github/workflows/poisonable_step5.yml:24:9:28:31 | Uses Step | +#select +| .github/workflows/poisonable_step1.yml:15:9:17:2 | Run Step | .github/workflows/poisonable_step1.yml:12:9:15:6 | Uses Step | .github/workflows/poisonable_step1.yml:15:9:17:2 | Run Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/poisonable_step1.yml:26:9:28:2 | Uses Step | .github/workflows/poisonable_step1.yml:23:9:26:6 | Uses Step | .github/workflows/poisonable_step1.yml:26:9:28:2 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/poisonable_step1.yml:37:9:37:75 | Run Step | .github/workflows/poisonable_step1.yml:34:9:37:6 | Uses Step | .github/workflows/poisonable_step1.yml:37:9:37:75 | Run Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/poisonable_step2.yml:22:9:26:31 | Uses Step | .github/workflows/poisonable_step2.yml:15:9:20:6 | Uses Step | .github/workflows/poisonable_step2.yml:22:9:26:31 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/poisonable_step3.yml:19:7:19:32 | Run Step | .github/workflows/poisonable_step3.yml:13:7:19:4 | Uses Step | .github/workflows/poisonable_step3.yml:19:7:19:32 | Run Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/poisonable_step4.yml:18:9:18:19 | Run Step | .github/workflows/poisonable_step4.yml:13:9:18:6 | Uses Step | .github/workflows/poisonable_step4.yml:18:9:18:19 | Run Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | +| .github/workflows/poisonable_step5.yml:24:9:28:31 | Uses Step | .github/workflows/poisonable_step5.yml:17:9:22:6 | Uses Step | .github/workflows/poisonable_step5.yml:24:9:28:31 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. | diff --git a/ql/test/query-tests/Security/CWE-349/CachePoisoningViaPoisonableStep.qlref b/ql/test/query-tests/Security/CWE-349/CachePoisoningViaPoisonableStep.qlref new file mode 100644 index 00000000000..89db21d70f5 --- /dev/null +++ b/ql/test/query-tests/Security/CWE-349/CachePoisoningViaPoisonableStep.qlref @@ -0,0 +1,2 @@ +Security/CWE-349/CachePoisoningViaPoisonableStep.ql +