From 0f4f3c84c83fd48949782ef2b5520e95d6d4bed3 Mon Sep 17 00:00:00 2001 From: Jesse Houwing Date: Tue, 12 May 2026 12:43:33 +0200 Subject: [PATCH] Implements multi-version support for extenal actions and workfows --- actions/extractor/tools/autobuild-impl.ps1 | 2 + actions/extractor/tools/autobuild.sh | 2 + .../ql/lib/codeql/actions/MappingHelper.qll | 49 +++++++++++++++++++ .../dataflow/internal/DataFlowPrivate.qll | 41 +++++++++++++++- .../CWE-349/CachePoisoningViaDirectCache.ql | 3 +- .../LegacyOrg/LegacyAction/action.yml | 8 +++ .../fedcba987654/sub-action/action.yml | 13 +++++ .../TestAction/abc123def456/action.yml | 13 +++++ .../TestAction/def789abc012/action.yml | 13 +++++ .../.github/actions/external/mapping.yaml | 5 ++ .../.github/workflows/test.yml | 32 ++++++++++++ .../mapping-resolution.expected | 23 +++++++++ .../mapping-resolution/mapping-resolution.ql | 28 +++++++++++ .../TestOrg/CacheAction/sha123abc/action.yml | 10 ++++ .../.github/actions/external/mapping.yaml | 2 + .../.github/workflows/direct_cache7.yml | 19 +++++++ .../CachePoisoningViaDirectCache.expected | 5 ++ .../CachePoisoningViaPoisonableStep.expected | 4 ++ 18 files changed, 269 insertions(+), 3 deletions(-) create mode 100644 actions/ql/lib/codeql/actions/MappingHelper.qll create mode 100644 actions/ql/test/library-tests/mapping-resolution/.github/actions/external/LegacyOrg/LegacyAction/action.yml create mode 100644 actions/ql/test/library-tests/mapping-resolution/.github/actions/external/TestOrg/TestAction-Sub/fedcba987654/sub-action/action.yml create mode 100644 actions/ql/test/library-tests/mapping-resolution/.github/actions/external/TestOrg/TestAction/abc123def456/action.yml create mode 100644 actions/ql/test/library-tests/mapping-resolution/.github/actions/external/TestOrg/TestAction/def789abc012/action.yml create mode 100644 actions/ql/test/library-tests/mapping-resolution/.github/actions/external/mapping.yaml create mode 100644 actions/ql/test/library-tests/mapping-resolution/.github/workflows/test.yml create mode 100644 actions/ql/test/library-tests/mapping-resolution/mapping-resolution.expected create mode 100644 actions/ql/test/library-tests/mapping-resolution/mapping-resolution.ql create mode 100644 actions/ql/test/query-tests/Security/CWE-349/.github/actions/external/TestOrg/CacheAction/sha123abc/action.yml create mode 100644 actions/ql/test/query-tests/Security/CWE-349/.github/actions/external/mapping.yaml create mode 100644 actions/ql/test/query-tests/Security/CWE-349/.github/workflows/direct_cache7.yml diff --git a/actions/extractor/tools/autobuild-impl.ps1 b/actions/extractor/tools/autobuild-impl.ps1 index e232cd3cc545..d0231650aed4 100644 --- a/actions/extractor/tools/autobuild-impl.ps1 +++ b/actions/extractor/tools/autobuild-impl.ps1 @@ -8,6 +8,8 @@ $DefaultPathFilters = @( 'include:.github/workflows/*.yaml', 'include:.github/reusable_workflows/**/*.yml', 'include:.github/reusable_workflows/**/*.yaml', + 'include:.github/actions/external/mapping.yaml', + 'include:.github/workflows/external/mapping.yaml', 'include:**/action.yml', 'include:**/action.yaml' ) diff --git a/actions/extractor/tools/autobuild.sh b/actions/extractor/tools/autobuild.sh index f2cbb7ddfa7e..bda098945371 100755 --- a/actions/extractor/tools/autobuild.sh +++ b/actions/extractor/tools/autobuild.sh @@ -12,6 +12,8 @@ include:.github/workflows/*.yml include:.github/workflows/*.yaml include:.github/reusable_workflows/**/*.yml include:.github/reusable_workflows/**/*.yaml +include:.github/actions/external/mapping.yaml +include:.github/workflows/external/mapping.yaml include:**/action.yml include:**/action.yaml END diff --git a/actions/ql/lib/codeql/actions/MappingHelper.qll b/actions/ql/lib/codeql/actions/MappingHelper.qll new file mode 100644 index 000000000000..73cdb5ba5cad --- /dev/null +++ b/actions/ql/lib/codeql/actions/MappingHelper.qll @@ -0,0 +1,49 @@ +/** + * Provides predicates for resolving external action and workflow references + * through SHA-based mapping files. + */ + +private import codeql.actions.ast.internal.Yaml + +/** + * Holds if the external action mapping file maps `ownerRepo` at `ref` to `sha`. + * + * The mapping file is expected at `.github/actions/external/mapping.yaml` and has + * the following structure: + * ```yaml + * owner/repo: + * ref: sha + * ``` + * + * This enables SHA-based directory resolution for external composite actions + * stored in the `.github/actions/external/{owner}/{repo}/{sha}/` directory structure. + */ +predicate externalActionRefMapping(string ownerRepo, string ref, string sha) { + exists(YamlMapping mapping, YamlMapping refMap | + ( + mapping.getLocation().getFile().getRelativePath().matches("%/.github/actions/external/mapping.yaml") + or + mapping.getLocation().getFile().getRelativePath() = ".github/actions/external/mapping.yaml" + ) and + refMap = mapping.lookup(ownerRepo) and + sha = refMap.lookup(ref).(YamlScalar).getValue() + ) +} + +/** + * Holds if the external workflow mapping file maps `ownerRepo` at `ref` to `sha`. + * + * The mapping file is expected at `.github/workflows/external/mapping.yaml` and has + * the same structure as the action mapping file. + */ +predicate externalWorkflowRefMapping(string ownerRepo, string ref, string sha) { + exists(YamlMapping mapping, YamlMapping refMap | + ( + mapping.getLocation().getFile().getRelativePath().matches("%/.github/workflows/external/mapping.yaml") + or + mapping.getLocation().getFile().getRelativePath() = ".github/workflows/external/mapping.yaml" + ) and + refMap = mapping.lookup(ownerRepo) and + sha = refMap.lookup(ref).(YamlScalar).getValue() + ) +} diff --git a/actions/ql/lib/codeql/actions/dataflow/internal/DataFlowPrivate.qll b/actions/ql/lib/codeql/actions/dataflow/internal/DataFlowPrivate.qll index cf95292588c3..6c157fa3503e 100644 --- a/actions/ql/lib/codeql/actions/dataflow/internal/DataFlowPrivate.qll +++ b/actions/ql/lib/codeql/actions/dataflow/internal/DataFlowPrivate.qll @@ -8,6 +8,7 @@ private import DataFlowPublic private import codeql.actions.dataflow.ExternalFlow private import codeql.actions.dataflow.FlowSteps private import codeql.actions.dataflow.FlowSources +private import codeql.actions.MappingHelper class DataFlowSecondLevelScope = Unit; @@ -50,7 +51,7 @@ predicate isArgumentNode(ArgumentNode arg, DataFlowCall call, ArgumentPosition p } DataFlowCallable nodeGetEnclosingCallable(Node node) { - node = TExprNode(any(DataFlowExpr e | result = e.getScope())) + result = node.(ExprNode).getCfgNode().(DataFlowExpr).getScope() } DataFlowType getNodeType(Node node) { any() } @@ -80,6 +81,9 @@ class DataFlowCall instanceof Cfg::Node { string getName() { result = super.getAstNode().(Uses).getCallee() } + /** Gets the version/ref of the action or workflow being called. */ + string getVersion() { result = super.getAstNode().(Uses).getVersion() } + DataFlowCallable getEnclosingCallable() { result = super.getScope() } /** Gets a best-effort total ordering. */ @@ -119,7 +123,40 @@ class NormalReturn extends ReturnKind, TNormalReturn { } /** Gets a viable implementation of the target of the given `Call`. */ -DataFlowCallable viableCallable(DataFlowCall c) { c.getName() = result.getName() } +DataFlowCallable viableCallable(DataFlowCall c) { + // Direct name match (existing behavior for local actions and backward compatibility) + c.getName() = result.getName() + or + // SHA-based resolution via mapping.yaml for external composite actions. + // Resolves uses: owner/repo[/path]@ref to owner/repo/sha[/path] using the mapping file. + exists(string callee, string version, string ownerRepo, string sha | + callee = c.getName() and + version = c.getVersion() and + ownerRepo = callee.regexpCapture("([^/]+/[^/]+)(?:/.*)?", 1) and + externalActionRefMapping(ownerRepo, version, sha) + | + // With sub-path: e.g. actions/cache/restore@v4 -> actions/cache/{sha}/restore + exists(string subpath | + subpath = callee.regexpCapture("[^/]+/[^/]+/(.*)", 1) and + result.getName() = [ownerRepo + "/" + sha + "/" + subpath, "./" + ownerRepo + "/" + sha + "/" + subpath] + ) + or + // No sub-path: e.g. actions/cache@v4 -> actions/cache/{sha} + not callee.regexpMatch("[^/]+/[^/]+/.*") and + result.getName() = [ownerRepo + "/" + sha, "./" + ownerRepo + "/" + sha] + ) + or + // SHA-based resolution via mapping.yaml for external callable workflows. + // Resolves uses: owner/repo/path/to/workflow.yml@ref to owner/repo/sha/path/to/workflow.yml. + exists(string callee, string version, string ownerRepo, string sha, string workflowPath | + callee = c.getName() and + version = c.getVersion() and + ownerRepo = callee.regexpCapture("([^/]+/[^/]+)(?:/.*)?", 1) and + workflowPath = callee.regexpCapture("[^/]+/[^/]+/(.*)", 1) and + externalWorkflowRefMapping(ownerRepo, version, sha) and + result.getName() = [ownerRepo + "/" + sha + "/" + workflowPath, "./" + ownerRepo + "/" + sha + "/" + workflowPath] + ) +} /** * Gets a node that can read the value returned from `call` with return kind diff --git a/actions/ql/src/Security/CWE-349/CachePoisoningViaDirectCache.ql b/actions/ql/src/Security/CWE-349/CachePoisoningViaDirectCache.ql index 85a0f53df1dc..7f208ef19eb8 100644 --- a/actions/ql/src/Security/CWE-349/CachePoisoningViaDirectCache.ql +++ b/actions/ql/src/Security/CWE-349/CachePoisoningViaDirectCache.ql @@ -53,7 +53,8 @@ where ) 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) - job.getAStep() = step and + // Check both direct job steps and steps inside composite actions called from the job. + step.getEnclosingJob() = job and step instanceof CacheWritingStep and ( // we dont know what code can be controlled by the attacker diff --git a/actions/ql/test/library-tests/mapping-resolution/.github/actions/external/LegacyOrg/LegacyAction/action.yml b/actions/ql/test/library-tests/mapping-resolution/.github/actions/external/LegacyOrg/LegacyAction/action.yml new file mode 100644 index 000000000000..c008c993698b --- /dev/null +++ b/actions/ql/test/library-tests/mapping-resolution/.github/actions/external/LegacyOrg/LegacyAction/action.yml @@ -0,0 +1,8 @@ +name: Legacy Action (no SHA) +description: An external action stored without SHA directory, for backward compat testing + +runs: + using: composite + steps: + - shell: bash + run: echo "Legacy action without SHA-based resolution" diff --git a/actions/ql/test/library-tests/mapping-resolution/.github/actions/external/TestOrg/TestAction-Sub/fedcba987654/sub-action/action.yml b/actions/ql/test/library-tests/mapping-resolution/.github/actions/external/TestOrg/TestAction-Sub/fedcba987654/sub-action/action.yml new file mode 100644 index 000000000000..1325c9d37d18 --- /dev/null +++ b/actions/ql/test/library-tests/mapping-resolution/.github/actions/external/TestOrg/TestAction-Sub/fedcba987654/sub-action/action.yml @@ -0,0 +1,13 @@ +name: Test Sub-Path Action +description: A composite action at a sub-path for testing mapping resolution +inputs: + path: + description: Path to restore + required: true + +runs: + using: composite + steps: + - shell: bash + run: | + echo "Restoring ${{ inputs.path }}" diff --git a/actions/ql/test/library-tests/mapping-resolution/.github/actions/external/TestOrg/TestAction/abc123def456/action.yml b/actions/ql/test/library-tests/mapping-resolution/.github/actions/external/TestOrg/TestAction/abc123def456/action.yml new file mode 100644 index 000000000000..d16d4598ddb0 --- /dev/null +++ b/actions/ql/test/library-tests/mapping-resolution/.github/actions/external/TestOrg/TestAction/abc123def456/action.yml @@ -0,0 +1,13 @@ +name: Test Composite Action +description: A simple composite action for testing mapping resolution +inputs: + message: + description: A test message + required: true + +runs: + using: composite + steps: + - shell: bash + run: | + echo "${{ inputs.message }}" diff --git a/actions/ql/test/library-tests/mapping-resolution/.github/actions/external/TestOrg/TestAction/def789abc012/action.yml b/actions/ql/test/library-tests/mapping-resolution/.github/actions/external/TestOrg/TestAction/def789abc012/action.yml new file mode 100644 index 000000000000..3fb410b82c0e --- /dev/null +++ b/actions/ql/test/library-tests/mapping-resolution/.github/actions/external/TestOrg/TestAction/def789abc012/action.yml @@ -0,0 +1,13 @@ +name: Test Composite Action v2 +description: A v2 composite action for testing mapping resolution +inputs: + message: + description: A test message + required: true + +runs: + using: composite + steps: + - shell: bash + run: | + echo "v2: ${{ inputs.message }}" diff --git a/actions/ql/test/library-tests/mapping-resolution/.github/actions/external/mapping.yaml b/actions/ql/test/library-tests/mapping-resolution/.github/actions/external/mapping.yaml new file mode 100644 index 000000000000..cc6cef44f2da --- /dev/null +++ b/actions/ql/test/library-tests/mapping-resolution/.github/actions/external/mapping.yaml @@ -0,0 +1,5 @@ +TestOrg/TestAction: + v1: abc123def456 + v2: def789abc012 +TestOrg/TestAction-Sub: + main: fedcba987654 diff --git a/actions/ql/test/library-tests/mapping-resolution/.github/workflows/test.yml b/actions/ql/test/library-tests/mapping-resolution/.github/workflows/test.yml new file mode 100644 index 000000000000..d717f219f64a --- /dev/null +++ b/actions/ql/test/library-tests/mapping-resolution/.github/workflows/test.yml @@ -0,0 +1,32 @@ +name: Test Mapping Resolution + +on: + push: + +jobs: + test-simple: + runs-on: ubuntu-latest + steps: + - name: Call external action v1 + uses: TestOrg/TestAction@v1 + with: + message: "hello from v1" + + - name: Call external action v2 + uses: TestOrg/TestAction@v2 + with: + message: "hello from v2" + + test-subpath: + runs-on: ubuntu-latest + steps: + - name: Call sub-path action + uses: TestOrg/TestAction-Sub/sub-action@main + with: + path: "./my-cache" + + test-legacy: + runs-on: ubuntu-latest + steps: + - name: Call legacy action (no mapping.yaml entry) + uses: LegacyOrg/LegacyAction@v1 diff --git a/actions/ql/test/library-tests/mapping-resolution/mapping-resolution.expected b/actions/ql/test/library-tests/mapping-resolution/mapping-resolution.expected new file mode 100644 index 000000000000..83c89713f069 --- /dev/null +++ b/actions/ql/test/library-tests/mapping-resolution/mapping-resolution.expected @@ -0,0 +1,23 @@ +actionMappings +| TestOrg/TestAction | v1 | abc123def456 | +| TestOrg/TestAction | v2 | def789abc012 | +| TestOrg/TestAction-Sub | main | fedcba987654 | +compositeActions +| .github/actions/external/LegacyOrg/LegacyAction/action.yml:1:1:8:61 | name: L ... no SHA) | +| .github/actions/external/TestOrg/TestAction-Sub/fedcba987654/sub-action/action.yml:1:1:13:42 | name: T ... Action | +| .github/actions/external/TestOrg/TestAction/abc123def456/action.yml:1:1:13:35 | name: T ... Action | +| .github/actions/external/TestOrg/TestAction/def789abc012/action.yml:1:1:13:39 | name: T ... tion v2 | +calls +| .github/workflows/test.yml:10:9:15:6 | Uses Step | +| .github/workflows/test.yml:15:9:20:2 | Uses Step | +| .github/workflows/test.yml:23:9:28:2 | Uses Step | +| .github/workflows/test.yml:31:9:32:40 | Uses Step | +resolvedCalls +| .github/workflows/test.yml:10:9:15:6 | Uses Step | ./TestOrg/TestAction/abc123def456 | +| .github/workflows/test.yml:10:9:15:6 | Uses Step | TestOrg/TestAction/abc123def456 | +| .github/workflows/test.yml:15:9:20:2 | Uses Step | ./TestOrg/TestAction/def789abc012 | +| .github/workflows/test.yml:15:9:20:2 | Uses Step | TestOrg/TestAction/def789abc012 | +| .github/workflows/test.yml:23:9:28:2 | Uses Step | ./TestOrg/TestAction-Sub/fedcba987654/sub-action | +| .github/workflows/test.yml:23:9:28:2 | Uses Step | TestOrg/TestAction-Sub/fedcba987654/sub-action | +| .github/workflows/test.yml:31:9:32:40 | Uses Step | ./LegacyOrg/LegacyAction | +| .github/workflows/test.yml:31:9:32:40 | Uses Step | LegacyOrg/LegacyAction | diff --git a/actions/ql/test/library-tests/mapping-resolution/mapping-resolution.ql b/actions/ql/test/library-tests/mapping-resolution/mapping-resolution.ql new file mode 100644 index 000000000000..c397025116bc --- /dev/null +++ b/actions/ql/test/library-tests/mapping-resolution/mapping-resolution.ql @@ -0,0 +1,28 @@ +import codeql.actions.Ast +import codeql.actions.DataFlow +import codeql.actions.MappingHelper + +/** + * Lists all mapping entries found in mapping.yaml files. + */ +query predicate actionMappings(string ownerRepo, string ref, string sha) { + externalActionRefMapping(ownerRepo, ref, sha) +} + +/** + * Lists all composite actions discovered and their resolved paths. + */ +query predicate compositeActions(CompositeAction ca) { any() } + +/** + * Lists all calls (uses: steps) and their callee names. + */ +query predicate calls(DataFlow::CallNode c) { any() } + +/** + * Lists resolved call targets: for each call node, which callable does it resolve to. + * This exercises viableCallable through the public CallNode.getCalleeNode() API. + */ +query predicate resolvedCalls(DataFlow::CallNode c, string targetName) { + targetName = c.getCalleeNode().getName() +} diff --git a/actions/ql/test/query-tests/Security/CWE-349/.github/actions/external/TestOrg/CacheAction/sha123abc/action.yml b/actions/ql/test/query-tests/Security/CWE-349/.github/actions/external/TestOrg/CacheAction/sha123abc/action.yml new file mode 100644 index 000000000000..d45f5e55e1eb --- /dev/null +++ b/actions/ql/test/query-tests/Security/CWE-349/.github/actions/external/TestOrg/CacheAction/sha123abc/action.yml @@ -0,0 +1,10 @@ +name: Cache Setup Action +description: A composite action that wraps actions/cache for testing + +runs: + using: composite + steps: + - uses: actions/cache@v4 + with: + path: ./poison + key: poison-cache-key diff --git a/actions/ql/test/query-tests/Security/CWE-349/.github/actions/external/mapping.yaml b/actions/ql/test/query-tests/Security/CWE-349/.github/actions/external/mapping.yaml new file mode 100644 index 000000000000..d180e57e56ae --- /dev/null +++ b/actions/ql/test/query-tests/Security/CWE-349/.github/actions/external/mapping.yaml @@ -0,0 +1,2 @@ +TestOrg/CacheAction: + v1: sha123abc diff --git a/actions/ql/test/query-tests/Security/CWE-349/.github/workflows/direct_cache7.yml b/actions/ql/test/query-tests/Security/CWE-349/.github/workflows/direct_cache7.yml new file mode 100644 index 000000000000..698e1ad9ce6c --- /dev/null +++ b/actions/ql/test/query-tests/Security/CWE-349/.github/workflows/direct_cache7.yml @@ -0,0 +1,19 @@ +name: Cache Poisoning Via External Composite Action + +on: + pull_request_target: + branches: + - main + +permissions: read-all + +jobs: + poison-via-external: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.sha }} + - uses: TestOrg/CacheAction@v1 + - run: | + cat poison diff --git a/actions/ql/test/query-tests/Security/CWE-349/CachePoisoningViaDirectCache.expected b/actions/ql/test/query-tests/Security/CWE-349/CachePoisoningViaDirectCache.expected index 4cc8536b5943..3725cde15080 100644 --- a/actions/ql/test/query-tests/Security/CWE-349/CachePoisoningViaDirectCache.expected +++ b/actions/ql/test/query-tests/Security/CWE-349/CachePoisoningViaDirectCache.expected @@ -1,4 +1,5 @@ edges +| .github/actions/external/TestOrg/CacheAction/sha123abc/action.yml:7:5:10:28 | Uses Step | .github/workflows/direct_cache7.yml:18:9:19:21 | Run Step | | .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 | @@ -14,6 +15,9 @@ edges | .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:16:6 | Uses Step | .github/workflows/direct_cache6.yml:16:9:20:6 | Uses Step | | .github/workflows/direct_cache6.yml:16:9:20:6 | Uses Step | .github/workflows/direct_cache6.yml:20:9:26:46 | Uses Step: cache-pip | +| .github/workflows/direct_cache7.yml:14:9:17:6 | Uses Step | .github/workflows/direct_cache7.yml:17:9:18:6 | Uses Step | +| .github/workflows/direct_cache7.yml:17:9:18:6 | Uses Step | .github/actions/external/TestOrg/CacheAction/sha123abc/action.yml:7:5:10:28 | Uses Step | +| .github/workflows/direct_cache7.yml:17:9:18:6 | Uses Step | .github/workflows/direct_cache7.yml:18:9:19:21 | Run 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 | @@ -44,6 +48,7 @@ edges | .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/actions/external/TestOrg/CacheAction/sha123abc/action.yml:7:5:10:28 | Uses Step | .github/workflows/direct_cache7.yml:14:9:17:6 | Uses Step | .github/actions/external/TestOrg/CacheAction/sha123abc/action.yml:7:5:10:28 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. ($@). | .github/workflows/direct_cache7.yml:4:3:4:21 | pull_request_target | pull_request_target | | .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_cache1.yml:2:3:2:15 | issue_comment | issue_comment | | .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_cache2.yml:3:5:3:23 | pull_request_target | pull_request_target | | .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_cache3.yml:2:3:2:15 | issue_comment | issue_comment | diff --git a/actions/ql/test/query-tests/Security/CWE-349/CachePoisoningViaPoisonableStep.expected b/actions/ql/test/query-tests/Security/CWE-349/CachePoisoningViaPoisonableStep.expected index 6b1a3e873134..3d0bb731001e 100644 --- a/actions/ql/test/query-tests/Security/CWE-349/CachePoisoningViaPoisonableStep.expected +++ b/actions/ql/test/query-tests/Security/CWE-349/CachePoisoningViaPoisonableStep.expected @@ -1,4 +1,5 @@ edges +| .github/actions/external/TestOrg/CacheAction/sha123abc/action.yml:7:5:10:28 | Uses Step | .github/workflows/direct_cache7.yml:18:9:19:21 | Run Step | | .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 | @@ -14,6 +15,9 @@ edges | .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:16:6 | Uses Step | .github/workflows/direct_cache6.yml:16:9:20:6 | Uses Step | | .github/workflows/direct_cache6.yml:16:9:20:6 | Uses Step | .github/workflows/direct_cache6.yml:20:9:26:46 | Uses Step: cache-pip | +| .github/workflows/direct_cache7.yml:14:9:17:6 | Uses Step | .github/workflows/direct_cache7.yml:17:9:18:6 | Uses Step | +| .github/workflows/direct_cache7.yml:17:9:18:6 | Uses Step | .github/actions/external/TestOrg/CacheAction/sha123abc/action.yml:7:5:10:28 | Uses Step | +| .github/workflows/direct_cache7.yml:17:9:18:6 | Uses Step | .github/workflows/direct_cache7.yml:18:9:19:21 | Run 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 |