mirror of
https://github.com/github/codeql.git
synced 2026-01-05 02:30:19 +01:00
Merge pull request #92 from github/fix/direct_cache_poison
Improve path checks for Artifact and Cache poisoning queries
This commit is contained in:
@@ -289,6 +289,8 @@ class Run extends Step instanceof RunImpl {
|
||||
ScalarValue getScriptScalar() { result = super.getScriptScalar() }
|
||||
|
||||
Expression getAnScriptExpr() { result = super.getAnScriptExpr() }
|
||||
|
||||
string getWorkingDirectory() { result = super.getWorkingDirectory() }
|
||||
}
|
||||
|
||||
abstract class SimpleReferenceExpression extends AstNode instanceof SimpleReferenceExpressionImpl {
|
||||
|
||||
@@ -283,3 +283,30 @@ string getRepoRoot() {
|
||||
result = ""
|
||||
)
|
||||
}
|
||||
|
||||
bindingset[path]
|
||||
string normalizePath(string path) {
|
||||
exists(string trimmed_path | trimmed_path = trimQuotes(path) |
|
||||
// ./foo -> GITHUB_WORKSPACE/foo
|
||||
if path.indexOf("./") = 0
|
||||
then result = path.replaceAll("./", "GITHUB_WORKSPACE/")
|
||||
else
|
||||
// GITHUB_WORKSPACE/foo -> GITHUB_WORKSPACE/foo
|
||||
if path.indexOf("GITHUB_WORKSPACE/") = 0
|
||||
then result = path
|
||||
else
|
||||
// foo -> GITHUB_WORKSPACE/foo
|
||||
if path.regexpMatch("^[^/~].*")
|
||||
then result = "GITHUB_WORKSPACE/" + path.regexpReplaceAll("/$", "")
|
||||
else
|
||||
// ~/foo -> ~/foo
|
||||
// /foo -> /foo
|
||||
result = path
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the path cache_path is a subpath of the path untrusted_path.
|
||||
*/
|
||||
bindingset[subpath, path]
|
||||
predicate isSubpath(string subpath, string path) { subpath.substring(0, path.length()) = path }
|
||||
|
||||
@@ -1317,6 +1317,18 @@ class RunImpl extends StepImpl {
|
||||
override string toString() {
|
||||
if exists(this.getId()) then result = "Run Step: " + this.getId() else result = "Run Step"
|
||||
}
|
||||
|
||||
/** Gets the working directory for this `runs` mapping. */
|
||||
string getWorkingDirectory() {
|
||||
if exists(n.lookup("working-directory").(YamlString).getValue())
|
||||
then
|
||||
result =
|
||||
n.lookup("working-directory")
|
||||
.(YamlString)
|
||||
.getValue()
|
||||
.regexpReplaceAll("^\\./", "GITHUB_WORKSPACE/")
|
||||
else result = "GITHUB_WORKSPACE/"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -35,7 +35,9 @@ class GitHubDownloadArtifactActionStep extends UntrustedArtifactDownloadStep, Us
|
||||
}
|
||||
|
||||
override string getPath() {
|
||||
if exists(this.getArgument("path")) then result = this.getArgument("path") else result = ""
|
||||
if exists(this.getArgument("path"))
|
||||
then result = normalizePath(this.getArgument("path"))
|
||||
else result = "GITHUB_WORKSPACE/"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,11 +81,11 @@ class DownloadArtifactActionStep extends UntrustedArtifactDownloadStep, UsesStep
|
||||
|
||||
override string getPath() {
|
||||
if exists(this.getArgument(["path", "download_path"]))
|
||||
then result = this.getArgument(["path", "download_path"])
|
||||
then result = normalizePath(this.getArgument(["path", "download_path"]))
|
||||
else
|
||||
if exists(this.getArgument("paths"))
|
||||
then result = this.getArgument("paths").splitAt(" ")
|
||||
else result = ""
|
||||
then result = normalizePath(this.getArgument("paths").splitAt(" "))
|
||||
else result = "GITHUB_WORKSPACE/"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,8 +116,8 @@ class LegitLabsDownloadArtifactActionStep extends UntrustedArtifactDownloadStep,
|
||||
|
||||
override string getPath() {
|
||||
if exists(this.getArgument("path"))
|
||||
then result = this.getArgument("path")
|
||||
else result = "./artifacts"
|
||||
then result = normalizePath(this.getArgument("path"))
|
||||
else result = "GITHUB_WORKSPACE/artifacts"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,14 +163,14 @@ class ActionsGitHubScriptDownloadStep extends UntrustedArtifactDownloadStep, Use
|
||||
.regexpMatch(unzipRegexp() + unzipDirArgRegexp())
|
||||
then
|
||||
result =
|
||||
trimQuotes(this.getAFollowingStep()
|
||||
.(Run)
|
||||
.getScript()
|
||||
.splitAt("\n")
|
||||
.regexpCapture(unzipRegexp() + unzipDirArgRegexp(), 2))
|
||||
normalizePath(trimQuotes(this.getAFollowingStep()
|
||||
.(Run)
|
||||
.getScript()
|
||||
.splitAt("\n")
|
||||
.regexpCapture(unzipRegexp() + unzipDirArgRegexp(), 2)))
|
||||
else
|
||||
if this.getAFollowingStep().(Run).getScript().splitAt("\n").regexpMatch(unzipRegexp())
|
||||
then result = ""
|
||||
then result = "GITHUB_WORKSPACE/"
|
||||
else none()
|
||||
}
|
||||
}
|
||||
@@ -197,18 +199,20 @@ class GHRunArtifactDownloadStep extends UntrustedArtifactDownloadStep, Run {
|
||||
script.splitAt("\n").regexpMatch(unzipRegexp() + unzipDirArgRegexp())
|
||||
then
|
||||
result =
|
||||
trimQuotes(script.splitAt("\n").regexpCapture(unzipRegexp() + unzipDirArgRegexp(), 2)) or
|
||||
normalizePath(trimQuotes(script
|
||||
.splitAt("\n")
|
||||
.regexpCapture(unzipRegexp() + unzipDirArgRegexp(), 2))) or
|
||||
result =
|
||||
trimQuotes(this.getAFollowingStep()
|
||||
.(Run)
|
||||
.getScript()
|
||||
.splitAt("\n")
|
||||
.regexpCapture(unzipRegexp() + unzipDirArgRegexp(), 2))
|
||||
normalizePath(trimQuotes(this.getAFollowingStep()
|
||||
.(Run)
|
||||
.getScript()
|
||||
.splitAt("\n")
|
||||
.regexpCapture(unzipRegexp() + unzipDirArgRegexp(), 2)))
|
||||
else
|
||||
if
|
||||
this.getAFollowingStep().(Run).getScript().splitAt("\n").regexpMatch(unzipRegexp()) or
|
||||
script.splitAt("\n").regexpMatch(unzipRegexp())
|
||||
then result = ""
|
||||
then result = "GITHUB_WORKSPACE/"
|
||||
else none()
|
||||
}
|
||||
}
|
||||
@@ -244,14 +248,16 @@ class DirectArtifactDownloadStep extends UntrustedArtifactDownloadStep, Run {
|
||||
.regexpMatch(unzipRegexp() + unzipDirArgRegexp())
|
||||
then
|
||||
result =
|
||||
trimQuotes(script.splitAt("\n").regexpCapture(unzipRegexp() + unzipDirArgRegexp(), 2)) or
|
||||
normalizePath(trimQuotes(script
|
||||
.splitAt("\n")
|
||||
.regexpCapture(unzipRegexp() + unzipDirArgRegexp(), 2))) or
|
||||
result =
|
||||
trimQuotes(this.getAFollowingStep()
|
||||
.(Run)
|
||||
.getScript()
|
||||
.splitAt("\n")
|
||||
.regexpCapture(unzipRegexp() + unzipDirArgRegexp(), 2))
|
||||
else result = ""
|
||||
normalizePath(trimQuotes(this.getAFollowingStep()
|
||||
.(Run)
|
||||
.getScript()
|
||||
.splitAt("\n")
|
||||
.regexpCapture(unzipRegexp() + unzipDirArgRegexp(), 2)))
|
||||
else result = "GITHUB_WORKSPACE/"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,18 +274,16 @@ class ArtifactPoisoningSink extends DataFlow::Node {
|
||||
(
|
||||
// Check if the poisonable step is a local script execution step
|
||||
// and the path of the command or script matches the path of the downloaded artifact
|
||||
isSubpath(poisonable.(LocalScriptExecutionRunStep).getPath(), download.getPath())
|
||||
or
|
||||
// Checking the path for non local script execution steps is very difficult
|
||||
not poisonable instanceof LocalScriptExecutionRunStep
|
||||
or
|
||||
// TODO: account for Run's working directory
|
||||
poisonable
|
||||
.(LocalScriptExecutionRunStep)
|
||||
.getCommand()
|
||||
.matches(["./", ""] + download.getPath() + "%")
|
||||
// Its not easy to extract the path from a non-local script execution step so skipping this check for now
|
||||
// and isSubpath(poisonable.(Run).getWorkingDirectory(), download.getPath())
|
||||
)
|
||||
or
|
||||
poisonable.(UsesStep) = this.asExpr() and
|
||||
download.getPath() = ""
|
||||
download.getPath() = "GITHUB_WORKSPACE/"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -51,13 +51,17 @@ abstract class CacheWritingStep extends Step {
|
||||
class CacheActionUsesStep extends CacheWritingStep, UsesStep {
|
||||
CacheActionUsesStep() { this.getCallee() = "actions/cache" }
|
||||
|
||||
override string getPath() { result = this.(UsesStep).getArgument("path").splitAt("\n") }
|
||||
override string getPath() {
|
||||
result = normalizePath(this.(UsesStep).getArgument("path").splitAt("\n"))
|
||||
}
|
||||
}
|
||||
|
||||
class CacheActionSaveUsesStep extends CacheWritingStep, UsesStep {
|
||||
CacheActionSaveUsesStep() { this.getCallee() = "actions/cache/save" }
|
||||
|
||||
override string getPath() { result = this.(UsesStep).getArgument("path").splitAt("\n") }
|
||||
override string getPath() {
|
||||
result = normalizePath(this.(UsesStep).getArgument("path").splitAt("\n"))
|
||||
}
|
||||
}
|
||||
|
||||
class SetupRubyUsesStep extends CacheWritingStep, UsesStep {
|
||||
@@ -66,5 +70,5 @@ class SetupRubyUsesStep extends CacheWritingStep, UsesStep {
|
||||
this.getArgument("bundler-cache") = "true"
|
||||
}
|
||||
|
||||
override string getPath() { result = "vendor/bundle" }
|
||||
override string getPath() { result = normalizePath("vendor/bundle") }
|
||||
}
|
||||
|
||||
@@ -36,18 +36,18 @@ class JavascriptImportnUsesStep extends PoisonableStep, UsesStep {
|
||||
}
|
||||
|
||||
class LocalScriptExecutionRunStep extends PoisonableStep, Run {
|
||||
string cmd;
|
||||
string path;
|
||||
|
||||
LocalScriptExecutionRunStep() {
|
||||
exists(string line, string regexp, int command_group |
|
||||
exists(string line, string regexp, int path_group |
|
||||
line = this.getScript().splitAt("\n").trim()
|
||||
|
|
||||
poisonableLocalScriptsDataModel(regexp, command_group) and
|
||||
cmd = line.regexpCapture(regexp, command_group)
|
||||
poisonableLocalScriptsDataModel(regexp, path_group) and
|
||||
path = line.regexpCapture(regexp, path_group)
|
||||
)
|
||||
}
|
||||
|
||||
string getCommand() { result = cmd }
|
||||
string getPath() { result = normalizePath(path.splitAt(" ")) }
|
||||
}
|
||||
|
||||
class LocalActionUsesStep extends PoisonableStep, UsesStep {
|
||||
|
||||
@@ -151,12 +151,6 @@ predicate containsHeadRef(string s) {
|
||||
)
|
||||
}
|
||||
|
||||
private string getStepCWD() {
|
||||
// TODO: This should be the path of the git command.
|
||||
// Read if from the step's CWD, workspace or look for a cd command.
|
||||
result = "?"
|
||||
}
|
||||
|
||||
/** Checkout of a Pull Request HEAD */
|
||||
abstract class PRHeadCheckoutStep extends Step {
|
||||
abstract string getPath();
|
||||
@@ -208,7 +202,7 @@ class ActionsMutableRefCheckout extends MutableRefCheckoutStep instanceof UsesSt
|
||||
override string getPath() {
|
||||
if exists(this.(UsesStep).getArgument("path"))
|
||||
then result = this.(UsesStep).getArgument("path")
|
||||
else result = "?"
|
||||
else result = "GITHUB_WORKSPACE/"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,7 +246,7 @@ class ActionsSHACheckout extends SHACheckoutStep instanceof UsesStep {
|
||||
override string getPath() {
|
||||
if exists(this.(UsesStep).getArgument("path"))
|
||||
then result = this.(UsesStep).getArgument("path")
|
||||
else result = "?"
|
||||
else result = "GITHUB_WORKSPACE/"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,7 +271,7 @@ class GitMutableRefCheckout extends MutableRefCheckoutStep instanceof Run {
|
||||
)
|
||||
}
|
||||
|
||||
override string getPath() { result = getStepCWD() }
|
||||
override string getPath() { result = this.(Run).getWorkingDirectory() }
|
||||
}
|
||||
|
||||
/** Checkout of a Pull Request HEAD ref using git within a Run step */
|
||||
@@ -298,7 +292,7 @@ class GitSHACheckout extends SHACheckoutStep instanceof Run {
|
||||
)
|
||||
}
|
||||
|
||||
override string getPath() { result = getStepCWD() }
|
||||
override string getPath() { result = this.(Run).getWorkingDirectory() }
|
||||
}
|
||||
|
||||
/** Checkout of a Pull Request HEAD ref using gh within a Run step */
|
||||
@@ -321,7 +315,7 @@ class GhMutableRefCheckout extends MutableRefCheckoutStep instanceof Run {
|
||||
)
|
||||
}
|
||||
|
||||
override string getPath() { result = getStepCWD() }
|
||||
override string getPath() { result = this.(Run).getWorkingDirectory() }
|
||||
}
|
||||
|
||||
/** Checkout of a Pull Request HEAD ref using gh within a Run step */
|
||||
@@ -341,5 +335,5 @@ class GhSHACheckout extends SHACheckoutStep instanceof Run {
|
||||
)
|
||||
}
|
||||
|
||||
override string getPath() { result = getStepCWD() }
|
||||
override string getPath() { result = this.(Run).getWorkingDirectory() }
|
||||
}
|
||||
|
||||
@@ -18,29 +18,6 @@ import codeql.actions.security.CachePoisoningQuery
|
||||
import codeql.actions.security.PoisonableSteps
|
||||
import codeql.actions.security.ControlChecks
|
||||
|
||||
/**
|
||||
* Holds if the path cache_path is a subpath of the path untrusted_path.
|
||||
*/
|
||||
bindingset[cache_path, untrusted_path]
|
||||
predicate controlledCachePath(string cache_path, string untrusted_path) {
|
||||
exists(string normalized_cache_path, string normalized_untrusted_path |
|
||||
(
|
||||
cache_path.regexpMatch("^[a-zA-Z0-9_-].*") and
|
||||
normalized_cache_path = "./" + cache_path.regexpReplaceAll("/$", "")
|
||||
or
|
||||
normalized_cache_path = cache_path.regexpReplaceAll("/$", "")
|
||||
) and
|
||||
(
|
||||
untrusted_path.regexpMatch("^[a-zA-Z0-9_-].*") and
|
||||
normalized_untrusted_path = "./" + untrusted_path.regexpReplaceAll("/$", "")
|
||||
or
|
||||
normalized_untrusted_path = untrusted_path.regexpReplaceAll("/$", "")
|
||||
) and
|
||||
normalized_cache_path.substring(0, normalized_untrusted_path.length()) =
|
||||
normalized_untrusted_path
|
||||
)
|
||||
}
|
||||
|
||||
query predicate edges(Step a, Step b) { a.getNextStep() = b }
|
||||
|
||||
from LocalJob job, Event event, Step source, Step step, string message, string path
|
||||
@@ -86,7 +63,7 @@ where
|
||||
step.(CacheWritingStep).getPath() = "?"
|
||||
or
|
||||
// the cache writing step reads from a path the attacker can control
|
||||
not path = "?" and controlledCachePath(step.(CacheWritingStep).getPath(), path)
|
||||
not path = "?" and isSubpath(step.(CacheWritingStep).getPath(), path)
|
||||
) and
|
||||
not step instanceof PoisonableStep
|
||||
select step, source, step,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: Test
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
pull_request_target:
|
||||
|
||||
permissions:
|
||||
actions: write
|
||||
@@ -11,6 +11,8 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: Set up Python 3.10
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
@@ -22,14 +24,3 @@ jobs:
|
||||
path: ./results/pip
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml') }}
|
||||
restore-keys: ${{ runner.os }}-pip-
|
||||
- name: Download artifact
|
||||
uses: dawidd6/action-download-artifact@v2
|
||||
with:
|
||||
name: results
|
||||
path: results/
|
||||
- name: Upload results
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: results
|
||||
path: results/
|
||||
if-no-files-found: ignore
|
||||
|
||||
23
ql/test/query-tests/Security/CWE-349/.github/workflows/neg_direct_cache4.yml
vendored
Normal file
23
ql/test/query-tests/Security/CWE-349/.github/workflows/neg_direct_cache4.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
pr-comment:
|
||||
permissions: read-all
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: xt0rted/pull-request-comment-branch@v2
|
||||
id: comment-branch
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
if: success()
|
||||
with:
|
||||
ref: ${{ steps.comment-branch.outputs.head_sha }}
|
||||
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.grade/caches/
|
||||
key: poison_key
|
||||
- run: |
|
||||
cat poison
|
||||
23
ql/test/query-tests/Security/CWE-349/.github/workflows/neg_direct_cache5.yml
vendored
Normal file
23
ql/test/query-tests/Security/CWE-349/.github/workflows/neg_direct_cache5.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
pr-comment:
|
||||
permissions: read-all
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: xt0rted/pull-request-comment-branch@v2
|
||||
id: comment-branch
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
if: success()
|
||||
with:
|
||||
ref: ${{ steps.comment-branch.outputs.head_sha }}
|
||||
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: /tmp/caches/
|
||||
key: poison_key
|
||||
- run: |
|
||||
cat poison
|
||||
@@ -12,10 +12,8 @@ edges
|
||||
| .github/workflows/direct_cache4.yml:17:9:21:6 | Uses Step | .github/workflows/direct_cache4.yml:21:9:22:21 | Run Step |
|
||||
| .github/workflows/direct_cache5.yml:14:9:17:6 | Uses Step | .github/workflows/direct_cache5.yml:17:9:21:6 | Uses Step |
|
||||
| .github/workflows/direct_cache5.yml:17:9:21:6 | Uses Step | .github/workflows/direct_cache5.yml:21:9:22:21 | Run Step |
|
||||
| .github/workflows/direct_cache6.yml:13:9:14:6 | Uses Step | .github/workflows/direct_cache6.yml:14:9:18:6 | Uses Step |
|
||||
| .github/workflows/direct_cache6.yml:14:9:18:6 | Uses Step | .github/workflows/direct_cache6.yml:18:9:25:6 | Uses Step: cache-pip |
|
||||
| .github/workflows/direct_cache6.yml:18:9:25:6 | Uses Step: cache-pip | .github/workflows/direct_cache6.yml:25:9:30:6 | Uses Step |
|
||||
| .github/workflows/direct_cache6.yml:25:9:30:6 | Uses Step | .github/workflows/direct_cache6.yml:30:9:35:36 | Uses Step |
|
||||
| .github/workflows/direct_cache6.yml:13:9:16:6 | Uses Step | .github/workflows/direct_cache6.yml:16:9:20:6 | Uses Step |
|
||||
| .github/workflows/direct_cache6.yml:16:9:20:6 | Uses Step | .github/workflows/direct_cache6.yml:20:9:26:46 | Uses Step: cache-pip |
|
||||
| .github/workflows/neg_direct_cache1.yml:14:9:17:6 | Uses Step | .github/workflows/neg_direct_cache1.yml:17:9:21:6 | Uses Step |
|
||||
| .github/workflows/neg_direct_cache1.yml:17:9:21:6 | Uses Step | .github/workflows/neg_direct_cache1.yml:21:9:22:21 | Run Step |
|
||||
| .github/workflows/neg_direct_cache2.yml:14:9:17:6 | Uses Step | .github/workflows/neg_direct_cache2.yml:17:9:21:6 | Uses Step |
|
||||
@@ -24,6 +22,12 @@ edges
|
||||
| .github/workflows/neg_direct_cache3.yml:14:9:18:6 | Uses Step | .github/workflows/neg_direct_cache3.yml:18:9:25:6 | Uses Step: cache-pip |
|
||||
| .github/workflows/neg_direct_cache3.yml:18:9:25:6 | Uses Step: cache-pip | .github/workflows/neg_direct_cache3.yml:25:9:30:6 | Uses Step |
|
||||
| .github/workflows/neg_direct_cache3.yml:25:9:30:6 | Uses Step | .github/workflows/neg_direct_cache3.yml:30:9:35:36 | Uses Step |
|
||||
| .github/workflows/neg_direct_cache4.yml:10:9:13:6 | Uses Step: comment-branch | .github/workflows/neg_direct_cache4.yml:13:9:18:6 | Uses Step |
|
||||
| .github/workflows/neg_direct_cache4.yml:13:9:18:6 | Uses Step | .github/workflows/neg_direct_cache4.yml:18:9:22:6 | Uses Step |
|
||||
| .github/workflows/neg_direct_cache4.yml:18:9:22:6 | Uses Step | .github/workflows/neg_direct_cache4.yml:22:9:23:21 | Run Step |
|
||||
| .github/workflows/neg_direct_cache5.yml:10:9:13:6 | Uses Step: comment-branch | .github/workflows/neg_direct_cache5.yml:13:9:18:6 | Uses Step |
|
||||
| .github/workflows/neg_direct_cache5.yml:13:9:18:6 | Uses Step | .github/workflows/neg_direct_cache5.yml:18:9:22:6 | Uses Step |
|
||||
| .github/workflows/neg_direct_cache5.yml:18:9:22:6 | Uses Step | .github/workflows/neg_direct_cache5.yml:22:9:23:21 | Run Step |
|
||||
| .github/workflows/neg_poisonable_step1.yml:11:9:14:6 | Uses Step: comment-branch | .github/workflows/neg_poisonable_step1.yml:14:9:19:6 | Uses Step |
|
||||
| .github/workflows/neg_poisonable_step1.yml:14:9:19:6 | Uses Step | .github/workflows/neg_poisonable_step1.yml:19:9:20:30 | Run Step |
|
||||
| .github/workflows/neg_poisonable_step2.yml:13:9:16:6 | Uses Step | .github/workflows/neg_poisonable_step2.yml:16:9:17:54 | Run Step |
|
||||
@@ -45,4 +49,4 @@ edges
|
||||
| .github/workflows/direct_cache3.yml:19:9:23:6 | Uses Step | .github/workflows/direct_cache3.yml:14:9:19:6 | Uses Step | .github/workflows/direct_cache3.yml:19:9:23:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. |
|
||||
| .github/workflows/direct_cache4.yml:17:9:21:6 | Uses Step | .github/workflows/direct_cache4.yml:14:9:17:6 | Uses Step | .github/workflows/direct_cache4.yml:17:9:21:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. |
|
||||
| .github/workflows/direct_cache5.yml:17:9:21:6 | Uses Step | .github/workflows/direct_cache5.yml:14:9:17:6 | Uses Step | .github/workflows/direct_cache5.yml:17:9:21:6 | Uses Step | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. |
|
||||
| .github/workflows/direct_cache6.yml:18:9:25:6 | Uses Step: cache-pip | .github/workflows/direct_cache6.yml:25:9:30:6 | Uses Step | .github/workflows/direct_cache6.yml:18:9:25:6 | Uses Step: cache-pip | Potential cache poisoning in the context of the default branch due to downloading an untrusted artifact. |
|
||||
| .github/workflows/direct_cache6.yml:20:9:26:46 | Uses Step: cache-pip | .github/workflows/direct_cache6.yml:13:9:16:6 | Uses Step | .github/workflows/direct_cache6.yml:20:9:26:46 | Uses Step: cache-pip | Potential cache poisoning in the context of the default branch due to privilege checkout of untrusted code. |
|
||||
|
||||
@@ -12,10 +12,8 @@ edges
|
||||
| .github/workflows/direct_cache4.yml:17:9:21:6 | Uses Step | .github/workflows/direct_cache4.yml:21:9:22:21 | Run Step |
|
||||
| .github/workflows/direct_cache5.yml:14:9:17:6 | Uses Step | .github/workflows/direct_cache5.yml:17:9:21:6 | Uses Step |
|
||||
| .github/workflows/direct_cache5.yml:17:9:21:6 | Uses Step | .github/workflows/direct_cache5.yml:21:9:22:21 | Run Step |
|
||||
| .github/workflows/direct_cache6.yml:13:9:14:6 | Uses Step | .github/workflows/direct_cache6.yml:14:9:18:6 | Uses Step |
|
||||
| .github/workflows/direct_cache6.yml:14:9:18:6 | Uses Step | .github/workflows/direct_cache6.yml:18:9:25:6 | Uses Step: cache-pip |
|
||||
| .github/workflows/direct_cache6.yml:18:9:25:6 | Uses Step: cache-pip | .github/workflows/direct_cache6.yml:25:9:30:6 | Uses Step |
|
||||
| .github/workflows/direct_cache6.yml:25:9:30:6 | Uses Step | .github/workflows/direct_cache6.yml:30:9:35:36 | Uses Step |
|
||||
| .github/workflows/direct_cache6.yml:13:9:16:6 | Uses Step | .github/workflows/direct_cache6.yml:16:9:20:6 | Uses Step |
|
||||
| .github/workflows/direct_cache6.yml:16:9:20:6 | Uses Step | .github/workflows/direct_cache6.yml:20:9:26:46 | Uses Step: cache-pip |
|
||||
| .github/workflows/neg_direct_cache1.yml:14:9:17:6 | Uses Step | .github/workflows/neg_direct_cache1.yml:17:9:21:6 | Uses Step |
|
||||
| .github/workflows/neg_direct_cache1.yml:17:9:21:6 | Uses Step | .github/workflows/neg_direct_cache1.yml:21:9:22:21 | Run Step |
|
||||
| .github/workflows/neg_direct_cache2.yml:14:9:17:6 | Uses Step | .github/workflows/neg_direct_cache2.yml:17:9:21:6 | Uses Step |
|
||||
@@ -24,6 +22,12 @@ edges
|
||||
| .github/workflows/neg_direct_cache3.yml:14:9:18:6 | Uses Step | .github/workflows/neg_direct_cache3.yml:18:9:25:6 | Uses Step: cache-pip |
|
||||
| .github/workflows/neg_direct_cache3.yml:18:9:25:6 | Uses Step: cache-pip | .github/workflows/neg_direct_cache3.yml:25:9:30:6 | Uses Step |
|
||||
| .github/workflows/neg_direct_cache3.yml:25:9:30:6 | Uses Step | .github/workflows/neg_direct_cache3.yml:30:9:35:36 | Uses Step |
|
||||
| .github/workflows/neg_direct_cache4.yml:10:9:13:6 | Uses Step: comment-branch | .github/workflows/neg_direct_cache4.yml:13:9:18:6 | Uses Step |
|
||||
| .github/workflows/neg_direct_cache4.yml:13:9:18:6 | Uses Step | .github/workflows/neg_direct_cache4.yml:18:9:22:6 | Uses Step |
|
||||
| .github/workflows/neg_direct_cache4.yml:18:9:22:6 | Uses Step | .github/workflows/neg_direct_cache4.yml:22:9:23:21 | Run Step |
|
||||
| .github/workflows/neg_direct_cache5.yml:10:9:13:6 | Uses Step: comment-branch | .github/workflows/neg_direct_cache5.yml:13:9:18:6 | Uses Step |
|
||||
| .github/workflows/neg_direct_cache5.yml:13:9:18:6 | Uses Step | .github/workflows/neg_direct_cache5.yml:18:9:22:6 | Uses Step |
|
||||
| .github/workflows/neg_direct_cache5.yml:18:9:22:6 | Uses Step | .github/workflows/neg_direct_cache5.yml:22:9:23:21 | Run Step |
|
||||
| .github/workflows/neg_poisonable_step1.yml:11:9:14:6 | Uses Step: comment-branch | .github/workflows/neg_poisonable_step1.yml:14:9:19:6 | Uses Step |
|
||||
| .github/workflows/neg_poisonable_step1.yml:14:9:19:6 | Uses Step | .github/workflows/neg_poisonable_step1.yml:19:9:20:30 | Run Step |
|
||||
| .github/workflows/neg_poisonable_step2.yml:13:9:16:6 | Uses Step | .github/workflows/neg_poisonable_step2.yml:16:9:17:54 | Run Step |
|
||||
|
||||
Reference in New Issue
Block a user