diff --git a/ql/lib/codeql/actions/dataflow/ExternalFlow.qll b/ql/lib/codeql/actions/dataflow/ExternalFlow.qll index 08f8b6b9363..c1c93221d1a 100644 --- a/ql/lib/codeql/actions/dataflow/ExternalFlow.qll +++ b/ql/lib/codeql/actions/dataflow/ExternalFlow.qll @@ -8,10 +8,9 @@ private import actions * - action: Fully-qualified action name (NWO) * - version: Either '*' or a specific SHA/Tag * - output arg: To node (prefixed with either `env.` or `output.`) - * - trigger: Triggering event under which this model introduces tainted data. Use `*` for any event. */ -predicate sourceModel(string action, string version, string output, string trigger, string kind) { - Extensions::sourceModel(action, version, output, trigger, kind) +predicate sourceModel(string action, string version, string output, string kind) { + Extensions::sourceModel(action, version, output, kind) } /** @@ -39,11 +38,9 @@ predicate sinkModel(string action, string version, string input, string kind) { Extensions::sinkModel(action, version, input, kind) } -predicate externallyDefinedSource( - DataFlow::Node source, string sourceType, string fieldName, string trigger -) { +predicate externallyDefinedSource(DataFlow::Node source, string sourceType, string fieldName) { exists(Uses uses, string action, string version, string kind | - sourceModel(action, version, fieldName, trigger, kind) and + sourceModel(action, version, fieldName, kind) and uses.getCallee() = action.toLowerCase() and ( if version.trim() = "*" diff --git a/ql/lib/codeql/actions/dataflow/FlowSources.qll b/ql/lib/codeql/actions/dataflow/FlowSources.qll index ab2466bc41b..699b5f6f6c3 100644 --- a/ql/lib/codeql/actions/dataflow/FlowSources.qll +++ b/ql/lib/codeql/actions/dataflow/FlowSources.qll @@ -18,8 +18,6 @@ abstract class RemoteFlowSource extends SourceNode { /** Gets a string that describes the type of this remote flow source. */ abstract string getSourceType(); - abstract string getATriggerEvent(); - override string getThreatModel() { result = "remote" } } @@ -122,33 +120,20 @@ private predicate isExternalUserControlledWorkflowRun(string context) { } private class EventSource extends RemoteFlowSource { - string trigger; - EventSource() { exists(Expression e, string context | this.asExpr() = e and context = e.getExpression() | - trigger = ["issues", "issue_comment"] and isExternalUserControlledIssue(context) - or - trigger = ["pull_request_target", "pull_request_review", "pull_request_review_comment"] and - isExternalUserControlledPullRequest(context) - or - trigger = ["pull_request_review"] and isExternalUserControlledReview(context) - or - trigger = ["pull_request_review_comment", "issue_comment", "discussion_comment"] and - isExternalUserControlledComment(context) - or - trigger = ["gollum"] and isExternalUserControlledGollum(context) - or - trigger = ["push"] and isExternalUserControlledCommit(context) - or - trigger = ["discussion", "discussion_comment"] and isExternalUserControlledDiscussion(context) - or - trigger = ["workflow_run"] and isExternalUserControlledWorkflowRun(context) + isExternalUserControlledIssue(context) or + isExternalUserControlledPullRequest(context) or + isExternalUserControlledReview(context) or + isExternalUserControlledComment(context) or + isExternalUserControlledGollum(context) or + isExternalUserControlledCommit(context) or + isExternalUserControlledDiscussion(context) or + isExternalUserControlledWorkflowRun(context) ) } override string getSourceType() { result = "User-controlled events" } - - override string getATriggerEvent() { result = trigger } } /** @@ -156,13 +141,10 @@ private class EventSource extends RemoteFlowSource { */ private class ExternallyDefinedSource extends RemoteFlowSource { string sourceType; - string trigger; - ExternallyDefinedSource() { externallyDefinedSource(this, sourceType, _, trigger) } + ExternallyDefinedSource() { externallyDefinedSource(this, sourceType, _) } override string getSourceType() { result = sourceType } - - override string getATriggerEvent() { result = trigger } } /** @@ -174,6 +156,4 @@ private class CompositeActionInputSource extends RemoteFlowSource { CompositeActionInputSource() { c.getAnInput() = this.asExpr() } override string getSourceType() { result = "Composite action input" } - - override string getATriggerEvent() { result = "*" } } diff --git a/ql/lib/codeql/actions/dataflow/internal/DataFlowPrivate.qll b/ql/lib/codeql/actions/dataflow/internal/DataFlowPrivate.qll index f1657717e04..11b8bf94bca 100644 --- a/ql/lib/codeql/actions/dataflow/internal/DataFlowPrivate.qll +++ b/ql/lib/codeql/actions/dataflow/internal/DataFlowPrivate.qll @@ -175,7 +175,7 @@ predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = */ predicate stepsCtxLocalStep(Node nodeFrom, Node nodeTo) { exists(Uses astFrom, StepsExpression astTo | - externallyDefinedSource(nodeFrom, _, "output." + astTo.getFieldName(), _) and + externallyDefinedSource(nodeFrom, _, "output." + astTo.getFieldName()) and astFrom = nodeFrom.asExpr() and astTo = nodeTo.asExpr() and astTo.getTarget() = astFrom @@ -192,7 +192,7 @@ predicate stepsCtxLocalStep(Node nodeFrom, Node nodeTo) { */ predicate needsCtxLocalStep(Node nodeFrom, Node nodeTo) { exists(Uses astFrom, NeedsExpression astTo | - externallyDefinedSource(nodeFrom, _, "output." + astTo.getFieldName(), _) and + externallyDefinedSource(nodeFrom, _, "output." + astTo.getFieldName()) and astFrom = nodeFrom.asExpr() and astTo = nodeTo.asExpr() and astTo.getTarget() = astFrom @@ -232,7 +232,7 @@ predicate envCtxLocalStep(Node nodeFrom, Node nodeTo) { astFrom = nodeFrom.asExpr() and astTo = nodeTo.asExpr() and ( - externallyDefinedSource(nodeFrom, _, "env." + astTo.getFieldName(), _) or + externallyDefinedSource(nodeFrom, _, "env." + astTo.getFieldName()) or astTo.getTarget() = astFrom ) ) diff --git a/ql/lib/codeql/actions/dataflow/internal/ExternalFlowExtensions.qll b/ql/lib/codeql/actions/dataflow/internal/ExternalFlowExtensions.qll index 93ec64b059e..89cf4de0261 100644 --- a/ql/lib/codeql/actions/dataflow/internal/ExternalFlowExtensions.qll +++ b/ql/lib/codeql/actions/dataflow/internal/ExternalFlowExtensions.qll @@ -5,9 +5,7 @@ /** * Holds if a source model exists for the given parameters. */ -extensible predicate sourceModel( - string action, string version, string output, string trigger, string kind -); +extensible predicate sourceModel(string action, string version, string output, string kind); /** * Holds if a summary model exists for the given parameters. diff --git a/ql/lib/ext/TEST-RW-MODELS.model.yml b/ql/lib/ext/TEST-RW-MODELS.model.yml index 44897ef3311..4ff387b1c5a 100644 --- a/ql/lib/ext/TEST-RW-MODELS.model.yml +++ b/ql/lib/ext/TEST-RW-MODELS.model.yml @@ -9,7 +9,7 @@ extensions: pack: githubsecuritylab/actions-all extensible: sourceModel data: - - ["octo-org/source-repo/.github/workflows/workflow.yml", "*", "output.workflow-output", "*", "Foo"] + - ["octo-org/source-repo/.github/workflows/workflow.yml", "*", "output.workflow-output", "Foo"] - addsTo: pack: githubsecuritylab/actions-all extensible: sinkModel diff --git a/ql/lib/ext/ahmadnassri_action-changed-files.model.yml b/ql/lib/ext/ahmadnassri_action-changed-files.model.yml index 34cb56a01ad..aabd5a3ce36 100644 --- a/ql/lib/ext/ahmadnassri_action-changed-files.model.yml +++ b/ql/lib/ext/ahmadnassri_action-changed-files.model.yml @@ -3,5 +3,5 @@ extensions: pack: githubsecuritylab/actions-all extensible: sourceModel data: - - ["ahmadnassri/action-changed-files", "*", "output.files", "pull_request_target", "PR changed files"] - - ["ahmadnassri/action-changed-files", "*", "output.json", "pull_request_target", "PR changed files"] + - ["ahmadnassri/action-changed-files", "*", "output.files", "PR changed files"] + - ["ahmadnassri/action-changed-files", "*", "output.json", "PR changed files"] diff --git a/ql/lib/ext/amannn_action-semantic-pull-request.model.yml b/ql/lib/ext/amannn_action-semantic-pull-request.model.yml index c530a3af9b3..638ff449735 100644 --- a/ql/lib/ext/amannn_action-semantic-pull-request.model.yml +++ b/ql/lib/ext/amannn_action-semantic-pull-request.model.yml @@ -3,4 +3,4 @@ extensions: pack: githubsecuritylab/actions-all extensible: sourceModel data: - - ["amannn/action-semantic-pull-request", "*", "output.error_message", "pull_request_target", "PR title"] + - ["amannn/action-semantic-pull-request", "*", "output.error_message", "PR title"] diff --git a/ql/lib/ext/cypress-io_github-action.model.yml b/ql/lib/ext/cypress-io_github-action.model.yml index 2fda092f20a..0aaa1b0722a 100644 --- a/ql/lib/ext/cypress-io_github-action.model.yml +++ b/ql/lib/ext/cypress-io_github-action.model.yml @@ -3,4 +3,4 @@ extensions: pack: githubsecuritylab/actions-all extensible: sourceModel data: - - ["cypress-io/github-action", "*", "env.GH_BRANCH", "pull_request_target", "PR branch"] + - ["cypress-io/github-action", "*", "env.GH_BRANCH", "PR branch"] diff --git a/ql/lib/ext/dawidd6_action-download-artifact.model.yml b/ql/lib/ext/dawidd6_action-download-artifact.model.yml index a8a54dbda29..3bc1dcc4759 100644 --- a/ql/lib/ext/dawidd6_action-download-artifact.model.yml +++ b/ql/lib/ext/dawidd6_action-download-artifact.model.yml @@ -3,4 +3,4 @@ extensions: pack: githubsecuritylab/actions-all extensible: sourceModel data: - - ["dawidd6/action-download-artifact", "*", "output.artifacts", "*", "Artifact details"] + - ["dawidd6/action-download-artifact", "*", "output.artifacts", "Artifact details"] diff --git a/ql/lib/ext/dorny_paths-filter.model.yml b/ql/lib/ext/dorny_paths-filter.model.yml index 6fefec9a4f8..41a9c337f49 100644 --- a/ql/lib/ext/dorny_paths-filter.model.yml +++ b/ql/lib/ext/dorny_paths-filter.model.yml @@ -3,4 +3,4 @@ extensions: pack: githubsecuritylab/actions-all extensible: sourceModel data: - - ["dorny/paths-filter", "*", "output.changes", "pull_request_target", "PR changed files"] + - ["dorny/paths-filter", "*", "output.changes", "PR changed files"] diff --git a/ql/lib/ext/franzdiebold_github-env-vars-action.model.yml b/ql/lib/ext/franzdiebold_github-env-vars-action.model.yml index ffde7dc6a91..b6c75a06e57 100644 --- a/ql/lib/ext/franzdiebold_github-env-vars-action.model.yml +++ b/ql/lib/ext/franzdiebold_github-env-vars-action.model.yml @@ -3,5 +3,5 @@ extensions: pack: githubsecuritylab/actions-all extensible: sourceModel data: - - ["franzdiebold/github-env-vars-action", "*", "output.CI_PR_DESCRIPTION", "pull_request_target", "PR body"] - - ["franzdiebold/github-env-vars-action", "*", "output.CI_PR_TITLE", "pull_request_target", "PR title"] + - ["franzdiebold/github-env-vars-action", "*", "output.CI_PR_DESCRIPTION", "PR body"] + - ["franzdiebold/github-env-vars-action", "*", "output.CI_PR_TITLE", "PR title"] diff --git a/ql/lib/ext/jitterbit_get-changed-files.model.yml b/ql/lib/ext/jitterbit_get-changed-files.model.yml index d7cbde25b88..2e5b0d42efd 100644 --- a/ql/lib/ext/jitterbit_get-changed-files.model.yml +++ b/ql/lib/ext/jitterbit_get-changed-files.model.yml @@ -3,10 +3,10 @@ extensions: pack: githubsecuritylab/actions-all extensible: sourceModel data: - - ["jitterbit/get-changed-files", "*", "output.all", "pull_request_target", "PR changed files"] - - ["jitterbit/get-changed-files", "*", "output.added", "pull_request_target", "PR changed files"] - - ["jitterbit/get-changed-files", "*", "output.modified", "pull_request_target", "PR changed files"] - - ["jitterbit/get-changed-files", "*", "output.removed", "pull_request_target", "PR changed files"] - - ["jitterbit/get-changed-files", "*", "output.renamed", "pull_request_target", "PR changed files"] - - ["jitterbit/get-changed-files", "*", "output.added_modified", "pull_request_target", "PR changed files"] - - ["jitterbit/get-changed-files", "*", "output.deleted", "pull_request_target", "PR changed files"] + - ["jitterbit/get-changed-files", "*", "output.all", "PR changed files"] + - ["jitterbit/get-changed-files", "*", "output.added", "PR changed files"] + - ["jitterbit/get-changed-files", "*", "output.modified", "PR changed files"] + - ["jitterbit/get-changed-files", "*", "output.removed", "PR changed files"] + - ["jitterbit/get-changed-files", "*", "output.renamed", "PR changed files"] + - ["jitterbit/get-changed-files", "*", "output.added_modified", "PR changed files"] + - ["jitterbit/get-changed-files", "*", "output.deleted", "PR changed files"] diff --git a/ql/lib/ext/khan_pull-request-comment-trigger.model.yml b/ql/lib/ext/khan_pull-request-comment-trigger.model.yml index b872bbe2ed0..18339bfa4e9 100644 --- a/ql/lib/ext/khan_pull-request-comment-trigger.model.yml +++ b/ql/lib/ext/khan_pull-request-comment-trigger.model.yml @@ -3,5 +3,5 @@ extensions: pack: githubsecuritylab/actions-all extensible: sourceModel data: - - ["khan/pull-request-comment-trigger", "*", "output.comment_body", "issue_comment", ""] - - ["khan/pull-request-comment-trigger", "*", "output.comment_body", "pull_request_comment", ""] + - ["khan/pull-request-comment-trigger", "*", "output.comment_body", "Comment body"] + - ["khan/pull-request-comment-trigger", "*", "output.comment_body", "Comment body"] diff --git a/ql/lib/ext/tj-actions_branch-names.model.yml b/ql/lib/ext/tj-actions_branch-names.model.yml index 1618eddf2d8..a7afc090a91 100644 --- a/ql/lib/ext/tj-actions_branch-names.model.yml +++ b/ql/lib/ext/tj-actions_branch-names.model.yml @@ -4,7 +4,7 @@ extensions: extensible: sourceModel data: # https://github.com/tj-actions/branch-names - - ["tj-actions/branch-names", "*", "output.current_branch", "pull_request_target", "PR current branch"] - - ["tj-actions/branch-names", "*", "output.head_ref_branch", "pull_request_target", "PR head branch"] - - ["tj-actions/branch-names", "*", "output.ref_branch", "pull_request_target", "Branch tirggering workflow run"] + - ["tj-actions/branch-names", "*", "output.current_branch", "PR current branch"] + - ["tj-actions/branch-names", "*", "output.head_ref_branch", "PR head branch"] + - ["tj-actions/branch-names", "*", "output.ref_branch", "Branch tirggering workflow run"] diff --git a/ql/lib/ext/tj-actions_changed-files.model.yml b/ql/lib/ext/tj-actions_changed-files.model.yml index 7c681d8a64b..7890668fa87 100644 --- a/ql/lib/ext/tj-actions_changed-files.model.yml +++ b/ql/lib/ext/tj-actions_changed-files.model.yml @@ -3,20 +3,20 @@ extensions: pack: githubsecuritylab/actions-all extensible: sourceModel data: - - ["tj-actions/changed-files", "*", "output.added_files", "pull_request_target", "PR changed files"] - - ["tj-actions/changed-files", "*", "output.copied_files", "pull_request_target", "PR changed files"] - - ["tj-actions/changed-files", "*", "output.deleted_files", "pull_request_target", "PR changed files"] - - ["tj-actions/changed-files", "*", "output.modified_files", "pull_request_target", "PR changed files"] - - ["tj-actions/changed-files", "*", "output.renamed_files", "pull_request_target", "PR changed files"] - - ["tj-actions/changed-files", "*", "output.all_old_new_renamed_files", "pull_request_target", "PR changed files"] - - ["tj-actions/changed-files", "*", "output.type_changed_files", "pull_request_target", "PR changed files"] - - ["tj-actions/changed-files", "*", "output.unmerged_files", "pull_request_target", "PR changed files"] - - ["tj-actions/changed-files", "*", "output.unknown_files", "pull_request_target", "PR changed files"] - - ["tj-actions/changed-files", "*", "output.all_changed_and_modified_files", "pull_request_target", "PR changed files"] - - ["tj-actions/changed-files", "*", "output.all_changed_files", "pull_request_target", "PR changed files"] - - ["tj-actions/changed-files", "*", "output.other_changed_files", "pull_request_target", "PR changed files"] - - ["tj-actions/changed-files", "*", "output.all_modified_files", "pull_request_target", "PR changed files"] - - ["tj-actions/changed-files", "*", "output.other_modified_files", "pull_request_target", "PR changed files"] - - ["tj-actions/changed-files", "*", "output.other_deleted_files", "pull_request_target", "PR changed files"] - - ["tj-actions/changed-files", "*", "output.modified_keys", "pull_request_target", "PR changed files"] - - ["tj-actions/changed-files", "*", "output.changed_keys", "pull_request_target", "PR changed files"] \ No newline at end of file + - ["tj-actions/changed-files", "*", "output.added_files", "PR changed files"] + - ["tj-actions/changed-files", "*", "output.copied_files", "PR changed files"] + - ["tj-actions/changed-files", "*", "output.deleted_files", "PR changed files"] + - ["tj-actions/changed-files", "*", "output.modified_files", "PR changed files"] + - ["tj-actions/changed-files", "*", "output.renamed_files", "PR changed files"] + - ["tj-actions/changed-files", "*", "output.all_old_new_renamed_files", "PR changed files"] + - ["tj-actions/changed-files", "*", "output.type_changed_files", "PR changed files"] + - ["tj-actions/changed-files", "*", "output.unmerged_files", "PR changed files"] + - ["tj-actions/changed-files", "*", "output.unknown_files", "PR changed files"] + - ["tj-actions/changed-files", "*", "output.all_changed_and_modified_files", "PR changed files"] + - ["tj-actions/changed-files", "*", "output.all_changed_files", "PR changed files"] + - ["tj-actions/changed-files", "*", "output.other_changed_files", "PR changed files"] + - ["tj-actions/changed-files", "*", "output.all_modified_files", "PR changed files"] + - ["tj-actions/changed-files", "*", "output.other_modified_files", "PR changed files"] + - ["tj-actions/changed-files", "*", "output.other_deleted_files", "PR changed files"] + - ["tj-actions/changed-files", "*", "output.modified_keys", "PR changed files"] + - ["tj-actions/changed-files", "*", "output.changed_keys", "PR changed files"] diff --git a/ql/lib/ext/tj-actions_verify-changed-files.model.yml b/ql/lib/ext/tj-actions_verify-changed-files.model.yml index 9b6649892af..1946b78f5fd 100644 --- a/ql/lib/ext/tj-actions_verify-changed-files.model.yml +++ b/ql/lib/ext/tj-actions_verify-changed-files.model.yml @@ -3,4 +3,4 @@ extensions: pack: githubsecuritylab/actions-all extensible: sourceModel data: - - ["tj-actions/verify-changed-files", "*", "output.changed-files", "pull_request_target", "PR changed files"] + - ["tj-actions/verify-changed-files", "*", "output.changed-files", "PR changed files"] diff --git a/ql/lib/ext/tzkhan_pr-update-action.model.yml b/ql/lib/ext/tzkhan_pr-update-action.model.yml index 6ce7dd68b3f..d4b083e14d2 100644 --- a/ql/lib/ext/tzkhan_pr-update-action.model.yml +++ b/ql/lib/ext/tzkhan_pr-update-action.model.yml @@ -3,4 +3,4 @@ extensions: pack: githubsecuritylab/actions-all extensible: sourceModel data: - - ["tzkhan/pr-update-action", "*", "output.headMatch", "pull_request_target", ""] + - ["tzkhan/pr-update-action", "*", "output.headMatch", ""] diff --git a/ql/lib/ext/xt0rted_slash-command-action.model.yml b/ql/lib/ext/xt0rted_slash-command-action.model.yml index 72df42535db..31a1eb5bde9 100644 --- a/ql/lib/ext/xt0rted_slash-command-action.model.yml +++ b/ql/lib/ext/xt0rted_slash-command-action.model.yml @@ -3,5 +3,5 @@ extensions: pack: githubsecuritylab/actions-all extensible: sourceModel data: - - ["xt0rted/slash-command-action", "*", "output.command-arguments", "issue_comment", ""] - - ["xt0rted/slash-command-action", "*", "output.command-arguments", "pull_request_comment", ""] + - ["xt0rted/slash-command-action", "*", "output.command-arguments", ""] + - ["xt0rted/slash-command-action", "*", "output.command-arguments", ""] diff --git a/ql/src/Security/CWE-078/PrivilegedCommandInjection.ql b/ql/src/Security/CWE-078/PrivilegedCommandInjection.ql index 6f66535e6a4..2f9a09f59c3 100644 --- a/ql/src/Security/CWE-078/PrivilegedCommandInjection.ql +++ b/ql/src/Security/CWE-078/PrivilegedCommandInjection.ql @@ -16,14 +16,16 @@ import actions import codeql.actions.security.CommandInjectionQuery import CommandInjectionFlow::PathGraph +predicate isSingleTriggerWorkflow(Workflow w, string trigger) { + w.getATriggerEvent() = trigger and + count(string t | w.getATriggerEvent() = t | t) = 1 +} + from CommandInjectionFlow::PathNode source, CommandInjectionFlow::PathNode sink, Workflow w where CommandInjectionFlow::flowPath(source, sink) and w = source.getNode().asExpr().getEnclosingWorkflow() and - ( - w instanceof ReusableWorkflow or - w.hasTriggerEvent(source.getNode().(RemoteFlowSource).getATriggerEvent()) - ) + not isSingleTriggerWorkflow(w, "pull_request") select sink.getNode(), source, sink, "Potential privileged command injection in $@, which may be controlled by an external user.", sink, sink.getNode().asExpr().(Expression).getRawExpression() diff --git a/ql/src/Security/CWE-094/PrivilegedCodeInjection.ql b/ql/src/Security/CWE-094/PrivilegedCodeInjection.ql index 69ab240616e..62030e32263 100644 --- a/ql/src/Security/CWE-094/PrivilegedCodeInjection.ql +++ b/ql/src/Security/CWE-094/PrivilegedCodeInjection.ql @@ -18,14 +18,16 @@ import actions import codeql.actions.security.CodeInjectionQuery import CodeInjectionFlow::PathGraph +predicate isSingleTriggerWorkflow(Workflow w, string trigger) { + w.getATriggerEvent() = trigger and + count(string t | w.getATriggerEvent() = t | t) = 1 +} + from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink, Workflow w where CodeInjectionFlow::flowPath(source, sink) and w = source.getNode().asExpr().getEnclosingWorkflow() and - ( - w instanceof ReusableWorkflow or - w.hasTriggerEvent(source.getNode().(RemoteFlowSource).getATriggerEvent()) - ) + not isSingleTriggerWorkflow(w, "pull_request") select sink.getNode(), source, sink, "Potential privileged code injection in $@, which may be controlled by an external user.", sink, sink.getNode().asExpr().(Expression).getRawExpression() diff --git a/ql/test/library-tests/test.expected b/ql/test/library-tests/test.expected index 5395fe82453..a8a0414dd9f 100644 --- a/ql/test/library-tests/test.expected +++ b/ql/test/library-tests/test.expected @@ -313,48 +313,46 @@ scopes | .github/workflows/expression_nodes.yml:1:1:21:47 | on: issue_comment | | .github/workflows/test.yml:1:1:40:53 | on: push | sources -| ahmadnassri/action-changed-files | * | output.files | pull_request_target | PR changed files | -| ahmadnassri/action-changed-files | * | output.json | pull_request_target | PR changed files | -| amannn/action-semantic-pull-request | * | output.error_message | pull_request_target | PR title | -| cypress-io/github-action | * | env.GH_BRANCH | pull_request_target | PR branch | -| dawidd6/action-download-artifact | * | output.artifacts | * | Artifact details | -| dorny/paths-filter | * | output.changes | pull_request_target | PR changed files | -| franzdiebold/github-env-vars-action | * | output.CI_PR_DESCRIPTION | pull_request_target | PR body | -| franzdiebold/github-env-vars-action | * | output.CI_PR_TITLE | pull_request_target | PR title | -| jitterbit/get-changed-files | * | output.added | pull_request_target | PR changed files | -| jitterbit/get-changed-files | * | output.added_modified | pull_request_target | PR changed files | -| jitterbit/get-changed-files | * | output.all | pull_request_target | PR changed files | -| jitterbit/get-changed-files | * | output.deleted | pull_request_target | PR changed files | -| jitterbit/get-changed-files | * | output.modified | pull_request_target | PR changed files | -| jitterbit/get-changed-files | * | output.removed | pull_request_target | PR changed files | -| jitterbit/get-changed-files | * | output.renamed | pull_request_target | PR changed files | -| khan/pull-request-comment-trigger | * | output.comment_body | issue_comment | | -| khan/pull-request-comment-trigger | * | output.comment_body | pull_request_comment | | -| octo-org/source-repo/.github/workflows/workflow.yml | * | output.workflow-output | * | Foo | -| tj-actions/branch-names | * | output.current_branch | pull_request_target | PR current branch | -| tj-actions/branch-names | * | output.head_ref_branch | pull_request_target | PR head branch | -| tj-actions/branch-names | * | output.ref_branch | pull_request_target | Branch tirggering workflow run | -| tj-actions/changed-files | * | output.added_files | pull_request_target | PR changed files | -| tj-actions/changed-files | * | output.all_changed_and_modified_files | pull_request_target | PR changed files | -| tj-actions/changed-files | * | output.all_changed_files | pull_request_target | PR changed files | -| tj-actions/changed-files | * | output.all_modified_files | pull_request_target | PR changed files | -| tj-actions/changed-files | * | output.all_old_new_renamed_files | pull_request_target | PR changed files | -| tj-actions/changed-files | * | output.changed_keys | pull_request_target | PR changed files | -| tj-actions/changed-files | * | output.copied_files | pull_request_target | PR changed files | -| tj-actions/changed-files | * | output.deleted_files | pull_request_target | PR changed files | -| tj-actions/changed-files | * | output.modified_files | pull_request_target | PR changed files | -| tj-actions/changed-files | * | output.modified_keys | pull_request_target | PR changed files | -| tj-actions/changed-files | * | output.other_changed_files | pull_request_target | PR changed files | -| tj-actions/changed-files | * | output.other_deleted_files | pull_request_target | PR changed files | -| tj-actions/changed-files | * | output.other_modified_files | pull_request_target | PR changed files | -| tj-actions/changed-files | * | output.renamed_files | pull_request_target | PR changed files | -| tj-actions/changed-files | * | output.type_changed_files | pull_request_target | PR changed files | -| tj-actions/changed-files | * | output.unknown_files | pull_request_target | PR changed files | -| tj-actions/changed-files | * | output.unmerged_files | pull_request_target | PR changed files | -| tj-actions/verify-changed-files | * | output.changed-files | pull_request_target | PR changed files | -| tzkhan/pr-update-action | * | output.headMatch | pull_request_target | | -| xt0rted/slash-command-action | * | output.command-arguments | issue_comment | | -| xt0rted/slash-command-action | * | output.command-arguments | pull_request_comment | | +| ahmadnassri/action-changed-files | * | output.files | PR changed files | +| ahmadnassri/action-changed-files | * | output.json | PR changed files | +| amannn/action-semantic-pull-request | * | output.error_message | PR title | +| cypress-io/github-action | * | env.GH_BRANCH | PR branch | +| dawidd6/action-download-artifact | * | output.artifacts | Artifact details | +| dorny/paths-filter | * | output.changes | PR changed files | +| franzdiebold/github-env-vars-action | * | output.CI_PR_DESCRIPTION | PR body | +| franzdiebold/github-env-vars-action | * | output.CI_PR_TITLE | PR title | +| jitterbit/get-changed-files | * | output.added | PR changed files | +| jitterbit/get-changed-files | * | output.added_modified | PR changed files | +| jitterbit/get-changed-files | * | output.all | PR changed files | +| jitterbit/get-changed-files | * | output.deleted | PR changed files | +| jitterbit/get-changed-files | * | output.modified | PR changed files | +| jitterbit/get-changed-files | * | output.removed | PR changed files | +| jitterbit/get-changed-files | * | output.renamed | PR changed files | +| khan/pull-request-comment-trigger | * | output.comment_body | Comment body | +| octo-org/source-repo/.github/workflows/workflow.yml | * | output.workflow-output | Foo | +| tj-actions/branch-names | * | output.current_branch | PR current branch | +| tj-actions/branch-names | * | output.head_ref_branch | PR head branch | +| tj-actions/branch-names | * | output.ref_branch | Branch tirggering workflow run | +| tj-actions/changed-files | * | output.added_files | PR changed files | +| tj-actions/changed-files | * | output.all_changed_and_modified_files | PR changed files | +| tj-actions/changed-files | * | output.all_changed_files | PR changed files | +| tj-actions/changed-files | * | output.all_modified_files | PR changed files | +| tj-actions/changed-files | * | output.all_old_new_renamed_files | PR changed files | +| tj-actions/changed-files | * | output.changed_keys | PR changed files | +| tj-actions/changed-files | * | output.copied_files | PR changed files | +| tj-actions/changed-files | * | output.deleted_files | PR changed files | +| tj-actions/changed-files | * | output.modified_files | PR changed files | +| tj-actions/changed-files | * | output.modified_keys | PR changed files | +| tj-actions/changed-files | * | output.other_changed_files | PR changed files | +| tj-actions/changed-files | * | output.other_deleted_files | PR changed files | +| tj-actions/changed-files | * | output.other_modified_files | PR changed files | +| tj-actions/changed-files | * | output.renamed_files | PR changed files | +| tj-actions/changed-files | * | output.type_changed_files | PR changed files | +| tj-actions/changed-files | * | output.unknown_files | PR changed files | +| tj-actions/changed-files | * | output.unmerged_files | PR changed files | +| tj-actions/verify-changed-files | * | output.changed-files | PR changed files | +| tzkhan/pr-update-action | * | output.headMatch | | +| xt0rted/slash-command-action | * | output.command-arguments | | summaries | akhileshns/heroku-deploy | * | input.branch | output.status | taint | | android-actions/setup-android | * | input.cmdline-tools-version | output.ANDROID_COMMANDLINE_TOOLS_VERSION | taint | diff --git a/ql/test/library-tests/test.ql b/ql/test/library-tests/test.ql index 268396a711e..d56ec73e26f 100644 --- a/ql/test/library-tests/test.ql +++ b/ql/test/library-tests/test.ql @@ -49,8 +49,8 @@ query predicate nodeLocations(DataFlow::Node n, Location l) { n.getLocation() = query predicate scopes(Cfg::CfgScope c) { any() } -query predicate sources(string action, string version, string output, string trigger, string kind) { - sourceModel(action, version, output, trigger, kind) +query predicate sources(string action, string version, string output, string kind) { + sourceModel(action, version, output, kind) } query predicate summaries(string action, string version, string input, string output, string kind) { diff --git a/ql/test/query-tests/Security/CWE-094/.github/workflows/pull_request_target.yml b/ql/test/query-tests/Security/CWE-094/.github/workflows/pull_request_target.yml index 215b3252885..995fefe4a15 100644 --- a/ql/test/query-tests/Security/CWE-094/.github/workflows/pull_request_target.yml +++ b/ql/test/query-tests/Security/CWE-094/.github/workflows/pull_request_target.yml @@ -4,8 +4,8 @@ jobs: echo-chamber: runs-on: ubuntu-latest steps: - - run: echo '${{ github.event.issue.title }}' # not defined - - run: echo '${{ github.event.issue.body }}' # not defined + - run: echo '${{ github.event.issue.title }}' # not defined for this trigger, but we will still report it + - run: echo '${{ github.event.issue.body }}' # not defined for this trigger, but we will still report it - run: echo '${{ github.event.pull_request.title }}' - run: echo '${{ github.event.pull_request.body }}' - run: echo '${{ github.event.pull_request.head.label }}' diff --git a/ql/test/query-tests/Security/CWE-094/PrivilegedCodeInjection.expected b/ql/test/query-tests/Security/CWE-094/PrivilegedCodeInjection.expected index e818ced0c1d..7061f509b81 100644 --- a/ql/test/query-tests/Security/CWE-094/PrivilegedCodeInjection.expected +++ b/ql/test/query-tests/Security/CWE-094/PrivilegedCodeInjection.expected @@ -230,6 +230,10 @@ subpaths | .github/workflows/gollum.yml:9:19:9:56 | github.event.pages[0].page_name | .github/workflows/gollum.yml:9:19:9:56 | github.event.pages[0].page_name | .github/workflows/gollum.yml:9:19:9:56 | github.event.pages[0].page_name | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/gollum.yml:9:19:9:56 | github.event.pages[0].page_name | ${{ github.event.pages[0].page_name }} | | .github/workflows/gollum.yml:10:19:10:59 | github.event.pages[2222].page_name | .github/workflows/gollum.yml:10:19:10:59 | github.event.pages[2222].page_name | .github/workflows/gollum.yml:10:19:10:59 | github.event.pages[2222].page_name | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/gollum.yml:10:19:10:59 | github.event.pages[2222].page_name | ${{ github.event.pages[2222].page_name }} | | .github/workflows/image_link_generator.yml:37:85:37:125 | steps.trim-url.outputs.trimmed_url | .github/workflows/image_link_generator.yml:18:18:18:49 | github.event.comment.body | .github/workflows/image_link_generator.yml:37:85:37:125 | steps.trim-url.outputs.trimmed_url | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/image_link_generator.yml:37:85:37:125 | steps.trim-url.outputs.trimmed_url | ${{ steps.trim-url.outputs.trimmed_url }} | +| .github/workflows/inter-job0.yml:43:20:43:53 | needs.job1.outputs.job_output | .github/workflows/inter-job0.yml:22:9:26:6 | Uses Step: source | .github/workflows/inter-job0.yml:43:20:43:53 | needs.job1.outputs.job_output | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/inter-job0.yml:43:20:43:53 | needs.job1.outputs.job_output | ${{needs.job1.outputs.job_output}} | +| .github/workflows/inter-job1.yml:43:20:43:53 | needs.job1.outputs.job_output | .github/workflows/inter-job1.yml:22:9:26:6 | Uses Step: source | .github/workflows/inter-job1.yml:43:20:43:53 | needs.job1.outputs.job_output | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/inter-job1.yml:43:20:43:53 | needs.job1.outputs.job_output | ${{needs.job1.outputs.job_output}} | +| .github/workflows/inter-job2.yml:45:20:45:53 | needs.job1.outputs.job_output | .github/workflows/inter-job2.yml:22:9:26:6 | Uses Step: source | .github/workflows/inter-job2.yml:45:20:45:53 | needs.job1.outputs.job_output | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/inter-job2.yml:45:20:45:53 | needs.job1.outputs.job_output | ${{needs.job1.outputs.job_output}} | +| .github/workflows/inter-job4.yml:44:20:44:53 | needs.job1.outputs.job_output | .github/workflows/inter-job4.yml:22:9:26:6 | Uses Step: source | .github/workflows/inter-job4.yml:44:20:44:53 | needs.job1.outputs.job_output | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/inter-job4.yml:44:20:44:53 | needs.job1.outputs.job_output | ${{needs.job1.outputs.job_output}} | | .github/workflows/issues.yaml:13:19:13:49 | github.event.issue.title | .github/workflows/issues.yaml:13:19:13:49 | github.event.issue.title | .github/workflows/issues.yaml:13:19:13:49 | github.event.issue.title | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/issues.yaml:13:19:13:49 | github.event.issue.title | ${{ github.event.issue.title }} | | .github/workflows/issues.yaml:14:19:14:48 | github.event.issue.body | .github/workflows/issues.yaml:14:19:14:48 | github.event.issue.body | .github/workflows/issues.yaml:14:19:14:48 | github.event.issue.body | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/issues.yaml:14:19:14:48 | github.event.issue.body | ${{ github.event.issue.body }} | | .github/workflows/issues.yaml:15:19:15:39 | env.global_env | .github/workflows/issues.yaml:4:16:4:46 | github.event.issue.title | .github/workflows/issues.yaml:15:19:15:39 | env.global_env | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/issues.yaml:15:19:15:39 | env.global_env | ${{ env.global_env }} | @@ -253,6 +257,8 @@ subpaths | .github/workflows/pull_request_review_comment.yml:12:19:12:69 | github.event.pull_request.head.repo.homepage | .github/workflows/pull_request_review_comment.yml:12:19:12:69 | github.event.pull_request.head.repo.homepage | .github/workflows/pull_request_review_comment.yml:12:19:12:69 | github.event.pull_request.head.repo.homepage | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/pull_request_review_comment.yml:12:19:12:69 | github.event.pull_request.head.repo.homepage | ${{ github.event.pull_request.head.repo.homepage }} | | .github/workflows/pull_request_review_comment.yml:13:19:13:59 | github.event.pull_request.head.ref | .github/workflows/pull_request_review_comment.yml:13:19:13:59 | github.event.pull_request.head.ref | .github/workflows/pull_request_review_comment.yml:13:19:13:59 | github.event.pull_request.head.ref | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/pull_request_review_comment.yml:13:19:13:59 | github.event.pull_request.head.ref | ${{ github.event.pull_request.head.ref }} | | .github/workflows/pull_request_review_comment.yml:14:19:14:50 | github.event.comment.body | .github/workflows/pull_request_review_comment.yml:14:19:14:50 | github.event.comment.body | .github/workflows/pull_request_review_comment.yml:14:19:14:50 | github.event.comment.body | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/pull_request_review_comment.yml:14:19:14:50 | github.event.comment.body | ${{ github.event.comment.body }} | +| .github/workflows/pull_request_target.yml:7:19:7:49 | github.event.issue.title | .github/workflows/pull_request_target.yml:7:19:7:49 | github.event.issue.title | .github/workflows/pull_request_target.yml:7:19:7:49 | github.event.issue.title | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/pull_request_target.yml:7:19:7:49 | github.event.issue.title | ${{ github.event.issue.title }} | +| .github/workflows/pull_request_target.yml:8:19:8:48 | github.event.issue.body | .github/workflows/pull_request_target.yml:8:19:8:48 | github.event.issue.body | .github/workflows/pull_request_target.yml:8:19:8:48 | github.event.issue.body | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/pull_request_target.yml:8:19:8:48 | github.event.issue.body | ${{ github.event.issue.body }} | | .github/workflows/pull_request_target.yml:9:19:9:56 | github.event.pull_request.title | .github/workflows/pull_request_target.yml:9:19:9:56 | github.event.pull_request.title | .github/workflows/pull_request_target.yml:9:19:9:56 | github.event.pull_request.title | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/pull_request_target.yml:9:19:9:56 | github.event.pull_request.title | ${{ github.event.pull_request.title }} | | .github/workflows/pull_request_target.yml:10:19:10:55 | github.event.pull_request.body | .github/workflows/pull_request_target.yml:10:19:10:55 | github.event.pull_request.body | .github/workflows/pull_request_target.yml:10:19:10:55 | github.event.pull_request.body | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/pull_request_target.yml:10:19:10:55 | github.event.pull_request.body | ${{ github.event.pull_request.body }} | | .github/workflows/pull_request_target.yml:11:19:11:61 | github.event.pull_request.head.label | .github/workflows/pull_request_target.yml:11:19:11:61 | github.event.pull_request.head.label | .github/workflows/pull_request_target.yml:11:19:11:61 | github.event.pull_request.head.label | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/pull_request_target.yml:11:19:11:61 | github.event.pull_request.head.label | ${{ github.event.pull_request.head.label }} | @@ -271,6 +277,8 @@ subpaths | .github/workflows/push.yml:14:19:14:64 | github.event.head_commit.committer.name | .github/workflows/push.yml:14:19:14:64 | github.event.head_commit.committer.name | .github/workflows/push.yml:14:19:14:64 | github.event.head_commit.committer.name | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/push.yml:14:19:14:64 | github.event.head_commit.committer.name | ${{ github.event.head_commit.committer.name }} | | .github/workflows/push.yml:15:19:15:65 | github.event.commits[11].committer.email | .github/workflows/push.yml:15:19:15:65 | github.event.commits[11].committer.email | .github/workflows/push.yml:15:19:15:65 | github.event.commits[11].committer.email | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/push.yml:15:19:15:65 | github.event.commits[11].committer.email | ${{ github.event.commits[11].committer.email }} | | .github/workflows/push.yml:16:19:16:64 | github.event.commits[11].committer.name | .github/workflows/push.yml:16:19:16:64 | github.event.commits[11].committer.name | .github/workflows/push.yml:16:19:16:64 | github.event.commits[11].committer.name | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/push.yml:16:19:16:64 | github.event.commits[11].committer.name | ${{ github.event.commits[11].committer.name }} | +| .github/workflows/self_needs.yml:19:15:19:47 | steps.source.outputs.value | .github/workflows/self_needs.yml:16:20:16:64 | github.event['head_commit']['message'] | .github/workflows/self_needs.yml:19:15:19:47 | steps.source.outputs.value | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/self_needs.yml:19:15:19:47 | steps.source.outputs.value | ${{ steps.source.outputs.value }} | +| .github/workflows/self_needs.yml:20:15:20:51 | needs.test1.outputs.job_output | .github/workflows/self_needs.yml:16:20:16:64 | github.event['head_commit']['message'] | .github/workflows/self_needs.yml:20:15:20:51 | needs.test1.outputs.job_output | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/self_needs.yml:20:15:20:51 | needs.test1.outputs.job_output | ${{ needs.test1.outputs.job_output }} | | .github/workflows/simple1.yml:16:18:16:49 | steps.summary.outputs.value | .github/workflows/simple1.yml:11:20:11:58 | github.event.head_commit.message | .github/workflows/simple1.yml:16:18:16:49 | steps.summary.outputs.value | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/simple1.yml:16:18:16:49 | steps.summary.outputs.value | ${{steps.summary.outputs.value}} | | .github/workflows/simple2.yml:29:24:29:54 | steps.step.outputs.value | .github/workflows/simple2.yml:14:9:18:6 | Uses Step: source | .github/workflows/simple2.yml:29:24:29:54 | steps.step.outputs.value | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/simple2.yml:29:24:29:54 | steps.step.outputs.value | ${{ steps.step.outputs.value }} | | .github/workflows/test.yml:37:20:37:56 | needs.job1.outputs['job_output'] | .github/workflows/test.yml:15:20:15:64 | github.event['head_commit']['message'] | .github/workflows/test.yml:37:20:37:56 | needs.job1.outputs['job_output'] | Potential privileged code injection in $@, which may be controlled by an external user. | .github/workflows/test.yml:37:20:37:56 | needs.job1.outputs['job_output'] | ${{needs.job1.outputs['job_output']}} |