diff --git a/actions/ql/lib/change-notes/2025-01-20-bash.md b/actions/ql/lib/change-notes/2025-01-20-bash.md new file mode 100644 index 000000000000..fe380d757013 --- /dev/null +++ b/actions/ql/lib/change-notes/2025-01-20-bash.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Improved `untrustedGhCommandDataModel` regex for `gh pr view` and Bash taint analysis in GitHub Actions. \ No newline at end of file diff --git a/actions/ql/lib/codeql/actions/Bash.qll b/actions/ql/lib/codeql/actions/Bash.qll index 7f2d4aeef9c3..d6be3c8e2d06 100644 --- a/actions/ql/lib/codeql/actions/Bash.qll +++ b/actions/ql/lib/codeql/actions/Bash.qll @@ -695,6 +695,19 @@ module Bash { not varMatchesRegexTest(script, var2, alphaNumericRegex()) ) or + exists(string var2, string value2, string var3, string value3 | + // VAR2=$(cmd) + // VAR3=$VAR2 + // echo "FIELD=${VAR3:-default}" >> $GITHUB_ENV (field, file_write_value) + containsCmdSubstitution(value2, cmd) and + script.getAnAssignment(var2, value2) and + containsParameterExpansion(value3, var2, _, _) and + script.getAnAssignment(var3, value3) and + containsParameterExpansion(expr, var3, _, _) and + not varMatchesRegexTest(script, var2, alphaNumericRegex()) and + not varMatchesRegexTest(script, var3, alphaNumericRegex()) + ) + or // var reaches the file write directly // echo "FIELD=$(cmd)" >> $GITHUB_ENV (field, file_write_value) containsCmdSubstitution(expr, cmd) diff --git a/actions/ql/lib/ext/config/untrusted_gh_command.yml b/actions/ql/lib/ext/config/untrusted_gh_command.yml index c81c048e45eb..571cd2d97e66 100644 --- a/actions/ql/lib/ext/config/untrusted_gh_command.yml +++ b/actions/ql/lib/ext/config/untrusted_gh_command.yml @@ -7,26 +7,29 @@ extensions: # PULL REQUESTS # # HEAD_REF=$(gh pr view "${{ github.event.issue.number }}" --json headRefName -q '.headRefName') - - ["gh\\s+pr\\b.*\\bview\\b.*\\.headRefName.*", "branch,oneline"] + - ["gh\\s+pr\\b.*\\bview\\b.*\\bheadRefName\\b", "branch,oneline"] # TITLE=$(gh pr view $PR_NUMBER --json title --jq .title) - - ["gh\\s+pr\\b.*\\bview\\b.*\\.title.*", "title,oneline"] + # TITLE=$(gh pr view $PR_NUMBER --json "title") + - ["gh\\s+pr\\b.*\\bview\\b.*\\btitle\\b", "title,oneline"] # BODY=$(gh pr view $PR_NUMBER --json body --jq .body) - - ["gh\\s+pr\\b.*\\bview\\b.*\\.body.*", "text,multiline"] + - ["gh\\s+pr\\b.*\\bview\\b.*\\bbody\\b", "text,multiline"] # COMMENTS="$(gh pr view --repo ${{ github.repository }} "$PR_NUMBER" --json "body,comments" -q '.body, .comments[].body')" - - ["gh\\s+pr\\b.*\\bview\\b.*\\.comments.*", "text,multiline"] + - ["gh\\s+pr\\b.*\\bview\\b.*\\bcomments\\b", "text,multiline"] # CHANGED_FILES="$(gh pr view --repo ${{ github.repository }} ${{ needs.check-comment.outputs.pull_number }} --json files --jq '.files.[].path')" - - ["gh\\s+pr\\b.*\\bview\\b.*\\.files.*", "filename,multiline"] + - ["gh\\s+pr\\b.*\\bview\\b.*\\bfiles\\b", "filename,multiline"] # AUTHOR=$(gh pr view ${ORI_PR} -R ${REPO} --json author -q '.author.login') - - ["gh\\s+pr\\b.*\\bview\\b.*\\.author.*", "username,oneline"] + - ["gh\\s+pr\\b.*\\bview\\b.*\\bauthor\\b", "username,oneline"] # # ISSUES # # TITLE=$(gh issue view "$ISSUE_NUMBER" --json title --jq '.title') - - ["gh\\s+issue\\b.*\\bview\\b.*\\.title.*", "title,oneline"] + # TITLE=$(gh issue view "$ISSUE_NUMBER" --json title,body) + # TITLE=$(gh issue view "$ISSUE_NUMBER" --json "title,body") + - ["gh\\s+issue\\b.*\\bview\\b.*\\btitle\\b", "title,oneline"] # BODY=$(gh issue view -R ${GITHUB_REPOSITORY} ${ORIGINAL_ISSUE_NUMBER} --json title,body,assignees --jq .body) - - ["gh\\s+issue\\b.*\\bview\\b.*\\.body.*", "text,multiline"] + - ["gh\\s+issue\\b.*\\bview\\b.*\\bbody\\b", "text,multiline"] # COMMENTS=$(gh issue view "$ISSUE_NUMBER" --json comments --jq '.comments[].body') - - ["gh\\s+issue\\b.*\\bview\\b.*\\.comments.*", "text,multiline"] + - ["gh\\s+issue\\b.*\\bview\\b.*\\bcomments\\b", "text,multiline"] # # API # diff --git a/actions/ql/test/query-tests/Security/CWE-094/.github/workflows/test19.yml b/actions/ql/test/query-tests/Security/CWE-094/.github/workflows/test19.yml index 804d55a7db28..2773c1044db1 100644 --- a/actions/ql/test/query-tests/Security/CWE-094/.github/workflows/test19.yml +++ b/actions/ql/test/query-tests/Security/CWE-094/.github/workflows/test19.yml @@ -106,7 +106,27 @@ jobs: COMMENTS=$(gh api /repos/test/test/pulls/${PR_NUMBER}/comments --jq '.[].body') echo "comments=$COMMENTS" >> "$GITHUB_OUTPUT" - run: echo "${{ steps.comments.outputs.comments}}" - + pulls3: + runs-on: ubuntu-latest + steps: + - id: title1 + run: | + DETAILS=$(gh pr view $PR_NUMBER --json "title,author,headRefName") + TITLE=$(echo $DETAILS | jq -r '.title') + echo "title=$TITLE" >> "$GITHUB_OUTPUT" + - run: echo "${{ steps.title1.outputs.title}}" + - id: title2 + run: | + TITLE=$(gh pr view $PR_NUMBER --json "title,author,headRefName") + TITLE=$(echo $TITLE | jq -r '.title') + echo "title=$TITLE" >> "$GITHUB_OUTPUT" + - run: echo "${{ steps.title2.outputs.title}}" + - id: title3 + run: | + TITLE=$(gh issue view "$ISSUE_NUMBER" --json title,author) + TITLE=$(echo $TITLE | jq -r '.title') + echo "title=$TITLE" >> "$GITHUB_OUTPUT" + - run: echo "${{ steps.title3.outputs.title}}" diff --git a/actions/ql/test/query-tests/Security/CWE-094/CodeInjectionCritical.expected b/actions/ql/test/query-tests/Security/CWE-094/CodeInjectionCritical.expected index c2bd8a1bc62d..d44205e4fb92 100644 --- a/actions/ql/test/query-tests/Security/CWE-094/CodeInjectionCritical.expected +++ b/actions/ql/test/query-tests/Security/CWE-094/CodeInjectionCritical.expected @@ -128,10 +128,14 @@ edges | .github/workflows/test9.yml:12:9:20:6 | Uses Step: issue_body_parser_request | .github/workflows/test9.yml:10:17:10:70 | steps.issue_body_parser_request.outputs.payload | provenance | | | .github/workflows/test9.yml:12:9:20:6 | Uses Step: issue_body_parser_request | .github/workflows/test9.yml:20:20:20:73 | steps.issue_body_parser_request.outputs.payload | provenance | | | .github/workflows/test11.yml:19:7:21:4 | Job outputs node [pr_num] | .github/workflows/test11.yml:54:20:54:60 | needs.get-artifacts.outputs.pr_num | provenance | | +| .github/workflows/test11.yml:19:7:21:4 | Job outputs node [ref] | .github/workflows/test11.yml:55:20:55:57 | needs.get-artifacts.outputs.ref | provenance | | | .github/workflows/test11.yml:19:16:19:50 | steps.set-ref.outputs.pr_num | .github/workflows/test11.yml:19:7:21:4 | Job outputs node [pr_num] | provenance | | +| .github/workflows/test11.yml:20:13:20:44 | steps.set-ref.outputs.ref | .github/workflows/test11.yml:19:7:21:4 | Job outputs node [ref] | provenance | | | .github/workflows/test11.yml:22:9:30:6 | Uses Step | .github/workflows/test11.yml:32:14:44:44 | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_OUTPUT\necho "ref=$ref" >> $GITHUB_OUTPUT\n | provenance | Config | | .github/workflows/test11.yml:30:9:46:2 | Run Step: set-ref [pr_num] | .github/workflows/test11.yml:19:16:19:50 | steps.set-ref.outputs.pr_num | provenance | | +| .github/workflows/test11.yml:30:9:46:2 | Run Step: set-ref [ref] | .github/workflows/test11.yml:20:13:20:44 | steps.set-ref.outputs.ref | provenance | | | .github/workflows/test11.yml:32:14:44:44 | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_OUTPUT\necho "ref=$ref" >> $GITHUB_OUTPUT\n | .github/workflows/test11.yml:30:9:46:2 | Run Step: set-ref [pr_num] | provenance | | +| .github/workflows/test11.yml:32:14:44:44 | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_OUTPUT\necho "ref=$ref" >> $GITHUB_OUTPUT\n | .github/workflows/test11.yml:30:9:46:2 | Run Step: set-ref [ref] | provenance | | | .github/workflows/test14.yml:13:9:16:6 | Run Step: changed-files [files] | .github/workflows/test14.yml:16:21:16:60 | steps.changed-files.outputs.files | provenance | | | .github/workflows/test14.yml:14:14:15:117 | echo "files=$(git diff-tree --no-commit-id --name-only -r ${{ github.sha }} -- docs/)" >> "$GITHUB_OUTPUT"\n | .github/workflows/test14.yml:13:9:16:6 | Run Step: changed-files [files] | provenance | | | .github/workflows/test14.yml:23:9:27:6 | Run Step: changed-files [files] | .github/workflows/test14.yml:27:21:27:60 | steps.changed-files.outputs.files | provenance | | @@ -199,6 +203,12 @@ edges | .github/workflows/test19.yml:100:14:102:48 | BODY=$(gh api /repos/test/test/issues/${{PR_NUMBER}} --jq ".body")\necho "body=$BODY" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:99:9:103:6 | Run Step: body [body] | provenance | | | .github/workflows/test19.yml:104:9:108:6 | Run Step: comments [comments] | .github/workflows/test19.yml:108:21:108:57 | steps.comments.outputs.comments | provenance | | | .github/workflows/test19.yml:105:14:107:56 | COMMENTS=$(gh api /repos/test/test/pulls/${PR_NUMBER}/comments --jq '.[].body')\necho "comments=$COMMENTS" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:104:9:108:6 | Run Step: comments [comments] | provenance | | +| .github/workflows/test19.yml:112:9:117:6 | Run Step: title1 [title] | .github/workflows/test19.yml:117:21:117:52 | steps.title1.outputs.title | provenance | | +| .github/workflows/test19.yml:113:14:116:50 | DETAILS=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $DETAILS \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:112:9:117:6 | Run Step: title1 [title] | provenance | | +| .github/workflows/test19.yml:118:9:123:6 | Run Step: title2 [title] | .github/workflows/test19.yml:123:21:123:52 | steps.title2.outputs.title | provenance | | +| .github/workflows/test19.yml:119:14:122:50 | TITLE=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:118:9:123:6 | Run Step: title2 [title] | provenance | | +| .github/workflows/test19.yml:124:9:129:6 | Run Step: title3 [title] | .github/workflows/test19.yml:129:21:129:52 | steps.title3.outputs.title | provenance | | +| .github/workflows/test19.yml:125:14:128:50 | TITLE=$(gh issue view "$ISSUE_NUMBER" --json title,author)\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:124:9:129:6 | Run Step: title3 [title] | provenance | | | .github/workflows/test24.yml:8:9:17:6 | Uses Step: parse | .github/workflows/test24.yml:19:17:19:50 | steps.parse.outputs.payload | provenance | | | .github/workflows/test25.yml:9:9:12:6 | Uses Step: parse | .github/workflows/test25.yml:12:20:12:50 | steps.parse.outputs.data | provenance | | | .github/workflows/test25.yml:9:9:12:6 | Uses Step: parse | .github/workflows/test25.yml:13:20:13:58 | toJSON(steps.parse.outputs.data) | provenance | | @@ -495,11 +505,15 @@ nodes | .github/workflows/test10.yml:423:34:423:77 | github.event.workflow_run.head_branch | semmle.label | github.event.workflow_run.head_branch | | .github/workflows/test10.yml:518:34:518:77 | github.event.workflow_run.head_branch | semmle.label | github.event.workflow_run.head_branch | | .github/workflows/test11.yml:19:7:21:4 | Job outputs node [pr_num] | semmle.label | Job outputs node [pr_num] | +| .github/workflows/test11.yml:19:7:21:4 | Job outputs node [ref] | semmle.label | Job outputs node [ref] | | .github/workflows/test11.yml:19:16:19:50 | steps.set-ref.outputs.pr_num | semmle.label | steps.set-ref.outputs.pr_num | +| .github/workflows/test11.yml:20:13:20:44 | steps.set-ref.outputs.ref | semmle.label | steps.set-ref.outputs.ref | | .github/workflows/test11.yml:22:9:30:6 | Uses Step | semmle.label | Uses Step | | .github/workflows/test11.yml:30:9:46:2 | Run Step: set-ref [pr_num] | semmle.label | Run Step: set-ref [pr_num] | +| .github/workflows/test11.yml:30:9:46:2 | Run Step: set-ref [ref] | semmle.label | Run Step: set-ref [ref] | | .github/workflows/test11.yml:32:14:44:44 | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_OUTPUT\necho "ref=$ref" >> $GITHUB_OUTPUT\n | semmle.label | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_OUTPUT\necho "ref=$ref" >> $GITHUB_OUTPUT\n | | .github/workflows/test11.yml:54:20:54:60 | needs.get-artifacts.outputs.pr_num | semmle.label | needs.get-artifacts.outputs.pr_num | +| .github/workflows/test11.yml:55:20:55:57 | needs.get-artifacts.outputs.ref | semmle.label | needs.get-artifacts.outputs.ref | | .github/workflows/test12.yml:10:21:10:67 | github.event.pull_request.title \|\| "foo" | semmle.label | github.event.pull_request.title \|\| "foo" | | .github/workflows/test13.yml:10:21:10:57 | github.event.changes.body.from | semmle.label | github.event.changes.body.from | | .github/workflows/test13.yml:11:21:11:58 | github.event.changes.title.from | semmle.label | github.event.changes.title.from | @@ -606,6 +620,15 @@ nodes | .github/workflows/test19.yml:104:9:108:6 | Run Step: comments [comments] | semmle.label | Run Step: comments [comments] | | .github/workflows/test19.yml:105:14:107:56 | COMMENTS=$(gh api /repos/test/test/pulls/${PR_NUMBER}/comments --jq '.[].body')\necho "comments=$COMMENTS" >> "$GITHUB_OUTPUT"\n | semmle.label | COMMENTS=$(gh api /repos/test/test/pulls/${PR_NUMBER}/comments --jq '.[].body')\necho "comments=$COMMENTS" >> "$GITHUB_OUTPUT"\n | | .github/workflows/test19.yml:108:21:108:57 | steps.comments.outputs.comments | semmle.label | steps.comments.outputs.comments | +| .github/workflows/test19.yml:112:9:117:6 | Run Step: title1 [title] | semmle.label | Run Step: title1 [title] | +| .github/workflows/test19.yml:113:14:116:50 | DETAILS=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $DETAILS \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | semmle.label | DETAILS=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $DETAILS \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | +| .github/workflows/test19.yml:117:21:117:52 | steps.title1.outputs.title | semmle.label | steps.title1.outputs.title | +| .github/workflows/test19.yml:118:9:123:6 | Run Step: title2 [title] | semmle.label | Run Step: title2 [title] | +| .github/workflows/test19.yml:119:14:122:50 | TITLE=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | semmle.label | TITLE=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | +| .github/workflows/test19.yml:123:21:123:52 | steps.title2.outputs.title | semmle.label | steps.title2.outputs.title | +| .github/workflows/test19.yml:124:9:129:6 | Run Step: title3 [title] | semmle.label | Run Step: title3 [title] | +| .github/workflows/test19.yml:125:14:128:50 | TITLE=$(gh issue view "$ISSUE_NUMBER" --json title,author)\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | semmle.label | TITLE=$(gh issue view "$ISSUE_NUMBER" --json title,author)\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | +| .github/workflows/test19.yml:129:21:129:52 | steps.title3.outputs.title | semmle.label | steps.title3.outputs.title | | .github/workflows/test21.yml:22:35:22:73 | github.event.head_commit.message | semmle.label | github.event.head_commit.message | | .github/workflows/test21.yml:23:36:23:74 | github.event.head_commit.message | semmle.label | github.event.head_commit.message | | .github/workflows/test21.yml:24:50:24:88 | github.event.head_commit.message | semmle.label | github.event.head_commit.message | @@ -767,6 +790,7 @@ subpaths | .github/workflows/test9.yml:31:42:31:99 | fromJson(needs.parse-issue.outputs.payload).version | .github/workflows/test9.yml:12:9:20:6 | Uses Step: issue_body_parser_request | .github/workflows/test9.yml:31:42:31:99 | fromJson(needs.parse-issue.outputs.payload).version | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test9.yml:31:42:31:99 | fromJson(needs.parse-issue.outputs.payload).version | ${{ fromJson(needs.parse-issue.outputs.payload).version }} | .github/workflows/test9.yml:4:3:4:15 | issue_comment | issue_comment | | .github/workflows/test9.yml:39:42:39:72 | github.event.issue.title | .github/workflows/test9.yml:39:42:39:72 | github.event.issue.title | .github/workflows/test9.yml:39:42:39:72 | github.event.issue.title | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test9.yml:39:42:39:72 | github.event.issue.title | ${{ github.event.issue.title }} | .github/workflows/test9.yml:4:3:4:15 | issue_comment | issue_comment | | .github/workflows/test11.yml:54:20:54:60 | needs.get-artifacts.outputs.pr_num | .github/workflows/test11.yml:22:9:30:6 | Uses Step | .github/workflows/test11.yml:54:20:54:60 | needs.get-artifacts.outputs.pr_num | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test11.yml:54:20:54:60 | needs.get-artifacts.outputs.pr_num | ${{ needs.get-artifacts.outputs.pr_num }} | .github/workflows/test11.yml:4:3:4:14 | workflow_run | workflow_run | +| .github/workflows/test11.yml:55:20:55:57 | needs.get-artifacts.outputs.ref | .github/workflows/test11.yml:22:9:30:6 | Uses Step | .github/workflows/test11.yml:55:20:55:57 | needs.get-artifacts.outputs.ref | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test11.yml:55:20:55:57 | needs.get-artifacts.outputs.ref | ${{ needs.get-artifacts.outputs.ref }} | .github/workflows/test11.yml:4:3:4:14 | workflow_run | workflow_run | | .github/workflows/test12.yml:10:21:10:67 | github.event.pull_request.title \|\| "foo" | .github/workflows/test12.yml:10:21:10:67 | github.event.pull_request.title \|\| "foo" | .github/workflows/test12.yml:10:21:10:67 | github.event.pull_request.title \|\| "foo" | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test12.yml:10:21:10:67 | github.event.pull_request.title \|\| "foo" | ${{ github.event.pull_request.title \|\| "foo" }} | .github/workflows/test12.yml:4:3:4:21 | pull_request_target | pull_request_target | | .github/workflows/test13.yml:10:21:10:57 | github.event.changes.body.from | .github/workflows/test13.yml:10:21:10:57 | github.event.changes.body.from | .github/workflows/test13.yml:10:21:10:57 | github.event.changes.body.from | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test13.yml:10:21:10:57 | github.event.changes.body.from | ${{ github.event.changes.body.from }} | .github/workflows/test13.yml:4:3:4:21 | pull_request_target | pull_request_target | | .github/workflows/test13.yml:11:21:11:58 | github.event.changes.title.from | .github/workflows/test13.yml:11:21:11:58 | github.event.changes.title.from | .github/workflows/test13.yml:11:21:11:58 | github.event.changes.title.from | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test13.yml:11:21:11:58 | github.event.changes.title.from | ${{ github.event.changes.title.from }} | .github/workflows/test13.yml:4:3:4:21 | pull_request_target | pull_request_target | @@ -807,6 +831,9 @@ subpaths | .github/workflows/test19.yml:98:21:98:51 | steps.title.outputs.title | .github/workflows/test19.yml:95:14:97:50 | TITLE=$(gh api /repos/test/test/issues/${{PR_NUMBER}} --jq ".title")\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:98:21:98:51 | steps.title.outputs.title | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test19.yml:98:21:98:51 | steps.title.outputs.title | ${{ steps.title.outputs.title}} | .github/workflows/test19.yml:4:3:4:21 | pull_request_target | pull_request_target | | .github/workflows/test19.yml:103:21:103:49 | steps.body.outputs.body | .github/workflows/test19.yml:100:14:102:48 | BODY=$(gh api /repos/test/test/issues/${{PR_NUMBER}} --jq ".body")\necho "body=$BODY" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:103:21:103:49 | steps.body.outputs.body | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test19.yml:103:21:103:49 | steps.body.outputs.body | ${{ steps.body.outputs.body}} | .github/workflows/test19.yml:4:3:4:21 | pull_request_target | pull_request_target | | .github/workflows/test19.yml:108:21:108:57 | steps.comments.outputs.comments | .github/workflows/test19.yml:105:14:107:56 | COMMENTS=$(gh api /repos/test/test/pulls/${PR_NUMBER}/comments --jq '.[].body')\necho "comments=$COMMENTS" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:108:21:108:57 | steps.comments.outputs.comments | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test19.yml:108:21:108:57 | steps.comments.outputs.comments | ${{ steps.comments.outputs.comments}} | .github/workflows/test19.yml:4:3:4:21 | pull_request_target | pull_request_target | +| .github/workflows/test19.yml:117:21:117:52 | steps.title1.outputs.title | .github/workflows/test19.yml:113:14:116:50 | DETAILS=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $DETAILS \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:117:21:117:52 | steps.title1.outputs.title | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test19.yml:117:21:117:52 | steps.title1.outputs.title | ${{ steps.title1.outputs.title}} | .github/workflows/test19.yml:4:3:4:21 | pull_request_target | pull_request_target | +| .github/workflows/test19.yml:123:21:123:52 | steps.title2.outputs.title | .github/workflows/test19.yml:119:14:122:50 | TITLE=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:123:21:123:52 | steps.title2.outputs.title | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test19.yml:123:21:123:52 | steps.title2.outputs.title | ${{ steps.title2.outputs.title}} | .github/workflows/test19.yml:4:3:4:21 | pull_request_target | pull_request_target | +| .github/workflows/test19.yml:129:21:129:52 | steps.title3.outputs.title | .github/workflows/test19.yml:125:14:128:50 | TITLE=$(gh issue view "$ISSUE_NUMBER" --json title,author)\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:129:21:129:52 | steps.title3.outputs.title | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test19.yml:129:21:129:52 | steps.title3.outputs.title | ${{ steps.title3.outputs.title}} | .github/workflows/test19.yml:4:3:4:21 | pull_request_target | pull_request_target | | .github/workflows/test24.yml:19:17:19:50 | steps.parse.outputs.payload | .github/workflows/test24.yml:8:9:17:6 | Uses Step: parse | .github/workflows/test24.yml:19:17:19:50 | steps.parse.outputs.payload | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test24.yml:19:17:19:50 | steps.parse.outputs.payload | ${{ steps.parse.outputs.payload }} | .github/workflows/test24.yml:2:3:2:8 | issues | issues | | .github/workflows/test25.yml:12:20:12:50 | steps.parse.outputs.data | .github/workflows/test25.yml:9:9:12:6 | Uses Step: parse | .github/workflows/test25.yml:12:20:12:50 | steps.parse.outputs.data | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test25.yml:12:20:12:50 | steps.parse.outputs.data | ${{ steps.parse.outputs.data }} | .github/workflows/test25.yml:3:5:3:10 | issues | issues | | .github/workflows/test25.yml:13:20:13:58 | toJSON(steps.parse.outputs.data) | .github/workflows/test25.yml:9:9:12:6 | Uses Step: parse | .github/workflows/test25.yml:13:20:13:58 | toJSON(steps.parse.outputs.data) | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test25.yml:13:20:13:58 | toJSON(steps.parse.outputs.data) | ${{ toJSON(steps.parse.outputs.data) }} | .github/workflows/test25.yml:3:5:3:10 | issues | issues | diff --git a/actions/ql/test/query-tests/Security/CWE-094/CodeInjectionMedium.expected b/actions/ql/test/query-tests/Security/CWE-094/CodeInjectionMedium.expected index b341ac198536..36b6019c10e9 100644 --- a/actions/ql/test/query-tests/Security/CWE-094/CodeInjectionMedium.expected +++ b/actions/ql/test/query-tests/Security/CWE-094/CodeInjectionMedium.expected @@ -128,10 +128,14 @@ edges | .github/workflows/test9.yml:12:9:20:6 | Uses Step: issue_body_parser_request | .github/workflows/test9.yml:10:17:10:70 | steps.issue_body_parser_request.outputs.payload | provenance | | | .github/workflows/test9.yml:12:9:20:6 | Uses Step: issue_body_parser_request | .github/workflows/test9.yml:20:20:20:73 | steps.issue_body_parser_request.outputs.payload | provenance | | | .github/workflows/test11.yml:19:7:21:4 | Job outputs node [pr_num] | .github/workflows/test11.yml:54:20:54:60 | needs.get-artifacts.outputs.pr_num | provenance | | +| .github/workflows/test11.yml:19:7:21:4 | Job outputs node [ref] | .github/workflows/test11.yml:55:20:55:57 | needs.get-artifacts.outputs.ref | provenance | | | .github/workflows/test11.yml:19:16:19:50 | steps.set-ref.outputs.pr_num | .github/workflows/test11.yml:19:7:21:4 | Job outputs node [pr_num] | provenance | | +| .github/workflows/test11.yml:20:13:20:44 | steps.set-ref.outputs.ref | .github/workflows/test11.yml:19:7:21:4 | Job outputs node [ref] | provenance | | | .github/workflows/test11.yml:22:9:30:6 | Uses Step | .github/workflows/test11.yml:32:14:44:44 | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_OUTPUT\necho "ref=$ref" >> $GITHUB_OUTPUT\n | provenance | Config | | .github/workflows/test11.yml:30:9:46:2 | Run Step: set-ref [pr_num] | .github/workflows/test11.yml:19:16:19:50 | steps.set-ref.outputs.pr_num | provenance | | +| .github/workflows/test11.yml:30:9:46:2 | Run Step: set-ref [ref] | .github/workflows/test11.yml:20:13:20:44 | steps.set-ref.outputs.ref | provenance | | | .github/workflows/test11.yml:32:14:44:44 | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_OUTPUT\necho "ref=$ref" >> $GITHUB_OUTPUT\n | .github/workflows/test11.yml:30:9:46:2 | Run Step: set-ref [pr_num] | provenance | | +| .github/workflows/test11.yml:32:14:44:44 | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_OUTPUT\necho "ref=$ref" >> $GITHUB_OUTPUT\n | .github/workflows/test11.yml:30:9:46:2 | Run Step: set-ref [ref] | provenance | | | .github/workflows/test14.yml:13:9:16:6 | Run Step: changed-files [files] | .github/workflows/test14.yml:16:21:16:60 | steps.changed-files.outputs.files | provenance | | | .github/workflows/test14.yml:14:14:15:117 | echo "files=$(git diff-tree --no-commit-id --name-only -r ${{ github.sha }} -- docs/)" >> "$GITHUB_OUTPUT"\n | .github/workflows/test14.yml:13:9:16:6 | Run Step: changed-files [files] | provenance | | | .github/workflows/test14.yml:23:9:27:6 | Run Step: changed-files [files] | .github/workflows/test14.yml:27:21:27:60 | steps.changed-files.outputs.files | provenance | | @@ -199,6 +203,12 @@ edges | .github/workflows/test19.yml:100:14:102:48 | BODY=$(gh api /repos/test/test/issues/${{PR_NUMBER}} --jq ".body")\necho "body=$BODY" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:99:9:103:6 | Run Step: body [body] | provenance | | | .github/workflows/test19.yml:104:9:108:6 | Run Step: comments [comments] | .github/workflows/test19.yml:108:21:108:57 | steps.comments.outputs.comments | provenance | | | .github/workflows/test19.yml:105:14:107:56 | COMMENTS=$(gh api /repos/test/test/pulls/${PR_NUMBER}/comments --jq '.[].body')\necho "comments=$COMMENTS" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:104:9:108:6 | Run Step: comments [comments] | provenance | | +| .github/workflows/test19.yml:112:9:117:6 | Run Step: title1 [title] | .github/workflows/test19.yml:117:21:117:52 | steps.title1.outputs.title | provenance | | +| .github/workflows/test19.yml:113:14:116:50 | DETAILS=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $DETAILS \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:112:9:117:6 | Run Step: title1 [title] | provenance | | +| .github/workflows/test19.yml:118:9:123:6 | Run Step: title2 [title] | .github/workflows/test19.yml:123:21:123:52 | steps.title2.outputs.title | provenance | | +| .github/workflows/test19.yml:119:14:122:50 | TITLE=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:118:9:123:6 | Run Step: title2 [title] | provenance | | +| .github/workflows/test19.yml:124:9:129:6 | Run Step: title3 [title] | .github/workflows/test19.yml:129:21:129:52 | steps.title3.outputs.title | provenance | | +| .github/workflows/test19.yml:125:14:128:50 | TITLE=$(gh issue view "$ISSUE_NUMBER" --json title,author)\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:124:9:129:6 | Run Step: title3 [title] | provenance | | | .github/workflows/test24.yml:8:9:17:6 | Uses Step: parse | .github/workflows/test24.yml:19:17:19:50 | steps.parse.outputs.payload | provenance | | | .github/workflows/test25.yml:9:9:12:6 | Uses Step: parse | .github/workflows/test25.yml:12:20:12:50 | steps.parse.outputs.data | provenance | | | .github/workflows/test25.yml:9:9:12:6 | Uses Step: parse | .github/workflows/test25.yml:13:20:13:58 | toJSON(steps.parse.outputs.data) | provenance | | @@ -495,11 +505,15 @@ nodes | .github/workflows/test10.yml:423:34:423:77 | github.event.workflow_run.head_branch | semmle.label | github.event.workflow_run.head_branch | | .github/workflows/test10.yml:518:34:518:77 | github.event.workflow_run.head_branch | semmle.label | github.event.workflow_run.head_branch | | .github/workflows/test11.yml:19:7:21:4 | Job outputs node [pr_num] | semmle.label | Job outputs node [pr_num] | +| .github/workflows/test11.yml:19:7:21:4 | Job outputs node [ref] | semmle.label | Job outputs node [ref] | | .github/workflows/test11.yml:19:16:19:50 | steps.set-ref.outputs.pr_num | semmle.label | steps.set-ref.outputs.pr_num | +| .github/workflows/test11.yml:20:13:20:44 | steps.set-ref.outputs.ref | semmle.label | steps.set-ref.outputs.ref | | .github/workflows/test11.yml:22:9:30:6 | Uses Step | semmle.label | Uses Step | | .github/workflows/test11.yml:30:9:46:2 | Run Step: set-ref [pr_num] | semmle.label | Run Step: set-ref [pr_num] | +| .github/workflows/test11.yml:30:9:46:2 | Run Step: set-ref [ref] | semmle.label | Run Step: set-ref [ref] | | .github/workflows/test11.yml:32:14:44:44 | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_OUTPUT\necho "ref=$ref" >> $GITHUB_OUTPUT\n | semmle.label | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_OUTPUT\necho "ref=$ref" >> $GITHUB_OUTPUT\n | | .github/workflows/test11.yml:54:20:54:60 | needs.get-artifacts.outputs.pr_num | semmle.label | needs.get-artifacts.outputs.pr_num | +| .github/workflows/test11.yml:55:20:55:57 | needs.get-artifacts.outputs.ref | semmle.label | needs.get-artifacts.outputs.ref | | .github/workflows/test12.yml:10:21:10:67 | github.event.pull_request.title \|\| "foo" | semmle.label | github.event.pull_request.title \|\| "foo" | | .github/workflows/test13.yml:10:21:10:57 | github.event.changes.body.from | semmle.label | github.event.changes.body.from | | .github/workflows/test13.yml:11:21:11:58 | github.event.changes.title.from | semmle.label | github.event.changes.title.from | @@ -606,6 +620,15 @@ nodes | .github/workflows/test19.yml:104:9:108:6 | Run Step: comments [comments] | semmle.label | Run Step: comments [comments] | | .github/workflows/test19.yml:105:14:107:56 | COMMENTS=$(gh api /repos/test/test/pulls/${PR_NUMBER}/comments --jq '.[].body')\necho "comments=$COMMENTS" >> "$GITHUB_OUTPUT"\n | semmle.label | COMMENTS=$(gh api /repos/test/test/pulls/${PR_NUMBER}/comments --jq '.[].body')\necho "comments=$COMMENTS" >> "$GITHUB_OUTPUT"\n | | .github/workflows/test19.yml:108:21:108:57 | steps.comments.outputs.comments | semmle.label | steps.comments.outputs.comments | +| .github/workflows/test19.yml:112:9:117:6 | Run Step: title1 [title] | semmle.label | Run Step: title1 [title] | +| .github/workflows/test19.yml:113:14:116:50 | DETAILS=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $DETAILS \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | semmle.label | DETAILS=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $DETAILS \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | +| .github/workflows/test19.yml:117:21:117:52 | steps.title1.outputs.title | semmle.label | steps.title1.outputs.title | +| .github/workflows/test19.yml:118:9:123:6 | Run Step: title2 [title] | semmle.label | Run Step: title2 [title] | +| .github/workflows/test19.yml:119:14:122:50 | TITLE=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | semmle.label | TITLE=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | +| .github/workflows/test19.yml:123:21:123:52 | steps.title2.outputs.title | semmle.label | steps.title2.outputs.title | +| .github/workflows/test19.yml:124:9:129:6 | Run Step: title3 [title] | semmle.label | Run Step: title3 [title] | +| .github/workflows/test19.yml:125:14:128:50 | TITLE=$(gh issue view "$ISSUE_NUMBER" --json title,author)\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | semmle.label | TITLE=$(gh issue view "$ISSUE_NUMBER" --json title,author)\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | +| .github/workflows/test19.yml:129:21:129:52 | steps.title3.outputs.title | semmle.label | steps.title3.outputs.title | | .github/workflows/test21.yml:22:35:22:73 | github.event.head_commit.message | semmle.label | github.event.head_commit.message | | .github/workflows/test21.yml:23:36:23:74 | github.event.head_commit.message | semmle.label | github.event.head_commit.message | | .github/workflows/test21.yml:24:50:24:88 | github.event.head_commit.message | semmle.label | github.event.head_commit.message |