From c6dbbca1c5e80a17b18346e2a276b71dea31660a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Tue, 15 Jul 2025 11:46:59 +0200 Subject: [PATCH 1/6] [DIFF-INFORMED] Actions: ArgumentInjection Query: - https://github.com/d10c/codeql/blob/d10c/diff-informed-phase-3/actions/ql/src/experimental/Security/CWE-088/ArgumentInjectionMedium.ql#L23 - https://github.com/d10c/codeql/blob/d10c/diff-informed-phase-3/actions/ql/src/experimental/Security/CWE-088/ArgumentInjectionCritical.ql#L27 --- .../actions/security/ArgumentInjectionQuery.qll | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/actions/ql/lib/codeql/actions/security/ArgumentInjectionQuery.qll b/actions/ql/lib/codeql/actions/security/ArgumentInjectionQuery.qll index 1d461cca3df2..6ac385c78d31 100644 --- a/actions/ql/lib/codeql/actions/security/ArgumentInjectionQuery.qll +++ b/actions/ql/lib/codeql/actions/security/ArgumentInjectionQuery.qll @@ -1,6 +1,7 @@ private import actions private import codeql.actions.TaintTracking private import codeql.actions.dataflow.ExternalFlow +private import codeql.actions.security.ControlChecks import codeql.actions.dataflow.FlowSources import codeql.actions.DataFlow @@ -88,6 +89,19 @@ private module ArgumentInjectionConfig implements DataFlow::ConfigSig { run.getScript().getAnEnvReachingArgumentInjectionSink(var, _, _) ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { none() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + result = sink.getLocation() + or + exists(Event event | result = event.getLocation() | + inPrivilegedContext(sink.asExpr(), event) and + not exists(ControlCheck check | check.protects(sink.asExpr(), event, "argument-injection")) + ) + } } /** Tracks flow of unsafe user input that is used to construct and evaluate a code script. */ From f1e1f8017d6fefa29760dad2b5068235ca59852d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Tue, 15 Jul 2025 14:28:55 +0200 Subject: [PATCH 2/6] [DIFF-INFORMED] Actions: ArtifactPoisoning Queries: - https://github.com/d10c/codeql/blob/d10c/diff-informed-phase-3/actions/ql/src/Security/CWE-829/ArtifactPoisoningMedium.ql#L23 - https://github.com/d10c/codeql/blob/d10c/diff-informed-phase-3/actions/ql/src/Security/CWE-829/ArtifactPoisoningCritical.ql#L26 --- .../actions/security/ArtifactPoisoningQuery.qll | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/actions/ql/lib/codeql/actions/security/ArtifactPoisoningQuery.qll b/actions/ql/lib/codeql/actions/security/ArtifactPoisoningQuery.qll index f0649bb8174e..b6480a53fc9a 100644 --- a/actions/ql/lib/codeql/actions/security/ArtifactPoisoningQuery.qll +++ b/actions/ql/lib/codeql/actions/security/ArtifactPoisoningQuery.qll @@ -4,6 +4,7 @@ import codeql.actions.DataFlow import codeql.actions.dataflow.FlowSources import codeql.actions.security.PoisonableSteps import codeql.actions.security.UntrustedCheckoutQuery +import codeql.actions.security.ControlChecks string unzipRegexp() { result = "(unzip|tar)\\s+.*" } @@ -318,6 +319,19 @@ private module ArtifactPoisoningConfig implements DataFlow::ConfigSig { exists(run.getScript().getAFileReadCommand()) ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { none() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + result = sink.getLocation() + or + exists(Event event | result = event.getLocation() | + inPrivilegedContext(sink.asExpr(), event) and + not exists(ControlCheck check | check.protects(sink.asExpr(), event, "artifact-poisoning")) + ) + } } /** Tracks flow of unsafe artifacts that is used in an insecure way. */ From 35dbe85b4aa738d5f5b861761a0ae150eddec502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Tue, 15 Jul 2025 14:34:15 +0200 Subject: [PATCH 3/6] [DIFF-INFORMED] Actions: CodeInjection Query: https://github.com/d10c/codeql/blob/d10c/diff-informed-phase-3/actions/ql/src/Security/CWE-349/CachePoisoningViaCodeInjection.ql#L46 --- .../actions/security/CodeInjectionQuery.qll | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/actions/ql/lib/codeql/actions/security/CodeInjectionQuery.qll b/actions/ql/lib/codeql/actions/security/CodeInjectionQuery.qll index fac498f72dab..a75ac84ef772 100644 --- a/actions/ql/lib/codeql/actions/security/CodeInjectionQuery.qll +++ b/actions/ql/lib/codeql/actions/security/CodeInjectionQuery.qll @@ -3,6 +3,8 @@ private import codeql.actions.TaintTracking private import codeql.actions.dataflow.ExternalFlow import codeql.actions.dataflow.FlowSources import codeql.actions.DataFlow +import codeql.actions.security.ControlChecks +import codeql.actions.security.CachePoisoningQuery class CodeInjectionSink extends DataFlow::Node { CodeInjectionSink() { @@ -35,6 +37,53 @@ private module CodeInjectionConfig implements DataFlow::ConfigSig { exists(run.getScript().getAFileReadCommand()) ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { none() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + result = sink.getLocation() + or + // where clause from CodeInjectionCritical.ql + exists(Event event, RemoteFlowSource source | result = event.getLocation() | + inPrivilegedContext(sink.asExpr(), event) and + isSource(source) and + source.getEventName() = event.getName() and + not exists(ControlCheck check | check.protects(sink.asExpr(), event, "code-injection")) and + // exclude cases where the sink is a JS script and the expression uses toJson + not exists(UsesStep script | + script.getCallee() = "actions/github-script" and + script.getArgumentExpr("script") = sink.asExpr() and + exists(getAToJsonReferenceExpression(sink.asExpr().(Expression).getExpression(), _)) + ) + ) + or + // where clause from CachePoisoningViaCodeInjection.ql + exists(Event event, LocalJob job, DataFlow::Node source | result = event.getLocation() | + job = sink.asExpr().getEnclosingJob() and + job.getATriggerEvent() = event and + // job can be triggered by an external user + event.isExternallyTriggerable() and + // the checkout is not controlled by an access check + isSource(source) and + not exists(ControlCheck check | check.protects(source.asExpr(), event, "code-injection")) and + // excluding privileged workflows since they can be exploited in easier circumstances + // which is covered by `actions/code-injection/critical` + not job.isPrivilegedExternallyTriggerable(event) and + ( + // the workflow runs in the context of the default branch + runsOnDefaultBranch(event) + or + // the workflow caller runs in the context of the default branch + event.getName() = "workflow_call" and + exists(ExternalJob caller | + caller.getCallee() = job.getLocation().getFile().getRelativePath() and + runsOnDefaultBranch(caller.getATriggerEvent()) + ) + ) + ) + } } /** Tracks flow of unsafe user input that is used to construct and evaluate a code script. */ From ed243bc1d160de1b3936dd90038841c44898be77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Tue, 15 Jul 2025 15:18:24 +0200 Subject: [PATCH 4/6] [DIFF-INFORMED] Actions: CommandInjection https://github.com/d10c/codeql/blob/d10c/diff-informed-phase-3/actions/ql/src/experimental/Security/CWE-078/CommandInjectionMedium.ql#L24 https://github.com/d10c/codeql/blob/d10c/diff-informed-phase-3/actions/ql/src/experimental/Security/CWE-078/CommandInjectionCritical.ql#L28 --- .../actions/security/CommandInjectionQuery.qll | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/actions/ql/lib/codeql/actions/security/CommandInjectionQuery.qll b/actions/ql/lib/codeql/actions/security/CommandInjectionQuery.qll index 59d523cd5827..878b7a598056 100644 --- a/actions/ql/lib/codeql/actions/security/CommandInjectionQuery.qll +++ b/actions/ql/lib/codeql/actions/security/CommandInjectionQuery.qll @@ -3,6 +3,7 @@ private import codeql.actions.TaintTracking private import codeql.actions.dataflow.ExternalFlow import codeql.actions.dataflow.FlowSources import codeql.actions.DataFlow +import codeql.actions.security.ControlChecks private class CommandInjectionSink extends DataFlow::Node { CommandInjectionSink() { madSink(this, "command-injection") } @@ -16,6 +17,22 @@ private module CommandInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } predicate isSink(DataFlow::Node sink) { sink instanceof CommandInjectionSink } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { none() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + result = sink.getLocation() + or + // where clause from CommandInjectionCritical.ql + exists(Event event | result = event.getLocation() | + inPrivilegedContext(sink.asExpr(), event) and + not exists(ControlCheck check | + check.protects(sink.asExpr(), event, ["command-injection", "code-injection"]) + ) + ) + } } /** Tracks flow of unsafe user input that is used to construct and evaluate a system command. */ From 7b4dd0eca3ce794ee481e53a3456a897c67a21e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Tue, 15 Jul 2025 15:21:37 +0200 Subject: [PATCH 5/6] [DIFF-INFORMED] Actions: EnvPathInjection https://github.com/d10c/codeql/blob/d10c/diff-informed-phase-3/actions/ql/src/Security/CWE-077/EnvPathInjectionMedium.ql#L30 https://github.com/d10c/codeql/blob/d10c/diff-informed-phase-3/actions/ql/src/Security/CWE-077/EnvPathInjectionCritical.ql#L37 --- .../security/EnvPathInjectionQuery.qll | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/actions/ql/lib/codeql/actions/security/EnvPathInjectionQuery.qll b/actions/ql/lib/codeql/actions/security/EnvPathInjectionQuery.qll index 33efc9b1bc8f..0ed0d2a877e9 100644 --- a/actions/ql/lib/codeql/actions/security/EnvPathInjectionQuery.qll +++ b/actions/ql/lib/codeql/actions/security/EnvPathInjectionQuery.qll @@ -108,6 +108,30 @@ private module EnvPathInjectionConfig implements DataFlow::ConfigSig { exists(run.getScript().getAFileReadCommand()) ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { none() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + result = sink.getLocation() + or + // where clause from EnvPathInjectionCritical.ql + exists(Event event, RemoteFlowSource source | result = event.getLocation() | + inPrivilegedContext(sink.asExpr(), event) and + isSource(source) and + ( + not source.getSourceType() = "artifact" and + not exists(ControlCheck check | check.protects(sink.asExpr(), event, "code-injection")) + or + source.getSourceType() = "artifact" and + not exists(ControlCheck check | + check.protects(sink.asExpr(), event, ["untrusted-checkout", "artifact-poisoning"]) + ) and + sink instanceof EnvPathInjectionFromFileReadSink + ) + ) + } } /** Tracks flow of unsafe user input that is used to construct and evaluate the PATH environment variable. */ From 3f931cd0d943823c1f6b77e88e41a7185ca605c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Tue, 15 Jul 2025 15:23:10 +0200 Subject: [PATCH 6/6] [DIFF-INFORMED] Actions: EnvVarInjection https://github.com/d10c/codeql/blob/d10c/diff-informed-phase-3/actions/ql/src/Security/CWE-077/EnvVarInjectionMedium.ql#L35 https://github.com/d10c/codeql/blob/d10c/diff-informed-phase-3/actions/ql/src/Security/CWE-077/EnvVarInjectionCritical.ql#L46 --- .../actions/security/EnvVarInjectionQuery.qll | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/actions/ql/lib/codeql/actions/security/EnvVarInjectionQuery.qll b/actions/ql/lib/codeql/actions/security/EnvVarInjectionQuery.qll index 656ea1207b51..a99c346e16d3 100644 --- a/actions/ql/lib/codeql/actions/security/EnvVarInjectionQuery.qll +++ b/actions/ql/lib/codeql/actions/security/EnvVarInjectionQuery.qll @@ -163,6 +163,40 @@ private module EnvVarInjectionConfig implements DataFlow::ConfigSig { exists(run.getScript().getAFileReadCommand()) ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { none() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + result = sink.getLocation() + or + // where clause from EnvVarInjectionCritical.ql + exists(Event event, RemoteFlowSource source | result = event.getLocation() | + inPrivilegedContext(sink.asExpr(), event) and + isSource(source) and + // exclude paths to file read sinks from non-artifact sources + ( + // source is text + not source.getSourceType() = "artifact" and + not exists(ControlCheck check | + check.protects(sink.asExpr(), event, ["envvar-injection", "code-injection"]) + ) + or + // source is an artifact or a file from an untrusted checkout + source.getSourceType() = "artifact" and + not exists(ControlCheck check | + check + .protects(sink.asExpr(), event, + ["envvar-injection", "untrusted-checkout", "artifact-poisoning"]) + ) and + ( + sink instanceof EnvVarInjectionFromFileReadSink or + madSink(sink, "envvar-injection") + ) + ) + ) + } } /** Tracks flow of unsafe user input that is used to construct and evaluate an environment variable. */ pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy