Merge pull request #26 from GitHubSecurityLab/refactor_ast

Refactor AST layer
This commit is contained in:
Alvaro Muñoz
2024-03-04 17:39:56 +01:00
committed by GitHub
40 changed files with 1023 additions and 1104 deletions

2
clean.sh Executable file
View File

@@ -0,0 +1,2 @@
#! /bin/bash
find . -type d -name "*testproj*" -exec rm -r {} +

View File

@@ -1,4 +1,4 @@
private import codeql.actions.ast.internal.Actions
private import codeql.actions.ast.internal.Yaml
private import codeql.Locations
/**
@@ -14,182 +14,276 @@ class AstNode instanceof YamlNode {
string getAPrimaryQlClass() { result = super.getAPrimaryQlClass() }
Location getLocation() { result = super.getLocation() }
}
/**
* A statement is a group of expressions and/or statements that you design to carry out a task or an action.
* Any statement that can return a value is automatically qualified to be used as an expression.
*/
class Statement extends AstNode {
/** Gets the workflow that this job is a part of. */
WorkflowStmt getEnclosingWorkflowStmt() { this = result.getAChildNode*() }
/**
* Gets a environment variable expression by name in the scope of the current step.
* Gets the enclosing workflow statement.
*/
Expression getEnvExpr(string name) {
exists(Actions::Env env |
env.(YamlMapping).maps(any(YamlScalar s | s.getValue() = name), result)
|
env.(Actions::StepEnv).getStep().getAChildNode*() = this
Workflow getEnclosingWorkflow() { this = result.getAChildNode*() }
/**
* Gets a environment variable expression by name in the scope of the current node.
*/
StringLiteral getEnvVar(string name) {
exists(Env env | env.(YamlMapping).maps(any(YamlScalar s | s.getValue() = name), result) |
env.(StepEnv).getStep().getAChildNode*() = this
or
env.(Actions::JobEnv).getJob().getAChildNode*() = this
env.(JobEnv).getJob().getAChildNode*() = this
or
env.(Actions::WorkflowEnv).getWorkflow().getAChildNode*() = this
env.(WorkflowEnv).getWorkflow().getAChildNode*() = this
)
}
}
/**
* An expression is any word or group of words or symbols that is a value. In programming, an expression is a value, or anything that executes and ends up being a value.
*/
class Expression extends Statement { }
/** A common class for `env` in workflow, job or step. */
abstract class Env extends AstNode instanceof YamlMapping { }
/**
* A composite action
*/
class CompositeActionStmt extends Statement instanceof Actions::CompositeAction {
RunsStmt getRunsStmt() { result = super.getRuns() }
/** A workflow level `env` mapping. */
class WorkflowEnv extends Env {
Workflow workflow;
InputsStmt getInputsStmt() { result = this.(YamlMapping).lookup("inputs") }
WorkflowEnv() { workflow.(YamlMapping).lookup("env") = this }
OutputsStmt getOutputsStmt() { result = this.(YamlMapping).lookup("outputs") }
/** Gets the workflow this field belongs to. */
Workflow getWorkflow() { result = workflow }
}
class RunsStmt extends Statement instanceof Actions::Runs {
StepStmt getAStepStmt() { result = super.getSteps().getElementNode(_) }
/** A job level `env` mapping. */
class JobEnv extends Env {
Job job;
StepStmt getStepStmt(int i) { result = super.getSteps().getElementNode(i) }
JobEnv() { job.(YamlMapping).lookup("env") = this }
/** Gets the job this field belongs to. */
Job getJob() { result = job }
}
/** A step level `env` mapping. */
class StepEnv extends Env {
Step step;
StepEnv() { step.(YamlMapping).lookup("env") = this }
/** Gets the step this field belongs to. */
Step getStep() { result = step }
}
/**
* A Github Actions Workflow
* A custom composite action. This is a mapping at the top level of an Actions YAML action file.
* See https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions.
*/
class WorkflowStmt extends Statement instanceof Actions::Workflow {
string getName() { result = super.getName() }
class CompositeAction extends AstNode instanceof YamlDocument, YamlMapping {
//class CompositeAction extends AstNode, YamlDocument, YamlMapping {
CompositeAction() {
this.getFile().getBaseName() = ["action.yml", "action.yaml"] and
super.lookup("runs").(YamlMapping).lookup("using").(YamlScalar).getValue() = "composite"
}
JobStmt getAJobStmt() { result = super.getJob(_) }
/** Gets the `runs` mapping. */
Runs getRuns() { result = super.lookup("runs") }
JobStmt getJobStmt(string id) { result = super.getJob(id) }
Outputs getOutputs() { result = super.lookup("outputs") }
StringLiteral getAnOutput() { result = this.getOutputs().getAnOutput() }
StringLiteral getOutput(string name) { result = this.getOutputs().getOutput(name) }
Input getAnInput() { super.lookup("inputs").(YamlMapping).maps(result, _) }
Input getInput(string name) {
super.lookup("inputs").(YamlMapping).maps(result, _) and
result.(YamlString).getValue() = name
}
}
/**
* An `runs` mapping in a custom composite action YAML.
* See https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#runs
*/
class Runs extends AstNode instanceof YamlMapping {
CompositeAction action;
Runs() { action.(YamlMapping).lookup("runs") = this }
/** Gets the action that this `runs` mapping is in. */
CompositeAction getAction() { result = action }
/** Gets any steps that are defined within this job. */
Step getAStep() { result = super.lookup("steps").(YamlSequence).getElementNode(_) }
/** Gets the step at the given index within this job. */
Step getStep(int i) { result = super.lookup("steps").(YamlSequence).getElementNode(i) }
}
/**
* An Actions workflow. This is a mapping at the top level of an Actions YAML workflow file.
* See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions.
*/
class Workflow extends AstNode instanceof YamlDocument, YamlMapping {
/** Gets the `jobs` mapping from job IDs to job definitions in this workflow. */
YamlMapping getJobs() { result = super.lookup("jobs") }
/** Gets the 'global' `env` mapping in this workflow. */
WorkflowEnv getEnv() { result = super.lookup("env") }
/** Gets the name of the workflow. */
string getName() { result = super.lookup("name").(YamlString).getValue() }
/** Gets the job within this workflow with the given job ID. */
Job getJob(string jobId) { result.getWorkflow() = this and result.getId() = jobId }
/** Gets a job within this workflow */
Job getAJob() { result = this.getJob(_) }
predicate hasTriggerEvent(string trigger) {
exists(YamlNode n | n = super.getOn().(YamlMappingLikeNode).getNode(trigger))
exists(YamlNode n | n = super.lookup("on").(YamlMappingLikeNode).getNode(trigger))
}
string getATriggerEvent() {
exists(YamlNode n | n = super.getOn().(YamlMappingLikeNode).getNode(result))
exists(YamlNode n | n = super.lookup("on").(YamlMappingLikeNode).getNode(result))
}
Statement getPermissionsStmt() { result = this.(YamlMapping).lookup("permissions") }
Permissions getPermissions() { result = super.lookup("permissions") }
StrategyStmt getStrategyStmt() { result = this.(YamlMapping).lookup("strategy") }
Strategy getStrategy() { result = super.lookup("strategy") }
}
class ReusableWorkflowStmt extends WorkflowStmt {
class ReusableWorkflow extends Workflow instanceof YamlMapping {
YamlValue workflow_call;
ReusableWorkflowStmt() {
this.(Actions::Workflow).getOn().getNode("workflow_call") = workflow_call
ReusableWorkflow() {
super.lookup("on").(YamlMappingLikeNode).getNode("workflow_call") = workflow_call
}
InputsStmt getInputsStmt() { result = workflow_call.(YamlMapping).lookup("inputs") }
Outputs getOutputs() { result = workflow_call.(YamlMapping).lookup("outputs") }
OutputsStmt getOutputsStmt() { result = workflow_call.(YamlMapping).lookup("outputs") }
}
StringLiteral getAnOutput() { result = this.getOutputs().getAnOutput() }
class InputsStmt extends Statement instanceof YamlMapping {
YamlMapping parent;
StringLiteral getOutput(string name) { result = this.getOutputs().getOutput(name) }
InputsStmt() { parent.lookup("inputs") = this }
Input getAnInput() { workflow_call.(YamlMapping).lookup("inputs").(YamlMapping).maps(result, _) }
/**
* Gets a specific input expression (YamlMapping) by name.
*/
InputExpr getInputExpr(string name) {
result.(YamlString).getValue() = name and
this.(YamlMapping).maps(result, _)
Input getInput(string name) {
workflow_call.(YamlMapping).lookup("inputs").(YamlMapping).maps(result, _) and
result.(YamlString).getValue() = name
}
}
class OutputsStmt extends Statement instanceof YamlMapping {
class Input extends AstNode {
YamlMapping parent;
OutputsStmt() { parent.lookup("outputs") = this }
Input() { parent.lookup("inputs").(YamlMapping).maps(this, _) }
}
class Outputs extends AstNode instanceof YamlMapping {
YamlMapping parent;
Outputs() { parent.lookup("outputs") = this }
/**
* Gets a specific output expression (YamlMapping) by name.
* Gets an output expression.
*/
OutputExpr getOutputExpr(string name) {
this.(YamlMapping).lookup(name).(YamlMapping).lookup("value") = result or
this.(YamlMapping).lookup(name) = result
StringLiteral getAnOutput() {
super.lookup(_).(YamlMapping).lookup("value") = result or
super.lookup(_) = result
}
/**
* Gets a specific output expression by name.
*/
StringLiteral getOutput(string name) {
super.lookup(name).(YamlMapping).lookup("value") = result or
super.lookup(name) = result
}
string getAnOutputName() { this.(YamlMapping).maps(any(YamlString s | s.getValue() = result), _) }
override string toString() { result = "Job outputs node" }
}
class StrategyStmt extends Statement instanceof YamlMapping {
class Permissions extends AstNode instanceof YamlMapping {
YamlMapping parent;
StrategyStmt() { parent.lookup("strategy") = this }
Permissions() { parent.lookup("permissions") = this }
}
class Strategy extends AstNode instanceof YamlMapping {
YamlMapping parent;
Strategy() { parent.lookup("strategy") = this }
/**
* Gets a specific matric expression (YamlMapping) by name.
*/
MatrixVariableExpr getMatrixVariableExpr(string name) {
this.(YamlMapping).lookup("matrix").(YamlMapping).lookup(name) = result
StringLiteral getMatrixVar(string name) {
super.lookup("matrix").(YamlMapping).lookup(name) = result
}
string getAMatrixVariableName() {
this.(YamlMapping).maps(any(YamlString s | s.getValue() = result), _)
}
/**
* Gets a specific matric expression (YamlMapping) by name.
*/
StringLiteral getAMatrixVar() { super.lookup("matrix").(YamlMapping).lookup(_) = result }
}
class InputExpr extends Expression instanceof YamlString {
InputExpr() { exists(InputsStmt inputs | inputs.(YamlMapping).maps(this, _)) }
}
/**
* https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idneeds
*/
class Needs extends AstNode instanceof YamlMappingLikeNode {
Job job;
class OutputExpr extends Expression instanceof YamlString {
OutputExpr() {
exists(OutputsStmt outputs |
outputs.(YamlMapping).lookup(_).(YamlMapping).lookup("value") = this or
outputs.(YamlMapping).lookup(_) = this
)
}
}
Needs() { job.(YamlMapping).lookup("needs") = this }
class MatrixVariableExpr extends Expression instanceof YamlString {
MatrixVariableExpr() {
exists(StrategyStmt outputs |
outputs.(YamlMapping).lookup("matrix").(YamlMapping).lookup(_) = this
)
Job getJob() { result = job }
Job getANeededJob() {
result.getId() = super.getNode(_).(YamlString).getValue() and
result.getLocation().getFile() = job.getLocation().getFile()
// if this instanceof YamlString
// then
// result.getId() = this.(YamlString).getValue() and
// result.getLocation().getFile() = job.getLocation().getFile()
// else
// if this instanceof YamlSequence
// then
// result.getId() = this.(YamlSequence).getElementNode(_).(YamlString).getValue() and
// result.getLocation().getFile() = job.getLocation().getFile()
// else none()
}
}
/**
* A Job is a collection of steps that run in an execution environment.
* An Actions job within a workflow.
* See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobs.
*/
class JobStmt extends Statement instanceof Actions::Job {
class Job extends AstNode instanceof YamlMapping {
string jobId;
Workflow workflow;
Job() { this = workflow.getJobs().lookup(jobId) }
/**
* Gets the ID of this job, as a string.
* This is the job's key within the `jobs` mapping.
*/
string getId() { result = super.getId() }
/** Gets the step at the given index within this job. */
StepStmt getStepStmt(int index) { result = super.getStep(index) }
string getId() { result = jobId }
/** Gets any steps that are defined within this job. */
StepStmt getAStepStmt() { result = super.getStep(_) }
Step getAStep() { result = super.lookup("steps").(YamlSequence).getElementNode(_) }
/** Gets the step at the given index within this job. */
Step getStep(int i) { result = super.lookup("steps").(YamlSequence).getElementNode(i) }
/** Gets the workflow this job belongs to. */
Workflow getWorkflow() { result = workflow }
/**
* Gets a needed job.
* eg:
* - needs: [job1, job2]
*/
JobStmt getNeededJob() {
exists(Actions::Needs needs |
Job getANeededJob() {
exists(Needs needs |
needs.getJob() = this and
result = needs.getANeededJob().(JobStmt)
result = needs.getANeededJob()
)
}
@@ -199,7 +293,11 @@ class JobStmt extends Statement instanceof Actions::Job {
* out1: ${steps.foo.bar}
* out2: ${steps.foo.baz}
*/
OutputsStmt getOutputsStmt() { result = this.(Actions::Job).lookup("outputs") }
Outputs getOutputs() { result = super.lookup("outputs") }
StringLiteral getAnOutput() { result = this.getOutputs().getAnOutput() }
StringLiteral getOutput(string name) { result = this.getOutputs().getOutput(name) }
/**
* Reusable workflow jobs may have Uses children
@@ -209,42 +307,52 @@ class JobStmt extends Statement instanceof Actions::Job {
* with:
* arg1: value1
*/
JobUsesExpr getUsesExpr() { result.getJobStmt() = this }
UsesJob getUses() { result.getJob() = this }
predicate usesReusableWorkflow() {
this.(YamlMapping).maps(any(YamlString s | s.getValue() = "uses"), _)
}
IfStmt getIfStmt() { result = super.getIf() }
If getIf() { result = super.lookup("if") }
Statement getPermissionsStmt() { result = this.(YamlMapping).lookup("permissions") }
Permissions getPermissions() { result = super.lookup("permissions") }
StrategyStmt getStrategyStmt() { result = this.(YamlMapping).lookup("strategy") }
Strategy getStrategy() { result = super.lookup("strategy") }
override string toString() { result = "Job: " + jobId }
}
/**
* A Step is a single task that can be executed as part of a job.
* A step within an Actions job.
* See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idsteps.
*/
class StepStmt extends Statement instanceof Actions::Step {
string getId() { result = super.getId() }
class Step extends AstNode instanceof YamlMapping {
YamlMapping parent;
JobStmt getJobStmt() { result = super.getJob() }
Step() { parent.lookup("steps").(YamlSequence).getElementNode(_) = this }
IfStmt getIfStmt() { result = super.getIf() }
/** Gets the ID of this step, if any. */
string getId() { result = super.lookup("id").(YamlString).getValue() }
/** Gets the `job` this step belongs to, if the step belongs to a `job` in a workflow. Has no result if the step belongs to `runs` in a custom composite action. */
Job getJob() { result = parent }
/** Gets the value of the `if` field in this step, if any. */
If getIf() { result = super.lookup("if") }
}
/**
* An If node representing a conditional statement.
*/
class IfStmt extends Statement {
class If extends AstNode {
YamlMapping parent;
IfStmt() {
(parent instanceof Actions::Step or parent instanceof Actions::Job) and
If() {
(parent instanceof Step or parent instanceof Job) and
parent.lookup("if") = this
}
Statement getEnclosingStatement() { result = parent }
AstNode getEnclosingNode() { result = parent }
string getCondition() { result = this.(YamlScalar).getValue() }
}
@@ -252,48 +360,61 @@ class IfStmt extends Statement {
/**
* Abstract class representing a call to a 3rd party action or reusable workflow.
*/
abstract class UsesExpr extends Expression {
abstract class Uses extends AstNode {
abstract string getCallee();
abstract string getVersion();
abstract Expression getArgumentExpr(string key);
abstract StringLiteral getArgument(string key);
override string toString() { result = "Uses Step" }
}
/**
* Gets a regular expression that parses an `owner/repo@version` reference within a `uses` field in an Actions job step.
* The capture groups are:
* 1: The owner of the repository where the Action comes from, e.g. `actions` in `actions/checkout@v2`
* 2: The name of the repository where the Action comes from, e.g. `checkout` in `actions/checkout@v2`.
* 3: The version reference used when checking out the Action, e.g. `v2` in `actions/checkout@v2`.
*/
private string usesParser() { result = "([^/]+)/([^/@]+)@(.+)" }
/**
* A Uses step represents a call to an action that is defined in a GitHub repository.
*/
class StepUsesExpr extends StepStmt, UsesExpr {
Actions::Uses uses;
class UsesStep extends Step, Uses {
YamlScalar uses;
StepUsesExpr() { uses.getStep() = this }
UsesStep() { this.(YamlMapping).maps(any(YamlScalar s | s.getValue() = "uses"), uses) }
override string getCallee() { result = uses.getGitHubRepository() }
override string getVersion() {
result = uses.getVersion()
or
not exists(uses.getVersion()) and
result = "main"
/** Gets the owner and name of the repository where the Action comes from, e.g. `actions/checkout` in `actions/checkout@v2`. */
override string getCallee() {
result =
(
uses.getValue().regexpCapture(usesParser(), 1) + "/" +
uses.getValue().regexpCapture(usesParser(), 2)
).toLowerCase()
}
override Expression getArgumentExpr(string key) {
exists(Actions::With with |
with.getStep() = this and
result = with.lookup(key)
)
/** Gets the version reference used when checking out the Action, e.g. `v2` in `actions/checkout@v2`. */
override string getVersion() { result = uses.getValue().regexpCapture(usesParser(), 3) }
override StringLiteral getArgument(string key) {
result = this.(YamlMapping).lookup("with").(YamlMapping).lookup(key)
}
override string toString() {
if exists(this.getId()) then result = "Uses Step: " + this.getId() else result = "Uses Step"
}
}
/**
* A Uses step represents a call to an action that is defined in a GitHub repository.
*/
class JobUsesExpr extends UsesExpr instanceof YamlMapping {
JobUsesExpr() {
this instanceof JobStmt and this.maps(any(YamlString s | s.getValue() = "uses"), _)
}
class UsesJob extends Uses instanceof YamlMapping {
UsesJob() { this instanceof Job and this.maps(any(YamlString s | s.getValue() = "uses"), _) }
JobStmt getJobStmt() { result = this }
Job getJob() { result = this }
/**
* Gets a regular expression that parses an `owner/repo@version` reference within a `uses` field in an Actions job step.
@@ -307,7 +428,7 @@ class JobUsesExpr extends UsesExpr instanceof YamlMapping {
override string getCallee() {
exists(YamlString name |
this.(YamlMapping).lookup("uses") = name and
super.lookup("uses") = name and
if name.getValue().matches("./%")
then result = name.getValue().regexpCapture(this.pathUsesParser(), 1)
else
@@ -321,50 +442,85 @@ class JobUsesExpr extends UsesExpr instanceof YamlMapping {
/** Gets the version reference used when checking out the Action, e.g. `v2` in `actions/checkout@v2`. */
override string getVersion() {
exists(YamlString name |
this.(YamlMapping).lookup("uses") = name and
super.lookup("uses") = name and
if not name.getValue().matches("\\.%")
then result = name.getValue().regexpCapture(this.repoUsesParser(), 4)
else none()
)
}
override Expression getArgumentExpr(string key) {
this.(YamlMapping).lookup("with").(YamlMapping).lookup(key) = result
override StringLiteral getArgument(string key) {
super.lookup("with").(YamlMapping).lookup(key) = result
}
}
/**
* A Run step represents the evaluation of a provided script
* A `run` field within an Actions job step, which runs command-line programs using an operating system shell.
* See https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstepsrun.
*/
class RunExpr extends StepStmt, Expression {
Actions::Run scriptExpr;
class Run extends Step {
StringLiteral script;
RunExpr() { scriptExpr.getStep() = this }
Run() { this.(YamlMapping).maps(any(YamlString s | s.getValue() = "run"), script) }
Expression getScriptExpr() { result = scriptExpr }
StringLiteral getScript() { result = script }
string getScript() { result = scriptExpr.getValue() }
override string toString() {
if exists(this.getId()) then result = "Run Step: " + this.getId() else result = "Run Step"
}
}
/**
* Evaluation of a workflow expression ${{}}.
* A YamlString part of a YamlSequence or YamlMapping values.
*/
class ExprAccessExpr extends Expression instanceof YamlString {
class StringLiteral extends AstNode instanceof YamlString {
StringLiteral() {
exists(YamlCollection c |
c instanceof YamlMapping and
c.(YamlMapping).maps(_, this)
or
c instanceof YamlSequence and
c.(YamlSequence).getElementNode(_) = this
)
}
string getValue() { result = this.(YamlString).getValue() }
}
/**
* Holds if `${{ e }}` is a GitHub Actions expression evaluated within this YAML string.
* See https://docs.github.com/en/free-pro-team@latest/actions/reference/context-and-expression-syntax-for-github-actions.
* Only finds simple expressions like `${{ github.event.comment.body }}`, where the expression contains only alphanumeric characters, underscores, dots, or dashes.
* Does not identify more complicated expressions like `${{ fromJSON(env.time) }}`, or ${{ format('{{Hello {0}!}}', github.event.head_commit.author.name) }}
*/
string getASimpleReferenceExpression(YamlString node) {
// We use `regexpFind` to obtain *all* matches of `${{...}}`,
// not just the last (greedy match) or first (reluctant match).
result =
node.getValue()
.regexpFind("\\$\\{\\{\\s*[A-Za-z0-9_\\[\\]\\*\\(\\)\\.\\-]+\\s*\\}\\}", _, _)
.regexpCapture("\\$\\{\\{\\s*([A-Za-z0-9_\\[\\]\\*\\((\\)\\.\\-]+)\\s*\\}\\}", 1)
}
/**
* A StringLiteral containing a workflow expression ${{}}.
*/
class Expression extends StringLiteral {
string expr;
ExprAccessExpr() { expr = Actions::getASimpleReferenceExpression(this) }
Expression() { expr = getASimpleReferenceExpression(this) }
string getExpression() { result = expr }
JobStmt getJobStmt() { result.getAChildNode*() = this }
Job getJob() { result.getAChildNode*() = this }
}
/**
* A context access expression.
* A ${{}} expression accessing a context variable such as steps, needs, jobs, env, inputs, or matrix.
* https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability
*/
class CtxAccessExpr extends ExprAccessExpr {
CtxAccessExpr() {
class ContextExpression extends Expression {
ContextExpression() {
expr.regexpMatch([
stepsCtxRegex(), needsCtxRegex(), jobsCtxRegex(), envCtxRegex(), inputsCtxRegex(),
matrixCtxRegex()
@@ -373,7 +529,7 @@ class CtxAccessExpr extends ExprAccessExpr {
abstract string getFieldName();
abstract Expression getRefExpr();
abstract AstNode getTarget();
}
private string stepsCtxRegex() {
@@ -406,11 +562,11 @@ private string wrapRegexp(string regex) {
* https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability
* e.g. `${{ steps.changed-files.outputs.all_changed_files }}`
*/
class StepsCtxAccessExpr extends CtxAccessExpr {
class StepsExpression extends ContextExpression {
string stepId;
string fieldName;
StepsCtxAccessExpr() {
StepsExpression() {
expr.regexpMatch(stepsCtxRegex()) and
stepId = expr.regexpCapture(stepsCtxRegex(), 1) and
fieldName = expr.regexpCapture(stepsCtxRegex(), 2)
@@ -418,9 +574,9 @@ class StepsCtxAccessExpr extends CtxAccessExpr {
override string getFieldName() { result = fieldName }
override Expression getRefExpr() {
override AstNode getTarget() {
this.getLocation().getFile() = result.getLocation().getFile() and
result.(StepStmt).getId() = stepId
result.(Step).getId() = stepId
}
}
@@ -429,30 +585,31 @@ class StepsCtxAccessExpr extends CtxAccessExpr {
* https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability
* e.g. `${{ needs.job1.outputs.foo}}`
*/
class NeedsCtxAccessExpr extends CtxAccessExpr {
JobStmt job;
string jobId;
class NeedsExpression extends ContextExpression {
Job neededJob;
string neededJobId;
string fieldName;
NeedsCtxAccessExpr() {
NeedsExpression() {
expr.regexpMatch(needsCtxRegex()) and
jobId = expr.regexpCapture(needsCtxRegex(), 1) and
neededJobId = expr.regexpCapture(needsCtxRegex(), 1) and
fieldName = expr.regexpCapture(needsCtxRegex(), 2) and
job.getId() = jobId
neededJob.getId() = neededJobId
}
predicate usesReusableWorkflow() { job.usesReusableWorkflow() }
predicate usesReusableWorkflow() { neededJob.usesReusableWorkflow() }
override string getFieldName() { result = fieldName }
override Expression getRefExpr() {
job.getLocation().getFile() = this.getLocation().getFile() and
override AstNode getTarget() {
neededJob.getLocation().getFile() = this.getLocation().getFile() and
this.getJob().getANeededJob() = neededJob and
(
// regular jobs
job.getOutputsStmt() = result
neededJob.getOutputs() = result
or
// reusable workflow calling jobs
job.getUsesExpr() = result
neededJob.getUses() = result
)
}
}
@@ -462,11 +619,11 @@ class NeedsCtxAccessExpr extends CtxAccessExpr {
* https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability
* e.g. `${{ jobs.job1.outputs.foo}}` (within reusable workflows)
*/
class JobsCtxAccessExpr extends CtxAccessExpr {
class JobsExpression extends ContextExpression {
string jobId;
string fieldName;
JobsCtxAccessExpr() {
JobsExpression() {
expr.regexpMatch(jobsCtxRegex()) and
jobId = expr.regexpCapture(jobsCtxRegex(), 1) and
fieldName = expr.regexpCapture(jobsCtxRegex(), 2)
@@ -474,11 +631,11 @@ class JobsCtxAccessExpr extends CtxAccessExpr {
override string getFieldName() { result = fieldName }
override Expression getRefExpr() {
exists(JobStmt job |
override AstNode getTarget() {
exists(Job job |
job.getId() = jobId and
job.getLocation().getFile() = this.getLocation().getFile() and
job.getOutputsStmt() = result
job.getOutputs() = result
)
}
}
@@ -488,21 +645,23 @@ class JobsCtxAccessExpr extends CtxAccessExpr {
* https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability
* e.g. `${{ inputs.foo }}`
*/
class InputsCtxAccessExpr extends CtxAccessExpr {
class InputsExpression extends ContextExpression {
string fieldName;
InputsCtxAccessExpr() {
InputsExpression() {
expr.regexpMatch(inputsCtxRegex()) and
fieldName = expr.regexpCapture(inputsCtxRegex(), 1)
}
override string getFieldName() { result = fieldName }
override Expression getRefExpr() {
override AstNode getTarget() {
result.getLocation().getFile() = this.getLocation().getFile() and
exists(ReusableWorkflowStmt w | w.getInputsStmt().getInputExpr(fieldName) = result)
or
exists(CompositeActionStmt a | a.getInputsStmt().getInputExpr(fieldName) = result)
(
exists(ReusableWorkflow w | w.getInput(fieldName) = result)
or
exists(CompositeAction a | a.getInput(fieldName) = result)
)
}
}
@@ -511,19 +670,19 @@ class InputsCtxAccessExpr extends CtxAccessExpr {
* https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability
* e.g. `${{ env.foo }}`
*/
class EnvCtxAccessExpr extends CtxAccessExpr {
class EnvExpression extends ContextExpression {
string fieldName;
EnvCtxAccessExpr() {
EnvExpression() {
expr.regexpMatch(envCtxRegex()) and
fieldName = expr.regexpCapture(envCtxRegex(), 1)
}
override string getFieldName() { result = fieldName }
override Expression getRefExpr() {
exists(Statement s |
s.getEnvExpr(fieldName) = result and
override AstNode getTarget() {
exists(AstNode s |
s.getEnvVar(fieldName) = result and
s.getAChildNode*() = this
)
}
@@ -534,24 +693,24 @@ class EnvCtxAccessExpr extends CtxAccessExpr {
* https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability
* e.g. `${{ matrix.foo }}`
*/
class MatrixCtxAccessExpr extends CtxAccessExpr {
class MatrixExpression extends ContextExpression {
string fieldName;
MatrixCtxAccessExpr() {
MatrixExpression() {
expr.regexpMatch(matrixCtxRegex()) and
fieldName = expr.regexpCapture(matrixCtxRegex(), 1)
}
override string getFieldName() { result = fieldName }
override Expression getRefExpr() {
exists(WorkflowStmt w |
w.getStrategyStmt().getMatrixVariableExpr(fieldName) = result and
override AstNode getTarget() {
exists(Workflow w |
w.getStrategy().getMatrixVar(fieldName) = result and
w.getAChildNode*() = this
)
or
exists(JobStmt j |
j.getStrategyStmt().getMatrixVariableExpr(fieldName) = result and
exists(Job j |
j.getStrategy().getMatrixVar(fieldName) = result and
j.getAChildNode*() = this
)
}

View File

@@ -1,398 +0,0 @@
/**
* Libraries for modeling GitHub Actions workflow files written in YAML.
* See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions.
*/
import codeql.actions.ast.internal.Yaml
import codeql.files.FileSystem
/**
* Libraries for modeling GitHub Actions workflow files written in YAML.
* See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions.
*/
module Actions {
/** A YAML node in a GitHub Actions workflow or a custom composite action file. */
private class Node extends YamlNode {
Node() {
exists(File f |
f = this.getLocation().getFile() and
(
f.getRelativePath().regexpMatch("(^|.*/)\\.github/workflows/.*\\.ya?ml$") or
f.getBaseName() = ["action.yml", "action.yaml"]
)
)
}
}
/**
* A custom composite action. This is a mapping at the top level of an Actions YAML action file.
* See https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions.
*/
class CompositeAction extends Node, YamlDocument, YamlMapping {
CompositeAction() {
this.getFile().getBaseName() = ["action.yml", "action.yaml"] and
this.lookup("runs").(YamlMapping).lookup("using").(YamlScalar).getValue() = "composite"
}
/** Gets the `runs` mapping. */
Runs getRuns() { result = this.lookup("runs") }
}
/**
* An `runs` mapping in a custom composite action YAML.
* See https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#runs
*/
class Runs extends StepsContainer {
CompositeAction action;
Runs() { action.lookup("runs") = this }
/** Gets the action that this `runs` mapping is in. */
CompositeAction getAction() { result = action }
/** Gets the `using` mapping. */
Using getUsing() { result = this.lookup("using") }
}
/**
* The parent class of the class that can contain `steps` mappings. (`Job` or `Runs` currently.)
*/
abstract class StepsContainer extends YamlNode, YamlMapping {
/** Gets the sequence of `steps` within this YAML node. */
YamlSequence getSteps() { result = this.lookup("steps") }
}
/**
* A `using` mapping in a custom composite action YAML.
*/
class Using extends YamlNode, YamlScalar {
Runs runs;
Using() { runs.lookup("using") = this }
/** Gets the `runs` mapping that this `using` mapping is in. */
Runs getRuns() { result = runs }
}
/**
* An Actions workflow. This is a mapping at the top level of an Actions YAML workflow file.
* See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions.
*/
class Workflow extends Node, YamlDocument, YamlMapping {
/** Gets the `jobs` mapping from job IDs to job definitions in this workflow. */
YamlMapping getJobs() { result = this.lookup("jobs") }
/** Gets the 'global' `env` mapping in this workflow. */
WorkflowEnv getEnv() { result = this.lookup("env") }
/** Gets the name of the workflow. */
string getName() { result = this.lookup("name").(YamlString).getValue() }
/** Gets the name of the workflow file. */
string getFileName() { result = this.getFile().getBaseName() }
/** Gets the `on:` in this workflow. */
On getOn() { result = this.lookup("on") }
/** Gets the job within this workflow with the given job ID. */
Job getJob(string jobId) { result.getWorkflow() = this and result.getId() = jobId }
}
/**
* An Actions On trigger within a workflow.
* See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#on.
*/
class On extends YamlNode, YamlMappingLikeNode {
Workflow workflow;
On() { workflow.lookup("on") = this }
/** Gets the workflow that this trigger is in. */
Workflow getWorkflow() { result = workflow }
}
/** A common class for `env` in workflow, job or step. */
abstract class Env extends YamlNode, YamlMapping { }
/** A workflow level `env` mapping. */
class WorkflowEnv extends Env {
Workflow workflow;
WorkflowEnv() { workflow.lookup("env") = this }
/** Gets the workflow this field belongs to. */
Workflow getWorkflow() { result = workflow }
}
/** A job level `env` mapping. */
class JobEnv extends Env {
Job job;
JobEnv() { job.lookup("env") = this }
/** Gets the job this field belongs to. */
Job getJob() { result = job }
}
/** A step level `env` mapping. */
class StepEnv extends Env {
Step step;
StepEnv() { step.lookup("env") = this }
/** Gets the step this field belongs to. */
Step getStep() { result = step }
}
/**
* An Actions job within a workflow.
* See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobs.
*/
class Job extends StepsContainer {
string jobId;
Workflow workflow;
Job() { this = workflow.getJobs().lookup(jobId) }
/**
* Gets the ID of this job, as a string.
* This is the job's key within the `jobs` mapping.
*/
string getId() { result = jobId }
/**
* Gets the ID of this job, as a YAML scalar node.
* This is the job's key within the `jobs` mapping.
*/
YamlString getIdNode() { workflow.getJobs().maps(result, this) }
/** Gets the human-readable name of this job, if any, as a string. */
string getName() { result = this.getNameNode().getValue() }
/** Gets the human-readable name of this job, if any, as a YAML scalar node. */
YamlString getNameNode() { result = this.lookup("name") }
/** Gets the step at the given index within this job. */
Step getStep(int index) { result.getJob() = this and result.getIndex() = index }
/** Gets the `env` mapping in this job. */
JobEnv getEnv() { result = this.lookup("env") }
/** Gets the workflow this job belongs to. */
Workflow getWorkflow() { result = workflow }
/** Gets the value of the `if` field in this job, if any. */
JobIf getIf() { result.getJob() = this }
/** Gets the value of the `runs-on` field in this job. */
JobRunson getRunsOn() { result.getJob() = this }
}
/**
* An `if` within a job.
* See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idif.
*/
class JobIf extends YamlNode, YamlScalar {
Job job;
JobIf() { job.lookup("if") = this }
/** Gets the step this field belongs to. */
Job getJob() { result = job }
}
/**
* A `runs-on` within a job.
* See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idruns-on.
*/
class JobRunson extends YamlNode, YamlScalar {
Job job;
JobRunson() { job.lookup("runs-on") = this }
/** Gets the step this field belongs to. */
Job getJob() { result = job }
}
/**
* A step within an Actions job.
* See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idsteps.
*/
class Step extends YamlNode, YamlMapping {
int index;
StepsContainer parent;
Step() { this = parent.getSteps().getElement(index) }
/** Gets the 0-based position of this step within the sequence of `steps`. */
int getIndex() { result = index }
/** Gets the `job` this step belongs to, if the step belongs to a `job` in a workflow. Has no result if the step belongs to `runs` in a custom composite action. */
Job getJob() { result = parent }
/** Gets the `runs` this step belongs to, if the step belongs to a `runs` in a custom composite action. Has no result if the step belongs to a `job` in a workflow. */
Runs getRuns() { result = parent }
/** Gets the value of the `uses` field in this step, if any. */
Uses getUses() { result.getStep() = this }
/** Gets the value of the `run` field in this step, if any. */
Run getRun() { result.getStep() = this }
/** Gets the value of the `if` field in this step, if any. */
StepIf getIf() { result.getStep() = this }
/** Gets the value of the `env` field in this step, if any. */
StepEnv getEnv() { result = this.lookup("env") }
/** Gets the ID of this step, if any. */
string getId() { result = this.lookup("id").(YamlString).getValue() }
}
/**
* An `if` within a step.
* See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstepsif.
*/
class StepIf extends YamlNode, YamlScalar {
Step step;
StepIf() { step.lookup("if") = this }
/** Gets the step this field belongs to. */
Step getStep() { result = step }
}
/**
* Gets a regular expression that parses an `owner/repo@version` reference within a `uses` field in an Actions job step.
* The capture groups are:
* 1: The owner of the repository where the Action comes from, e.g. `actions` in `actions/checkout@v2`
* 2: The name of the repository where the Action comes from, e.g. `checkout` in `actions/checkout@v2`.
* 3: The version reference used when checking out the Action, e.g. `v2` in `actions/checkout@v2`.
*/
private string usesParser() { result = "([^/]+)/([^/@]+)@(.+)" }
/**
* A `uses` field within an Actions job step, which references an action as a reusable unit of code.
* See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstepsuses.
*
* For example:
* ```
* uses: actions/checkout@v2
* ```
*
* Does not handle local repository references, e.g. `.github/actions/action-name`.
*/
class Uses extends YamlNode, YamlScalar {
Step step;
Uses() { step.lookup("uses") = this }
/** Gets the step this field belongs to. */
Step getStep() { result = step }
/** Gets the owner and name of the repository where the Action comes from, e.g. `actions/checkout` in `actions/checkout@v2`. */
string getGitHubRepository() {
result =
(
this.getValue().regexpCapture(usesParser(), 1) + "/" +
this.getValue().regexpCapture(usesParser(), 2)
).toLowerCase()
}
/** Gets the version reference used when checking out the Action, e.g. `v2` in `actions/checkout@v2`. */
string getVersion() { result = this.getValue().regexpCapture(usesParser(), 3) }
}
/**
* A `with` field within an Actions job step, which references an action as a reusable unit of code.
* See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstepswith.
*
* For example:
* ```
* with:
* arg1: 1
* arg2: abc
* ```
*/
class With extends YamlNode, YamlMapping {
Step step;
With() { step.lookup("with") = this }
/** Gets the step this field belongs to. */
Step getStep() { result = step }
}
/**
* A `ref:` field within an Actions `with:` specific to `actions/checkout` action.
*
* For example:
* ```
* uses: actions/checkout@v2
* with:
* ref: ${{ github.event.pull_request.head.sha }}
* ```
*/
class Ref extends YamlNode, YamlString {
With with;
Ref() { with.lookup("ref") = this }
/** Gets the `with` field this field belongs to. */
With getWith() { result = with }
}
/**
* Holds if `${{ e }}` is a GitHub Actions expression evaluated within this YAML string.
* See https://docs.github.com/en/free-pro-team@latest/actions/reference/context-and-expression-syntax-for-github-actions.
* Only finds simple expressions like `${{ github.event.comment.body }}`, where the expression contains only alphanumeric characters, underscores, dots, or dashes.
* Does not identify more complicated expressions like `${{ fromJSON(env.time) }}`, or ${{ format('{{Hello {0}!}}', github.event.head_commit.author.name) }}
*/
string getASimpleReferenceExpression(YamlString node) {
// We use `regexpFind` to obtain *all* matches of `${{...}}`,
// not just the last (greedy match) or first (reluctant match).
result =
node.getValue()
.regexpFind("\\$\\{\\{\\s*[A-Za-z0-9_\\[\\]\\*\\(\\)\\.\\-]+\\s*\\}\\}", _, _)
.regexpCapture("\\$\\{\\{\\s*([A-Za-z0-9_\\[\\]\\*\\((\\)\\.\\-]+)\\s*\\}\\}", 1)
}
/** Extracts the 'name' part from env.name */
bindingset[name]
string getEnvName(string name) { result = name.regexpCapture("env\\.([A-Za-z0-9_]+)", 1) }
/**
* A `run` field within an Actions job step, which runs command-line programs using an operating system shell.
* See https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstepsrun.
*/
class Run extends YamlNode, YamlString {
Step step;
Run() { step.lookup("run") = this }
/** Gets the step that executes this `run` command. */
Step getStep() { result = step }
}
/**
* https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idneeds
*/
class Needs extends YamlNode {
Job job;
Needs() { job.lookup("needs") = this }
Job getJob() { result = job }
Job getANeededJob() {
if this instanceof YamlString
then result.getId() = this.(YamlString).getValue() and result.getFile() = job.getFile()
else
if this instanceof YamlSequence
then
result.getId() = this.(YamlSequence).getElementNode(_).(YamlString).getValue() and
result.getFile() = job.getFile()
else none()
}
}
}

View File

@@ -442,4 +442,3 @@ class ConditionBlock extends BasicBlock {
*/
predicate controls(BasicBlock controlled, BooleanSuccessor s) { controls(this, controlled, s) }
}

View File

@@ -77,15 +77,14 @@ module Completion {
class ReturnSuccessor extends SuccessorType, TReturnSuccessor {
override string toString() { result = "return" }
}
// Why is there no conditional successor type?
}
module CfgScope {
abstract class CfgScope extends AstNode { }
class WorkflowScope extends CfgScope instanceof WorkflowStmt { }
class WorkflowScope extends CfgScope instanceof Workflow { }
class CompositeActionScope extends CfgScope instanceof CompositeActionStmt { }
class CompositeActionScope extends CfgScope instanceof CompositeAction { }
}
private module Implementation implements CfgShared::InputSig<Location> {
@@ -119,13 +118,13 @@ private module Implementation implements CfgShared::InputSig<Location> {
int maxSplits() { result = 0 }
predicate scopeFirst(CfgScope scope, AstNode e) {
first(scope.(WorkflowStmt), e) or
first(scope.(CompositeActionStmt), e)
first(scope.(Workflow), e) or
first(scope.(CompositeAction), e)
}
predicate scopeLast(CfgScope scope, AstNode e, Completion c) {
last(scope.(WorkflowStmt), e, c) or
last(scope.(CompositeActionStmt), e, c)
last(scope.(Workflow), e, c) or
last(scope.(CompositeAction), e, c)
}
predicate successorTypeIsSimple(SuccessorType t) { t instanceof NormalSuccessor }
@@ -143,14 +142,14 @@ private import CfgImpl
private import Completion
private import CfgScope
private class CompositeActionTree extends StandardPreOrderTree instanceof CompositeActionStmt {
private class CompositeActionTree extends StandardPreOrderTree instanceof CompositeAction {
override ControlFlowTree getChildNode(int i) {
result =
rank[i](Expression child, Location l |
rank[i](AstNode child, Location l |
(
child = this.(CompositeActionStmt).getInputsStmt() or
child = this.(CompositeActionStmt).getOutputsStmt() or
child = this.(CompositeActionStmt).getRunsStmt()
child = this.(CompositeAction).getAnInput() or
child = this.(CompositeAction).getAnOutput() or
child = this.(CompositeAction).getRuns()
) and
l = child.getLocation()
|
@@ -161,21 +160,21 @@ private class CompositeActionTree extends StandardPreOrderTree instanceof Compos
}
}
private class RunsTree extends StandardPreOrderTree instanceof RunsStmt {
override ControlFlowTree getChildNode(int i) { result = super.getStepStmt(i) }
private class RunsTree extends StandardPreOrderTree instanceof Runs {
override ControlFlowTree getChildNode(int i) { result = super.getStep(i) }
}
private class WorkflowTree extends StandardPreOrderTree instanceof WorkflowStmt {
private class WorkflowTree extends StandardPreOrderTree instanceof Workflow {
override ControlFlowTree getChildNode(int i) {
if this instanceof ReusableWorkflowStmt
if this instanceof ReusableWorkflow
then
result =
rank[i](Expression child, Location l |
rank[i](AstNode child, Location l |
(
child = this.(ReusableWorkflowStmt).getInputsStmt() or
child = this.(ReusableWorkflowStmt).getOutputsStmt() or
child = this.(ReusableWorkflowStmt).getStrategyStmt() or
child = this.(ReusableWorkflowStmt).getAJobStmt()
child = this.(ReusableWorkflow).getAnInput() or
child = this.(ReusableWorkflow).getAnOutput() or
child = this.(ReusableWorkflow).getStrategy() or
child = this.(ReusableWorkflow).getAJob()
) and
l = child.getLocation()
|
@@ -185,10 +184,10 @@ private class WorkflowTree extends StandardPreOrderTree instanceof WorkflowStmt
)
else
result =
rank[i](Expression child, Location l |
rank[i](AstNode child, Location l |
(
child = super.getAJobStmt() or
child = super.getStrategyStmt()
child = super.getAJob() or
child = super.getStrategy()
) and
l = child.getLocation()
|
@@ -199,11 +198,11 @@ private class WorkflowTree extends StandardPreOrderTree instanceof WorkflowStmt
}
}
private class InputsTree extends StandardPreOrderTree instanceof InputsStmt {
private class OutputsTree extends StandardPreOrderTree instanceof Outputs {
override ControlFlowTree getChildNode(int i) {
result =
rank[i](Expression child, Location l |
child = super.getInputExpr(_) and l = child.getLocation()
rank[i](AstNode child, Location l |
child = super.getOutput(_) and l = child.getLocation()
|
child
order by
@@ -212,13 +211,11 @@ private class InputsTree extends StandardPreOrderTree instanceof InputsStmt {
}
}
private class InputExprTree extends LeafTree instanceof InputExpr { }
private class OutputsTree extends StandardPreOrderTree instanceof OutputsStmt {
private class StrategyTree extends StandardPreOrderTree instanceof Strategy {
override ControlFlowTree getChildNode(int i) {
result =
rank[i](Expression child, Location l |
child = super.getOutputExpr(_) and l = child.getLocation()
rank[i](AstNode child, Location l |
child = super.getAMatrixVar() and l = child.getLocation()
|
child
order by
@@ -227,32 +224,15 @@ private class OutputsTree extends StandardPreOrderTree instanceof OutputsStmt {
}
}
private class OutputExprTree extends LeafTree instanceof OutputExpr { }
private class StrategyTree extends StandardPreOrderTree instanceof StrategyStmt {
private class JobTree extends StandardPreOrderTree instanceof Job {
override ControlFlowTree getChildNode(int i) {
result =
rank[i](Expression child, Location l |
child = super.getMatrixVariableExpr(_) and l = child.getLocation()
|
child
order by
l.getStartLine(), l.getStartColumn(), l.getEndColumn(), l.getEndLine(), child.toString()
)
}
}
private class MatrixVariableExprTree extends LeafTree instanceof MatrixVariableExpr { }
private class JobTree extends StandardPreOrderTree instanceof JobStmt {
override ControlFlowTree getChildNode(int i) {
result =
rank[i](Expression child, Location l |
rank[i](AstNode child, Location l |
(
child = super.getAStepStmt() or
child = super.getOutputsStmt() or
child = super.getStrategyStmt() or
child = super.getUsesExpr()
child = super.getAStep() or
child = super.getOutputs() or
child = super.getStrategy() or
child = super.getUses()
) and
l = child.getLocation()
|
@@ -263,13 +243,11 @@ private class JobTree extends StandardPreOrderTree instanceof JobStmt {
}
}
private class UsesExprTree extends LeafTree instanceof UsesExpr { }
private class UsesTree extends StandardPreOrderTree instanceof UsesExpr {
private class UsesTree extends StandardPreOrderTree instanceof Uses {
override ControlFlowTree getChildNode(int i) {
result =
rank[i](Expression child, Location l |
(child = super.getArgumentExpr(_) or child = super.getEnvExpr(_)) and
rank[i](AstNode child, Location l |
(child = super.getArgument(_) or child = super.getEnvVar(_)) and
l = child.getLocation()
|
child
@@ -279,12 +257,11 @@ private class UsesTree extends StandardPreOrderTree instanceof UsesExpr {
}
}
private class RunTree extends StandardPreOrderTree instanceof RunExpr {
//override ControlFlowTree getChildNode(int i) { result = super.getScriptExpr() and i = 0 }
private class RunTree extends StandardPreOrderTree instanceof Run {
override ControlFlowTree getChildNode(int i) {
result =
rank[i](Expression child, Location l |
(child = super.getEnvExpr(_) or child = super.getScriptExpr()) and
rank[i](AstNode child, Location l |
(child = super.getEnvVar(_) or child = super.getScript()) and
l = child.getLocation()
|
child
@@ -294,4 +271,8 @@ private class RunTree extends StandardPreOrderTree instanceof RunExpr {
}
}
private class ExprAccessTree extends LeafTree instanceof ExprAccessExpr { }
private class UsesLeaf extends LeafTree instanceof Uses { }
private class InputTree extends LeafTree instanceof Input { }
private class StringLiteralLeaf extends LeafTree instanceof StringLiteral { }

View File

@@ -42,7 +42,7 @@ predicate sinkModel(string action, string version, string input, string kind) {
predicate externallyDefinedSource(
DataFlow::Node source, string sourceType, string fieldName, string trigger
) {
exists(UsesExpr uses, string action, string version, string kind |
exists(Uses uses, string action, string version, string kind |
sourceModel(action, version, fieldName, trigger, kind) and
uses.getCallee() = action.toLowerCase() and
(
@@ -52,7 +52,7 @@ predicate externallyDefinedSource(
) and
(
if fieldName.trim().matches("env.%")
then source.asExpr() = uses.getEnvExpr(fieldName.trim().replaceAll("env.", ""))
then source.asExpr() = uses.getEnvVar(fieldName.trim().replaceAll("env.", ""))
else
if fieldName.trim().matches("output.%")
then source.asExpr() = uses
@@ -65,7 +65,7 @@ predicate externallyDefinedSource(
predicate externallyDefinedStoreStep(
DataFlow::Node pred, DataFlow::Node succ, DataFlow::ContentSet c
) {
exists(UsesExpr uses, string action, string version, string input, string output |
exists(Uses uses, string action, string version, string input, string output |
summaryModel(action, version, input, output, "taint") and
c = any(DataFlow::FieldContent ct | ct.getName() = output.replaceAll("output.", "")) and
uses.getCallee() = action.toLowerCase() and
@@ -76,10 +76,10 @@ predicate externallyDefinedStoreStep(
) and
(
if input.trim().matches("env.%")
then pred.asExpr() = uses.getEnvExpr(input.trim().replaceAll("env.", ""))
then pred.asExpr() = uses.getEnvVar(input.trim().replaceAll("env.", ""))
else
if input.trim().matches("input.%")
then pred.asExpr() = uses.getArgumentExpr(input.trim().replaceAll("input.", ""))
then pred.asExpr() = uses.getArgument(input.trim().replaceAll("input.", ""))
else none()
) and
succ.asExpr() = uses
@@ -87,13 +87,13 @@ predicate externallyDefinedStoreStep(
}
predicate externallyDefinedSink(DataFlow::ExprNode sink, string kind) {
exists(UsesExpr uses, string action, string version, string input |
exists(Uses uses, string action, string version, string input |
(
if input.trim().matches("env.%")
then sink.asExpr() = uses.getEnvExpr(input.trim().replaceAll("env.", ""))
then sink.asExpr() = uses.getEnvVar(input.trim().replaceAll("env.", ""))
else
if input.trim().matches("input.%")
then sink.asExpr() = uses.getArgumentExpr(input.trim().replaceAll("input.", ""))
then sink.asExpr() = uses.getArgument(input.trim().replaceAll("input.", ""))
else none()
) and
sinkModel(action, version, input, kind) and

View File

@@ -114,7 +114,7 @@ private class EventSource extends RemoteFlowSource {
string trigger;
EventSource() {
exists(ExprAccessExpr e, string context | this.asExpr() = e and context = e.getExpression() |
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
@@ -158,9 +158,9 @@ private class ExternallyDefinedSource extends RemoteFlowSource {
* An input for a Composite Action
*/
private class CompositeActionInputSource extends RemoteFlowSource {
CompositeActionStmt c;
CompositeAction c;
CompositeActionInputSource() { c.getInputsStmt().getInputExpr(_) = this.asExpr() }
CompositeActionInputSource() { c.getAnInput() = this.asExpr() }
override string getSourceType() { result = "Composite action input" }

View File

@@ -34,11 +34,11 @@ class AdditionalTaintStep extends Unit {
* echo "foo=$(echo $BODY)" >> "$GITHUB_OUTPUT"
*/
predicate runEnvToScriptStoreStep(DataFlow::Node pred, DataFlow::Node succ, DataFlow::ContentSet c) {
exists(RunExpr r, string varName, string output |
exists(Run r, string varName, string output |
c = any(DataFlow::FieldContent ct | ct.getName() = output.replaceAll("output\\.", "")) and
r.getEnvExpr(varName) = pred.asExpr() and
r.getEnvVar(varName) = pred.asExpr() and
exists(string script, string line |
script = r.getScript() and
script = r.getScript().getValue() and
line = script.splitAt("\n") and
(
output = line.regexpCapture(".*::set-output\\s+name=(.*)::.*", 1) or

View File

@@ -54,21 +54,27 @@ DataFlowType getNodeType(Node node) { any() }
predicate nodeIsHidden(Node node) { none() }
class DataFlowExpr extends Cfg::Node {
DataFlowExpr() { this.getAstNode() instanceof Expression }
DataFlowExpr() {
this.getAstNode() instanceof Expression or
this.getAstNode() instanceof Uses or
this.getAstNode() instanceof Run or
this.getAstNode() instanceof Outputs or
this.getAstNode() instanceof Input
}
}
/**
* A call corresponds to a Uses steps where a 3rd party action or a reusable workflow get called
*/
class DataFlowCall instanceof Cfg::Node {
DataFlowCall() { super.getAstNode() instanceof UsesExpr }
DataFlowCall() { super.getAstNode() instanceof Uses }
/** Gets a textual representation of this element. */
string toString() { result = super.toString() }
Location getLocation() { result = super.getLocation() }
string getName() { result = super.getAstNode().(UsesExpr).getCallee() }
string getName() { result = super.getAstNode().(Uses).getCallee() }
DataFlowCallable getEnclosingCallable() { result = super.getScope() }
}
@@ -82,11 +88,11 @@ class DataFlowCallable instanceof Cfg::CfgScope {
Location getLocation() { result = super.getLocation() }
string getName() {
if this instanceof ReusableWorkflowStmt
then result = this.(ReusableWorkflowStmt).getLocation().getFile().getRelativePath()
if this instanceof ReusableWorkflow
then result = this.(ReusableWorkflow).getLocation().getFile().getRelativePath()
else
if this instanceof CompositeActionStmt
then result = this.(CompositeActionStmt).getLocation().getFile().getRelativePath()
if this instanceof CompositeAction
then result = this.(CompositeAction).getLocation().getFile().getRelativePath()
else none()
}
}
@@ -134,9 +140,9 @@ predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) { none() }
newtype TContent =
TFieldContent(string name) {
// We only use field flow for steps and jobs outputs, not for accessing other context fields such as env, matrix or inputs
name = any(StepsCtxAccessExpr a).getFieldName() or
name = any(NeedsCtxAccessExpr a).getFieldName() or
name = any(JobsCtxAccessExpr a).getFieldName()
name = any(StepsExpression a).getFieldName() or
name = any(NeedsExpression a).getFieldName() or
name = any(JobsExpression a).getFieldName()
}
predicate forceHighPrecision(Content c) { c instanceof FieldContent }
@@ -149,14 +155,14 @@ ContentApprox getContentApprox(Content c) { result = c }
* Made a string to match the ArgumentPosition type.
*/
class ParameterPosition extends string {
ParameterPosition() { exists(any(ReusableWorkflowStmt w).getInputsStmt().getInputExpr(this)) }
ParameterPosition() { exists(any(ReusableWorkflow w).getInput(this)) }
}
/**
* Made a string to match `With:` keys in the AST
*/
class ArgumentPosition extends string {
ArgumentPosition() { exists(any(UsesExpr e).getArgumentExpr(this)) }
ArgumentPosition() { exists(any(Uses e).getArgument(this)) }
}
/**
@@ -172,11 +178,11 @@ predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos =
* field name.
*/
predicate stepsCtxLocalStep(Node nodeFrom, Node nodeTo) {
exists(UsesExpr astFrom, StepsCtxAccessExpr astTo |
exists(Uses astFrom, StepsExpression astTo |
externallyDefinedSource(nodeFrom, _, "output." + astTo.getFieldName(), _) and
astFrom = nodeFrom.asExpr() and
astTo = nodeTo.asExpr() and
astTo.getRefExpr() = astFrom
astTo.getTarget() = astFrom
)
}
@@ -189,11 +195,11 @@ predicate stepsCtxLocalStep(Node nodeFrom, Node nodeTo) {
* field name.
*/
predicate needsCtxLocalStep(Node nodeFrom, Node nodeTo) {
exists(UsesExpr astFrom, NeedsCtxAccessExpr astTo |
exists(Uses astFrom, NeedsExpression astTo |
externallyDefinedSource(nodeFrom, _, "output." + astTo.getFieldName(), _) and
astFrom = nodeFrom.asExpr() and
astTo = nodeTo.asExpr() and
astTo.getRefExpr() = astFrom
astTo.getTarget() = astFrom
)
}
@@ -202,10 +208,10 @@ predicate needsCtxLocalStep(Node nodeFrom, Node nodeTo) {
* e.g. ${{ inputs.foo }}
*/
predicate inputsCtxLocalStep(Node nodeFrom, Node nodeTo) {
exists(Expression astFrom, InputsCtxAccessExpr astTo |
exists(AstNode astFrom, InputsExpression astTo |
astFrom = nodeFrom.asExpr() and
astTo = nodeTo.asExpr() and
astTo.getRefExpr() = astFrom
astTo.getTarget() = astFrom
)
}
@@ -214,10 +220,10 @@ predicate inputsCtxLocalStep(Node nodeFrom, Node nodeTo) {
* e.g. ${{ matrix.foo }}
*/
predicate matrixCtxLocalStep(Node nodeFrom, Node nodeTo) {
exists(Expression astFrom, MatrixCtxAccessExpr astTo |
exists(AstNode astFrom, MatrixExpression astTo |
astFrom = nodeFrom.asExpr() and
astTo = nodeTo.asExpr() and
astTo.getRefExpr() = astFrom
astTo.getTarget() = astFrom
)
}
@@ -226,12 +232,12 @@ predicate matrixCtxLocalStep(Node nodeFrom, Node nodeTo) {
* e.g. ${{ env.foo }}
*/
predicate envCtxLocalStep(Node nodeFrom, Node nodeTo) {
exists(Expression astFrom, EnvCtxAccessExpr astTo |
exists(Expression astFrom, EnvExpression astTo |
astFrom = nodeFrom.asExpr() and
astTo = nodeTo.asExpr() and
(
externallyDefinedSource(nodeFrom, _, "env." + astTo.getFieldName(), _) or
astTo.getRefExpr() = astFrom
astTo.getTarget() = astFrom
)
)
}
@@ -266,17 +272,17 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) { localFlowStep(nodeFr
predicate jumpStep(Node nodeFrom, Node nodeTo) { none() }
/**
* Holds if a CtxAccessExpr reads a field from a job (needs/jobs), step (steps) output via a read of `c` (fieldname)
* Holds if a Expression reads a field from a job (needs/jobs), step (steps) output via a read of `c` (fieldname)
*/
predicate ctxFieldReadStep(Node node1, Node node2, ContentSet c) {
exists(CtxAccessExpr access |
exists(ContextExpression access |
(
access instanceof NeedsCtxAccessExpr or
access instanceof StepsCtxAccessExpr or
access instanceof JobsCtxAccessExpr
access instanceof NeedsExpression or
access instanceof StepsExpression or
access instanceof JobsExpression
) and
c = any(FieldContent ct | ct.getName() = access.getFieldName()) and
node1.asExpr() = access.getRefExpr() and
node1.asExpr() = access.getTarget() and
node2.asExpr() = access
)
}
@@ -294,8 +300,8 @@ predicate readStep(Node node1, ContentSet c, Node node2) { ctxFieldReadStep(node
* using the output variable name as the access path
*/
predicate fieldStoreStep(Node node1, Node node2, ContentSet c) {
exists(OutputsStmt out, string fieldName |
node1.asExpr() = out.getOutputExpr(fieldName) and
exists(Outputs out, string fieldName |
node1.asExpr() = out.getOutput(fieldName) and
node2.asExpr() = out and
c = any(FieldContent ct | ct.getName() = fieldName)
)

View File

@@ -48,22 +48,19 @@ class ExprNode extends Node, TExprNode {
* Reusable workflow input nodes
*/
class ParameterNode extends ExprNode {
private InputExpr input;
private Input input;
ParameterNode() {
this.asExpr() = input and
input = any(InputsStmt s).getInputExpr(_)
}
ParameterNode() { this.asExpr() = input }
predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
input = c.(ReusableWorkflowStmt).getInputsStmt().getInputExpr(pos)
input = c.(ReusableWorkflow).getInput(pos)
}
override string toString() { result = "input " + input.toString() }
override Location getLocation() { result = input.getLocation() }
InputExpr getInputExpr() { result = input }
Input getInput() { result = input }
}
/**
@@ -81,12 +78,12 @@ class CallNode extends ExprNode {
* An argument to a Uses step (call).
*/
class ArgumentNode extends ExprNode {
ArgumentNode() { this.getCfgNode().getAstNode() = any(UsesExpr e).getArgumentExpr(_) }
ArgumentNode() { this.getCfgNode().getAstNode() = any(Uses e).getArgument(_) }
predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
this.getCfgNode() = call.(Cfg::Node).getASuccessor+() and
call.(Cfg::Node).getAstNode() =
any(UsesExpr e | e.getArgumentExpr(pos) = this.getCfgNode().getAstNode())
any(Uses e | e.getArgument(pos) = this.getCfgNode().getAstNode())
}
}
@@ -94,11 +91,11 @@ class ArgumentNode extends ExprNode {
* Reusable workflow output nodes
*/
class ReturnNode extends ExprNode {
private OutputsStmt outputs;
private Outputs outputs;
ReturnNode() {
this.asExpr() = outputs and
outputs = any(ReusableWorkflowStmt s).getOutputsStmt()
outputs = any(ReusableWorkflow s).getOutputs()
}
ReturnKind getKind() { result = TNormalReturn() }

View File

@@ -1,39 +0,0 @@
---
sourceLocationPrefix: /Users/pwntester/seclab/projects/actions/codeql-actions/ql/lib
baselineLinesOfCode: 0
unicodeNewlines: false
columnKind: utf16
primaryLanguage: yaml
inProgress:
primaryLanguage: yaml
installedExtractors:
go:
- /Users/pwntester/.local/share/nvim/mason/packages/codeql/codeql/go
python:
- /Users/pwntester/.local/share/nvim/mason/packages/codeql/codeql/python
java:
- /Users/pwntester/.local/share/nvim/mason/packages/codeql/codeql/java
html:
- /Users/pwntester/.local/share/nvim/mason/packages/codeql/codeql/html
xml:
- /Users/pwntester/.local/share/nvim/mason/packages/codeql/codeql/xml
properties:
- /Users/pwntester/.local/share/nvim/mason/packages/codeql/codeql/properties
cpp:
- /Users/pwntester/.local/share/nvim/mason/packages/codeql/codeql/cpp
swift:
- /Users/pwntester/.local/share/nvim/mason/packages/codeql/codeql/swift
csv:
- /Users/pwntester/.local/share/nvim/mason/packages/codeql/codeql/csv
yaml:
- /Users/pwntester/.local/share/nvim/mason/packages/codeql/codeql/yaml
csharp:
- /Users/pwntester/.local/share/nvim/mason/packages/codeql/codeql/csharp
javascript:
- /Users/pwntester/.local/share/nvim/mason/packages/codeql/codeql/javascript
ruby:
- /Users/pwntester/.local/share/nvim/mason/packages/codeql/codeql/ruby
creationMetadata:
cliVersion: 2.16.0
creationTime: 2024-02-02T10:02:02.082819Z
finalised: false

View File

@@ -15,7 +15,7 @@ import PartialFlow::PartialPathGraph
private module MyConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source instanceof RemoteFlowSource and
source.getLocation().getFile().getBaseName() = "matrix.yml"
source.getLocation().getFile().getBaseName() = "argus_case_study.yml"
}
predicate isSink(DataFlow::Node sink) { none() }

View File

@@ -18,14 +18,14 @@ import codeql.actions.dataflow.ExternalFlow
private class ExpressionInjectionSink extends DataFlow::Node {
ExpressionInjectionSink() {
exists(RunExpr e | e.getScriptExpr() = this.asExpr()) or
exists(Run e | e.getScript() = this.asExpr()) or
externallyDefinedSink(this, "expression-injection")
}
}
private module MyConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
exists(CompositeActionStmt c | c.getInputsStmt().getInputExpr(_) = source.asExpr())
exists(CompositeAction c | c.getAnInput() = source.asExpr())
}
predicate isSink(DataFlow::Node sink) { sink instanceof ExpressionInjectionSink }

View File

@@ -20,11 +20,11 @@ private module MyConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source instanceof RemoteFlowSource and
not source instanceof DataFlow::ParameterNode and
exists(CompositeActionStmt c | c.getAChildNode*() = source.asExpr())
exists(CompositeAction c | c.getAChildNode*() = source.asExpr())
}
predicate isSink(DataFlow::Node sink) {
exists(CompositeActionStmt c | c.getOutputsStmt().getOutputExpr(_) = sink.asExpr())
exists(CompositeAction c | c.getAnOutput() = sink.asExpr())
}
predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet set) {

View File

@@ -18,11 +18,11 @@ import codeql.actions.dataflow.ExternalFlow
private module MyConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
exists(CompositeActionStmt c | c.getInputsStmt().getInputExpr(_) = source.asExpr())
exists(CompositeAction c | c.getAnInput() = source.asExpr())
}
predicate isSink(DataFlow::Node sink) {
exists(CompositeActionStmt c | c.getOutputsStmt().getOutputExpr(_) = sink.asExpr())
exists(CompositeAction c | c.getAnOutput() = sink.asExpr())
}
}

View File

@@ -18,14 +18,14 @@ import codeql.actions.dataflow.ExternalFlow
private class ExpressionInjectionSink extends DataFlow::Node {
ExpressionInjectionSink() {
exists(RunExpr e | e.getScriptExpr() = this.asExpr()) or
exists(Run e | e.getScript() = this.asExpr()) or
externallyDefinedSink(this, "expression-injection")
}
}
private module MyConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
exists(ReusableWorkflowStmt w | w.getInputsStmt().getInputExpr(_) = source.asExpr())
exists(ReusableWorkflow w | w.getAnInput() = source.asExpr())
}
predicate isSink(DataFlow::Node sink) { sink instanceof ExpressionInjectionSink }

View File

@@ -20,11 +20,11 @@ private module MyConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source instanceof RemoteFlowSource and
not source instanceof DataFlow::ParameterNode and
exists(ReusableWorkflowStmt w | w.getAChildNode*() = source.asExpr())
exists(ReusableWorkflow w | w.getAChildNode*() = source.asExpr())
}
predicate isSink(DataFlow::Node sink) {
exists(ReusableWorkflowStmt w | w.getOutputsStmt().getOutputExpr(_) = sink.asExpr())
exists(ReusableWorkflow w | w.getAnOutput() = sink.asExpr())
}
predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet set) {

View File

@@ -18,11 +18,11 @@ import codeql.actions.dataflow.ExternalFlow
private module MyConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
exists(ReusableWorkflowStmt w | w.getInputsStmt().getInputExpr(_) = source.asExpr())
exists(ReusableWorkflow w | w.getAnInput() = source.asExpr())
}
predicate isSink(DataFlow::Node sink) {
exists(ReusableWorkflowStmt w | w.getOutputsStmt().getOutputExpr(_) = sink.asExpr())
exists(ReusableWorkflow w | w.getAnOutput() = sink.asExpr())
}
}

View File

@@ -19,7 +19,7 @@ import codeql.actions.dataflow.ExternalFlow
private class ExpressionInjectionSink extends DataFlow::Node {
ExpressionInjectionSink() {
exists(RunExpr e | e.getScriptExpr() = this.asExpr()) or
exists(Run e | e.getScript() = this.asExpr()) or
externallyDefinedSink(this, "expression-injection")
}
}
@@ -40,8 +40,7 @@ where
source
.getNode()
.asExpr()
.(Statement)
.getEnclosingWorkflowStmt()
.getEnclosingWorkflow()
.hasTriggerEvent(source.getNode().(RemoteFlowSource).getATriggerEvent())
select sink.getNode(), source, sink,
"Potential expression injection, which may be controlled by an external user."

View File

@@ -19,7 +19,7 @@ import codeql.actions.dataflow.ExternalFlow
private class ExpressionInjectionSink extends DataFlow::Node {
ExpressionInjectionSink() {
exists(RunExpr e | e.getScriptExpr() = this.asExpr()) or
exists(Run e | e.getScript() = this.asExpr()) or
externallyDefinedSink(this, "expression-injection")
}
}

View File

@@ -13,11 +13,11 @@
import actions
from WorkflowStmt workflow, JobStmt job
from Workflow workflow, Job job
where
job = workflow.getAJobStmt() and
job = workflow.getAJob() and
(
not exists(workflow.getPermissionsStmt()) and
not exists(job.getPermissionsStmt())
not exists(workflow.getPermissions()) and
not exists(job.getPermissions())
)
select job, "Actions Job or Workflow does not set permissions"

View File

@@ -21,10 +21,10 @@ private predicate isTrustedOrg(string repo) {
exists(string org | org in ["actions", "github", "advanced-security"] | repo.matches(org + "/%"))
}
from StepUsesExpr uses, string repo, string version, WorkflowStmt workflow, string name
from UsesStep uses, string repo, string version, Workflow workflow, string name
where
uses.getCallee() = repo and
uses.getEnclosingWorkflowStmt() = workflow and
uses.getEnclosingWorkflow() = workflow and
(
workflow.getName() = name
or

View File

@@ -18,34 +18,34 @@ import actions
/**
* An If node that contains an `actor` check
*/
class ActorCheckStmt extends IfStmt {
ActorCheckStmt() { this.getCondition().regexpMatch(".*github\\.(triggering_)?actor.*") }
class ActorCheck extends If {
ActorCheck() { this.getCondition().regexpMatch(".*github\\.(triggering_)?actor.*") }
}
/**
* An If node that contains a `label` check
*/
class LabelCheckStmt extends IfStmt {
LabelCheckStmt() {
class LabelCheck extends If {
LabelCheck() {
this.getCondition().regexpMatch(".*github\\.event\\.pull_request\\.labels.*") or
this.getCondition().regexpMatch(".*github\\.event\\.label\\.name.*")
}
}
from WorkflowStmt w, JobStmt job, StepUsesExpr checkoutStep
from Workflow w, Job job, UsesStep checkoutStep
where
w.hasTriggerEvent("pull_request_target") and
w.getAJobStmt() = job and
job.getAStepStmt() = checkoutStep and
w.getAJob() = job and
job.getAStep() = checkoutStep and
checkoutStep.getCallee() = "actions/checkout" and
checkoutStep
.getArgumentExpr("ref")
.(ExprAccessExpr)
.getArgument("ref")
.(Expression)
.getExpression()
.matches([
"%github.event.pull_request.head.ref%", "%github.event.pull_request.head.sha%",
"%github.event.pull_request.number%", "%github.event.number%", "%github.head_ref%"
]) and
not exists(ActorCheckStmt check | job.getIfStmt() = check or checkoutStep.getIfStmt() = check) and
not exists(LabelCheckStmt check | job.getIfStmt() = check or checkoutStep.getIfStmt() = check)
not exists(ActorCheck check | job.getIf() = check or checkoutStep.getIf() = check) and
not exists(LabelCheck check | job.getIf() = check or checkoutStep.getIf() = check)
select checkoutStep, "Potential unsafe checkout of untrusted pull request on 'pull_request_target'."

View File

@@ -71,205 +71,179 @@ yamlNodes
| .github/workflows/test.yml:40:9:40:11 | run |
| .github/workflows/test.yml:40:14:40:52 | echo ${ ... utput}} |
jobNodes
| .github/workflows/test.yml:5:5:31:2 | runs-on ... -latest |
| .github/workflows/test.yml:32:5:40:53 | runs-on ... -latest |
| .github/workflows/test.yml:5:5:31:2 | Job: job1 |
| .github/workflows/test.yml:32:5:40:53 | Job: job2 |
stepNodes
| .github/workflows/test.yml:11:9:15:6 | uses: a ... kout@v4 |
| .github/workflows/test.yml:15:9:19:6 | name: G ... d files |
| .github/workflows/test.yml:19:9:26:6 | name: R ... d files |
| .github/workflows/test.yml:26:9:28:6 | id: simplesink1 |
| .github/workflows/test.yml:28:9:31:2 | id: simplesink2 |
| .github/workflows/test.yml:39:9:40:53 | id: sink |
| .github/workflows/test.yml:11:9:15:6 | Uses Step |
| .github/workflows/test.yml:15:9:19:6 | Uses Step: source |
| .github/workflows/test.yml:19:9:26:6 | Uses Step: step |
| .github/workflows/test.yml:26:9:28:6 | Run Step: simplesink1 |
| .github/workflows/test.yml:28:9:31:2 | Run Step: simplesink2 |
| .github/workflows/test.yml:39:9:40:53 | Run Step: sink |
allUsesNodes
| .github/workflows/test.yml:11:9:15:6 | uses: a ... kout@v4 |
| .github/workflows/test.yml:15:9:19:6 | name: G ... d files |
| .github/workflows/test.yml:19:9:26:6 | name: R ... d files |
| .github/workflows/test.yml:11:9:15:6 | Uses Step |
| .github/workflows/test.yml:15:9:19:6 | Uses Step: source |
| .github/workflows/test.yml:19:9:26:6 | Uses Step: step |
stepUsesNodes
| .github/workflows/test.yml:11:9:15:6 | uses: a ... kout@v4 |
| .github/workflows/test.yml:15:9:19:6 | name: G ... d files |
| .github/workflows/test.yml:19:9:26:6 | name: R ... d files |
| .github/workflows/test.yml:11:9:15:6 | Uses Step |
| .github/workflows/test.yml:15:9:19:6 | Uses Step: source |
| .github/workflows/test.yml:19:9:26:6 | Uses Step: step |
jobUsesNodes
| .github/workflows/test.yml:11:9:15:6 | Uses Step |
| .github/workflows/test.yml:15:9:19:6 | Uses Step: source |
| .github/workflows/test.yml:19:9:26:6 | Uses Step: step |
usesSteps
| .github/workflows/test.yml:11:9:15:6 | uses: a ... kout@v4 | fetch-depth | .github/workflows/test.yml:13:24:13:24 | 0 |
| .github/workflows/test.yml:19:9:26:6 | name: R ... d files | find | .github/workflows/test.yml:24:17:24:21 | "foo" |
| .github/workflows/test.yml:19:9:26:6 | name: R ... d files | replace | .github/workflows/test.yml:25:20:25:21 | "" |
| .github/workflows/test.yml:19:9:26:6 | name: R ... d files | source | .github/workflows/test.yml:23:19:23:63 | ${{ ste ... iles }} |
runSteps1
| .github/workflows/test.yml:26:9:28:6 | id: simplesink1 | echo ${{ steps.source.outputs.all_changed_files }} |
| .github/workflows/test.yml:28:9:31:2 | id: simplesink2 | ${{ github.event.pull_request.head.ref }} |
| .github/workflows/test.yml:39:9:40:53 | id: sink | echo ${{needs.job1.outputs.job_output}} |
runSteps2
| .github/workflows/test.yml:26:9:28:6 | id: simplesink1 | .github/workflows/test.yml:27:14:27:63 | echo ${ ... iles }} |
| .github/workflows/test.yml:28:9:31:2 | id: simplesink2 | .github/workflows/test.yml:29:14:29:54 | ${{ git ... .ref }} |
| .github/workflows/test.yml:39:9:40:53 | id: sink | .github/workflows/test.yml:40:14:40:52 | echo ${ ... utput}} |
| .github/workflows/test.yml:19:9:26:6 | Uses Step: step | source | .github/workflows/test.yml:23:19:23:63 | ${{ ste ... iles }} |
runSteps
| .github/workflows/test.yml:26:9:28:6 | Run Step: simplesink1 | echo ${{ steps.source.outputs.all_changed_files }} |
| .github/workflows/test.yml:28:9:31:2 | Run Step: simplesink2 | ${{ github.event.pull_request.head.ref }} |
| .github/workflows/test.yml:39:9:40:53 | Run Step: sink | echo ${{needs.job1.outputs.job_output}} |
runStepChildren
| .github/workflows/test.yml:26:9:28:6 | id: simplesink1 | .github/workflows/test.yml:26:9:26:10 | id |
| .github/workflows/test.yml:26:9:28:6 | id: simplesink1 | .github/workflows/test.yml:26:13:26:23 | simplesink1 |
| .github/workflows/test.yml:26:9:28:6 | id: simplesink1 | .github/workflows/test.yml:27:9:27:11 | run |
| .github/workflows/test.yml:26:9:28:6 | id: simplesink1 | .github/workflows/test.yml:27:14:27:63 | echo ${ ... iles }} |
| .github/workflows/test.yml:28:9:31:2 | id: simplesink2 | .github/workflows/test.yml:28:9:28:10 | id |
| .github/workflows/test.yml:28:9:31:2 | id: simplesink2 | .github/workflows/test.yml:28:13:28:23 | simplesink2 |
| .github/workflows/test.yml:28:9:31:2 | id: simplesink2 | .github/workflows/test.yml:29:9:29:11 | run |
| .github/workflows/test.yml:28:9:31:2 | id: simplesink2 | .github/workflows/test.yml:29:14:29:54 | ${{ git ... .ref }} |
| .github/workflows/test.yml:39:9:40:53 | id: sink | .github/workflows/test.yml:39:9:39:10 | id |
| .github/workflows/test.yml:39:9:40:53 | id: sink | .github/workflows/test.yml:39:13:39:16 | sink |
| .github/workflows/test.yml:39:9:40:53 | id: sink | .github/workflows/test.yml:40:9:40:11 | run |
| .github/workflows/test.yml:39:9:40:53 | id: sink | .github/workflows/test.yml:40:14:40:52 | echo ${ ... utput}} |
varAccesses
| .github/workflows/test.yml:8:19:8:49 | ${{ ste ... alue }} | steps.step.outputs.value |
| .github/workflows/test.yml:23:19:23:63 | ${{ ste ... iles }} | steps.source.outputs.all_changed_files |
| .github/workflows/test.yml:27:14:27:63 | echo ${ ... iles }} | steps.source.outputs.all_changed_files |
| .github/workflows/test.yml:29:14:29:54 | ${{ git ... .ref }} | github.event.pull_request.head.ref |
| .github/workflows/test.yml:34:9:34:23 | ${{ always() }} | always() |
| .github/workflows/test.yml:40:14:40:52 | echo ${ ... utput}} | needs.job1.outputs.job_output |
orphanVarAccesses
nonOrphanVarAccesses
| .github/workflows/test.yml:8:19:8:49 | ${{ ste ... alue }} | steps.step.outputs.value | .github/workflows/test.yml:8:7:10:4 | job_out ... alue }} |
| .github/workflows/test.yml:23:19:23:63 | ${{ ste ... iles }} | steps.source.outputs.all_changed_files | .github/workflows/test.yml:23:11:26:6 | source: ... iles }} |
| .github/workflows/test.yml:27:14:27:63 | echo ${ ... iles }} | steps.source.outputs.all_changed_files | .github/workflows/test.yml:26:9:28:6 | id: simplesink1 |
| .github/workflows/test.yml:29:14:29:54 | ${{ git ... .ref }} | github.event.pull_request.head.ref | .github/workflows/test.yml:28:9:31:2 | id: simplesink2 |
| .github/workflows/test.yml:34:9:34:23 | ${{ always() }} | always() | .github/workflows/test.yml:32:5:40:53 | runs-on ... -latest |
| .github/workflows/test.yml:40:14:40:52 | echo ${ ... utput}} | needs.job1.outputs.job_output | .github/workflows/test.yml:39:9:40:53 | id: sink |
| .github/workflows/test.yml:26:9:28:6 | Run Step: simplesink1 | .github/workflows/test.yml:26:9:26:10 | id |
| .github/workflows/test.yml:26:9:28:6 | Run Step: simplesink1 | .github/workflows/test.yml:26:13:26:23 | simplesink1 |
| .github/workflows/test.yml:26:9:28:6 | Run Step: simplesink1 | .github/workflows/test.yml:27:9:27:11 | run |
| .github/workflows/test.yml:26:9:28:6 | Run Step: simplesink1 | .github/workflows/test.yml:27:14:27:63 | echo ${ ... iles }} |
| .github/workflows/test.yml:28:9:31:2 | Run Step: simplesink2 | .github/workflows/test.yml:28:9:28:10 | id |
| .github/workflows/test.yml:28:9:31:2 | Run Step: simplesink2 | .github/workflows/test.yml:28:13:28:23 | simplesink2 |
| .github/workflows/test.yml:28:9:31:2 | Run Step: simplesink2 | .github/workflows/test.yml:29:9:29:11 | run |
| .github/workflows/test.yml:28:9:31:2 | Run Step: simplesink2 | .github/workflows/test.yml:29:14:29:54 | ${{ git ... .ref }} |
| .github/workflows/test.yml:39:9:40:53 | Run Step: sink | .github/workflows/test.yml:39:9:39:10 | id |
| .github/workflows/test.yml:39:9:40:53 | Run Step: sink | .github/workflows/test.yml:39:13:39:16 | sink |
| .github/workflows/test.yml:39:9:40:53 | Run Step: sink | .github/workflows/test.yml:40:9:40:11 | run |
| .github/workflows/test.yml:39:9:40:53 | Run Step: sink | .github/workflows/test.yml:40:14:40:52 | echo ${ ... utput}} |
parentNodes
| .github/workflows/test.yml:1:1:1:2 | on | .github/workflows/test.yml:1:1:40:53 | on: push |
| .github/workflows/test.yml:1:5:1:8 | push | .github/workflows/test.yml:1:1:40:53 | on: push |
| .github/workflows/test.yml:3:1:3:4 | jobs | .github/workflows/test.yml:1:1:40:53 | on: push |
| .github/workflows/test.yml:4:3:4:6 | job1 | .github/workflows/test.yml:4:3:40:53 | job1: |
| .github/workflows/test.yml:4:3:40:53 | job1: | .github/workflows/test.yml:1:1:40:53 | on: push |
| .github/workflows/test.yml:5:5:5:11 | runs-on | .github/workflows/test.yml:5:5:31:2 | runs-on ... -latest |
| .github/workflows/test.yml:5:5:31:2 | runs-on ... -latest | .github/workflows/test.yml:4:3:40:53 | job1: |
| .github/workflows/test.yml:5:14:5:26 | ubuntu-latest | .github/workflows/test.yml:5:5:31:2 | runs-on ... -latest |
| .github/workflows/test.yml:7:5:7:11 | outputs | .github/workflows/test.yml:5:5:31:2 | runs-on ... -latest |
| .github/workflows/test.yml:8:7:8:16 | job_output | .github/workflows/test.yml:8:7:10:4 | job_out ... alue }} |
| .github/workflows/test.yml:8:7:10:4 | job_out ... alue }} | .github/workflows/test.yml:5:5:31:2 | runs-on ... -latest |
| .github/workflows/test.yml:8:19:8:49 | ${{ ste ... alue }} | .github/workflows/test.yml:8:7:10:4 | job_out ... alue }} |
| .github/workflows/test.yml:10:5:10:9 | steps | .github/workflows/test.yml:5:5:31:2 | runs-on ... -latest |
| .github/workflows/test.yml:11:7:31:2 | - uses: ... kout@v4 | .github/workflows/test.yml:5:5:31:2 | runs-on ... -latest |
| .github/workflows/test.yml:11:9:11:12 | uses | .github/workflows/test.yml:11:9:15:6 | uses: a ... kout@v4 |
| .github/workflows/test.yml:11:9:15:6 | uses: a ... kout@v4 | .github/workflows/test.yml:11:7:31:2 | - uses: ... kout@v4 |
| .github/workflows/test.yml:11:15:11:33 | actions/checkout@v4 | .github/workflows/test.yml:11:9:15:6 | uses: a ... kout@v4 |
| .github/workflows/test.yml:12:9:12:12 | with | .github/workflows/test.yml:11:9:15:6 | uses: a ... kout@v4 |
| .github/workflows/test.yml:5:5:5:11 | runs-on | .github/workflows/test.yml:5:5:31:2 | Job: job1 |
| .github/workflows/test.yml:5:5:31:2 | Job: job1 | .github/workflows/test.yml:4:3:40:53 | job1: |
| .github/workflows/test.yml:5:14:5:26 | ubuntu-latest | .github/workflows/test.yml:5:5:31:2 | Job: job1 |
| .github/workflows/test.yml:7:5:7:11 | outputs | .github/workflows/test.yml:5:5:31:2 | Job: job1 |
| .github/workflows/test.yml:8:7:8:16 | job_output | .github/workflows/test.yml:8:7:10:4 | Job outputs node |
| .github/workflows/test.yml:8:7:10:4 | Job outputs node | .github/workflows/test.yml:5:5:31:2 | Job: job1 |
| .github/workflows/test.yml:8:19:8:49 | ${{ ste ... alue }} | .github/workflows/test.yml:8:7:10:4 | Job outputs node |
| .github/workflows/test.yml:10:5:10:9 | steps | .github/workflows/test.yml:5:5:31:2 | Job: job1 |
| .github/workflows/test.yml:11:7:31:2 | - uses: ... kout@v4 | .github/workflows/test.yml:5:5:31:2 | Job: job1 |
| .github/workflows/test.yml:11:9:11:12 | uses | .github/workflows/test.yml:11:9:15:6 | Uses Step |
| .github/workflows/test.yml:11:9:15:6 | Uses Step | .github/workflows/test.yml:11:7:31:2 | - uses: ... kout@v4 |
| .github/workflows/test.yml:11:15:11:33 | actions/checkout@v4 | .github/workflows/test.yml:11:9:15:6 | Uses Step |
| .github/workflows/test.yml:12:9:12:12 | with | .github/workflows/test.yml:11:9:15:6 | Uses Step |
| .github/workflows/test.yml:13:11:13:21 | fetch-depth | .github/workflows/test.yml:13:11:15:6 | fetch-depth: 0 |
| .github/workflows/test.yml:13:11:15:6 | fetch-depth: 0 | .github/workflows/test.yml:11:9:15:6 | uses: a ... kout@v4 |
| .github/workflows/test.yml:13:11:15:6 | fetch-depth: 0 | .github/workflows/test.yml:11:9:15:6 | Uses Step |
| .github/workflows/test.yml:13:24:13:24 | 0 | .github/workflows/test.yml:13:11:15:6 | fetch-depth: 0 |
| .github/workflows/test.yml:15:9:15:12 | name | .github/workflows/test.yml:15:9:19:6 | name: G ... d files |
| .github/workflows/test.yml:15:9:19:6 | name: G ... d files | .github/workflows/test.yml:11:7:31:2 | - uses: ... kout@v4 |
| .github/workflows/test.yml:15:15:15:31 | Get changed files | .github/workflows/test.yml:15:9:19:6 | name: G ... d files |
| .github/workflows/test.yml:16:9:16:10 | id | .github/workflows/test.yml:15:9:19:6 | name: G ... d files |
| .github/workflows/test.yml:16:13:16:18 | source | .github/workflows/test.yml:15:9:19:6 | name: G ... d files |
| .github/workflows/test.yml:17:9:17:12 | uses | .github/workflows/test.yml:15:9:19:6 | name: G ... d files |
| .github/workflows/test.yml:17:15:17:42 | tj-acti ... les@v40 | .github/workflows/test.yml:15:9:19:6 | name: G ... d files |
| .github/workflows/test.yml:19:9:19:12 | name | .github/workflows/test.yml:19:9:26:6 | name: R ... d files |
| .github/workflows/test.yml:19:9:26:6 | name: R ... d files | .github/workflows/test.yml:11:7:31:2 | - uses: ... kout@v4 |
| .github/workflows/test.yml:19:15:19:43 | Remove ... d files | .github/workflows/test.yml:19:9:26:6 | name: R ... d files |
| .github/workflows/test.yml:20:9:20:10 | id | .github/workflows/test.yml:19:9:26:6 | name: R ... d files |
| .github/workflows/test.yml:20:13:20:16 | step | .github/workflows/test.yml:19:9:26:6 | name: R ... d files |
| .github/workflows/test.yml:21:9:21:12 | uses | .github/workflows/test.yml:19:9:26:6 | name: R ... d files |
| .github/workflows/test.yml:21:15:21:55 | mad9000 ... tring@3 | .github/workflows/test.yml:19:9:26:6 | name: R ... d files |
| .github/workflows/test.yml:22:9:22:12 | with | .github/workflows/test.yml:19:9:26:6 | name: R ... d files |
| .github/workflows/test.yml:15:9:15:12 | name | .github/workflows/test.yml:15:9:19:6 | Uses Step: source |
| .github/workflows/test.yml:15:9:19:6 | Uses Step: source | .github/workflows/test.yml:11:7:31:2 | - uses: ... kout@v4 |
| .github/workflows/test.yml:15:15:15:31 | Get changed files | .github/workflows/test.yml:15:9:19:6 | Uses Step: source |
| .github/workflows/test.yml:16:9:16:10 | id | .github/workflows/test.yml:15:9:19:6 | Uses Step: source |
| .github/workflows/test.yml:16:13:16:18 | source | .github/workflows/test.yml:15:9:19:6 | Uses Step: source |
| .github/workflows/test.yml:17:9:17:12 | uses | .github/workflows/test.yml:15:9:19:6 | Uses Step: source |
| .github/workflows/test.yml:17:15:17:42 | tj-acti ... les@v40 | .github/workflows/test.yml:15:9:19:6 | Uses Step: source |
| .github/workflows/test.yml:19:9:19:12 | name | .github/workflows/test.yml:19:9:26:6 | Uses Step: step |
| .github/workflows/test.yml:19:9:26:6 | Uses Step: step | .github/workflows/test.yml:11:7:31:2 | - uses: ... kout@v4 |
| .github/workflows/test.yml:19:15:19:43 | Remove ... d files | .github/workflows/test.yml:19:9:26:6 | Uses Step: step |
| .github/workflows/test.yml:20:9:20:10 | id | .github/workflows/test.yml:19:9:26:6 | Uses Step: step |
| .github/workflows/test.yml:20:13:20:16 | step | .github/workflows/test.yml:19:9:26:6 | Uses Step: step |
| .github/workflows/test.yml:21:9:21:12 | uses | .github/workflows/test.yml:19:9:26:6 | Uses Step: step |
| .github/workflows/test.yml:21:15:21:55 | mad9000 ... tring@3 | .github/workflows/test.yml:19:9:26:6 | Uses Step: step |
| .github/workflows/test.yml:22:9:22:12 | with | .github/workflows/test.yml:19:9:26:6 | Uses Step: step |
| .github/workflows/test.yml:23:11:23:16 | source | .github/workflows/test.yml:23:11:26:6 | source: ... iles }} |
| .github/workflows/test.yml:23:11:26:6 | source: ... iles }} | .github/workflows/test.yml:19:9:26:6 | name: R ... d files |
| .github/workflows/test.yml:23:11:26:6 | source: ... iles }} | .github/workflows/test.yml:19:9:26:6 | Uses Step: step |
| .github/workflows/test.yml:23:19:23:63 | ${{ ste ... iles }} | .github/workflows/test.yml:23:11:26:6 | source: ... iles }} |
| .github/workflows/test.yml:24:11:24:14 | find | .github/workflows/test.yml:23:11:26:6 | source: ... iles }} |
| .github/workflows/test.yml:24:17:24:21 | "foo" | .github/workflows/test.yml:23:11:26:6 | source: ... iles }} |
| .github/workflows/test.yml:25:11:25:17 | replace | .github/workflows/test.yml:23:11:26:6 | source: ... iles }} |
| .github/workflows/test.yml:25:20:25:21 | "" | .github/workflows/test.yml:23:11:26:6 | source: ... iles }} |
| .github/workflows/test.yml:26:9:26:10 | id | .github/workflows/test.yml:26:9:28:6 | id: simplesink1 |
| .github/workflows/test.yml:26:9:28:6 | id: simplesink1 | .github/workflows/test.yml:11:7:31:2 | - uses: ... kout@v4 |
| .github/workflows/test.yml:26:13:26:23 | simplesink1 | .github/workflows/test.yml:26:9:28:6 | id: simplesink1 |
| .github/workflows/test.yml:27:9:27:11 | run | .github/workflows/test.yml:26:9:28:6 | id: simplesink1 |
| .github/workflows/test.yml:27:14:27:63 | echo ${ ... iles }} | .github/workflows/test.yml:26:9:28:6 | id: simplesink1 |
| .github/workflows/test.yml:28:9:28:10 | id | .github/workflows/test.yml:28:9:31:2 | id: simplesink2 |
| .github/workflows/test.yml:28:9:31:2 | id: simplesink2 | .github/workflows/test.yml:11:7:31:2 | - uses: ... kout@v4 |
| .github/workflows/test.yml:28:13:28:23 | simplesink2 | .github/workflows/test.yml:28:9:31:2 | id: simplesink2 |
| .github/workflows/test.yml:29:9:29:11 | run | .github/workflows/test.yml:28:9:31:2 | id: simplesink2 |
| .github/workflows/test.yml:29:14:29:54 | ${{ git ... .ref }} | .github/workflows/test.yml:28:9:31:2 | id: simplesink2 |
| .github/workflows/test.yml:26:9:26:10 | id | .github/workflows/test.yml:26:9:28:6 | Run Step: simplesink1 |
| .github/workflows/test.yml:26:9:28:6 | Run Step: simplesink1 | .github/workflows/test.yml:11:7:31:2 | - uses: ... kout@v4 |
| .github/workflows/test.yml:26:13:26:23 | simplesink1 | .github/workflows/test.yml:26:9:28:6 | Run Step: simplesink1 |
| .github/workflows/test.yml:27:9:27:11 | run | .github/workflows/test.yml:26:9:28:6 | Run Step: simplesink1 |
| .github/workflows/test.yml:27:14:27:63 | echo ${ ... iles }} | .github/workflows/test.yml:26:9:28:6 | Run Step: simplesink1 |
| .github/workflows/test.yml:28:9:28:10 | id | .github/workflows/test.yml:28:9:31:2 | Run Step: simplesink2 |
| .github/workflows/test.yml:28:9:31:2 | Run Step: simplesink2 | .github/workflows/test.yml:11:7:31:2 | - uses: ... kout@v4 |
| .github/workflows/test.yml:28:13:28:23 | simplesink2 | .github/workflows/test.yml:28:9:31:2 | Run Step: simplesink2 |
| .github/workflows/test.yml:29:9:29:11 | run | .github/workflows/test.yml:28:9:31:2 | Run Step: simplesink2 |
| .github/workflows/test.yml:29:14:29:54 | ${{ git ... .ref }} | .github/workflows/test.yml:28:9:31:2 | Run Step: simplesink2 |
| .github/workflows/test.yml:31:3:31:6 | job2 | .github/workflows/test.yml:4:3:40:53 | job1: |
| .github/workflows/test.yml:32:5:32:11 | runs-on | .github/workflows/test.yml:32:5:40:53 | runs-on ... -latest |
| .github/workflows/test.yml:32:5:40:53 | runs-on ... -latest | .github/workflows/test.yml:4:3:40:53 | job1: |
| .github/workflows/test.yml:32:14:32:26 | ubuntu-latest | .github/workflows/test.yml:32:5:40:53 | runs-on ... -latest |
| .github/workflows/test.yml:34:5:34:6 | if | .github/workflows/test.yml:32:5:40:53 | runs-on ... -latest |
| .github/workflows/test.yml:34:9:34:23 | ${{ always() }} | .github/workflows/test.yml:32:5:40:53 | runs-on ... -latest |
| .github/workflows/test.yml:36:5:36:9 | needs | .github/workflows/test.yml:32:5:40:53 | runs-on ... -latest |
| .github/workflows/test.yml:36:12:36:15 | job1 | .github/workflows/test.yml:32:5:40:53 | runs-on ... -latest |
| .github/workflows/test.yml:38:5:38:9 | steps | .github/workflows/test.yml:32:5:40:53 | runs-on ... -latest |
| .github/workflows/test.yml:39:7:40:53 | - id: sink | .github/workflows/test.yml:32:5:40:53 | runs-on ... -latest |
| .github/workflows/test.yml:39:9:39:10 | id | .github/workflows/test.yml:39:9:40:53 | id: sink |
| .github/workflows/test.yml:39:9:40:53 | id: sink | .github/workflows/test.yml:39:7:40:53 | - id: sink |
| .github/workflows/test.yml:39:13:39:16 | sink | .github/workflows/test.yml:39:9:40:53 | id: sink |
| .github/workflows/test.yml:40:9:40:11 | run | .github/workflows/test.yml:39:9:40:53 | id: sink |
| .github/workflows/test.yml:40:14:40:52 | echo ${ ... utput}} | .github/workflows/test.yml:39:9:40:53 | id: sink |
| .github/workflows/test.yml:32:5:32:11 | runs-on | .github/workflows/test.yml:32:5:40:53 | Job: job2 |
| .github/workflows/test.yml:32:5:40:53 | Job: job2 | .github/workflows/test.yml:4:3:40:53 | job1: |
| .github/workflows/test.yml:32:14:32:26 | ubuntu-latest | .github/workflows/test.yml:32:5:40:53 | Job: job2 |
| .github/workflows/test.yml:34:5:34:6 | if | .github/workflows/test.yml:32:5:40:53 | Job: job2 |
| .github/workflows/test.yml:34:9:34:23 | ${{ always() }} | .github/workflows/test.yml:32:5:40:53 | Job: job2 |
| .github/workflows/test.yml:36:5:36:9 | needs | .github/workflows/test.yml:32:5:40:53 | Job: job2 |
| .github/workflows/test.yml:36:12:36:15 | job1 | .github/workflows/test.yml:32:5:40:53 | Job: job2 |
| .github/workflows/test.yml:38:5:38:9 | steps | .github/workflows/test.yml:32:5:40:53 | Job: job2 |
| .github/workflows/test.yml:39:7:40:53 | - id: sink | .github/workflows/test.yml:32:5:40:53 | Job: job2 |
| .github/workflows/test.yml:39:9:39:10 | id | .github/workflows/test.yml:39:9:40:53 | Run Step: sink |
| .github/workflows/test.yml:39:9:40:53 | Run Step: sink | .github/workflows/test.yml:39:7:40:53 | - id: sink |
| .github/workflows/test.yml:39:13:39:16 | sink | .github/workflows/test.yml:39:9:40:53 | Run Step: sink |
| .github/workflows/test.yml:40:9:40:11 | run | .github/workflows/test.yml:39:9:40:53 | Run Step: sink |
| .github/workflows/test.yml:40:14:40:52 | echo ${ ... utput}} | .github/workflows/test.yml:39:9:40:53 | Run Step: sink |
cfgNodes
| .github/workflows/test.yml:1:1:40:53 | enter on: push |
| .github/workflows/test.yml:1:1:40:53 | exit on: push |
| .github/workflows/test.yml:1:1:40:53 | exit on: push (normal) |
| .github/workflows/test.yml:1:1:40:53 | on: push |
| .github/workflows/test.yml:5:5:31:2 | runs-on ... -latest |
| .github/workflows/test.yml:8:7:10:4 | job_out ... alue }} |
| .github/workflows/test.yml:5:5:31:2 | Job: job1 |
| .github/workflows/test.yml:8:7:10:4 | Job outputs node |
| .github/workflows/test.yml:8:19:8:49 | ${{ ste ... alue }} |
| .github/workflows/test.yml:11:9:15:6 | uses: a ... kout@v4 |
| .github/workflows/test.yml:15:9:19:6 | name: G ... d files |
| .github/workflows/test.yml:19:9:26:6 | name: R ... d files |
| .github/workflows/test.yml:11:9:15:6 | Uses Step |
| .github/workflows/test.yml:15:9:19:6 | Uses Step: source |
| .github/workflows/test.yml:19:9:26:6 | Uses Step: step |
| .github/workflows/test.yml:23:19:23:63 | ${{ ste ... iles }} |
| .github/workflows/test.yml:26:9:28:6 | id: simplesink1 |
| .github/workflows/test.yml:24:17:24:21 | "foo" |
| .github/workflows/test.yml:25:20:25:21 | "" |
| .github/workflows/test.yml:26:9:28:6 | Run Step: simplesink1 |
| .github/workflows/test.yml:27:14:27:63 | echo ${ ... iles }} |
| .github/workflows/test.yml:28:9:31:2 | id: simplesink2 |
| .github/workflows/test.yml:28:9:31:2 | Run Step: simplesink2 |
| .github/workflows/test.yml:29:14:29:54 | ${{ git ... .ref }} |
| .github/workflows/test.yml:32:5:40:53 | runs-on ... -latest |
| .github/workflows/test.yml:39:9:40:53 | id: sink |
| .github/workflows/test.yml:32:5:40:53 | Job: job2 |
| .github/workflows/test.yml:39:9:40:53 | Run Step: sink |
| .github/workflows/test.yml:40:14:40:52 | echo ${ ... utput}} |
dfNodes
| .github/workflows/test.yml:1:1:40:53 | on: push |
| .github/workflows/test.yml:5:5:31:2 | runs-on ... -latest |
| .github/workflows/test.yml:8:7:10:4 | job_out ... alue }} |
| .github/workflows/test.yml:8:7:10:4 | Job outputs node |
| .github/workflows/test.yml:8:19:8:49 | ${{ ste ... alue }} |
| .github/workflows/test.yml:11:9:15:6 | uses: a ... kout@v4 |
| .github/workflows/test.yml:15:9:19:6 | name: G ... d files |
| .github/workflows/test.yml:19:9:26:6 | name: R ... d files |
| .github/workflows/test.yml:11:9:15:6 | Uses Step |
| .github/workflows/test.yml:15:9:19:6 | Uses Step: source |
| .github/workflows/test.yml:19:9:26:6 | Uses Step: step |
| .github/workflows/test.yml:23:19:23:63 | ${{ ste ... iles }} |
| .github/workflows/test.yml:26:9:28:6 | id: simplesink1 |
| .github/workflows/test.yml:26:9:28:6 | Run Step: simplesink1 |
| .github/workflows/test.yml:27:14:27:63 | echo ${ ... iles }} |
| .github/workflows/test.yml:28:9:31:2 | id: simplesink2 |
| .github/workflows/test.yml:28:9:31:2 | Run Step: simplesink2 |
| .github/workflows/test.yml:29:14:29:54 | ${{ git ... .ref }} |
| .github/workflows/test.yml:32:5:40:53 | runs-on ... -latest |
| .github/workflows/test.yml:39:9:40:53 | id: sink |
| .github/workflows/test.yml:39:9:40:53 | Run Step: sink |
| .github/workflows/test.yml:40:14:40:52 | echo ${ ... utput}} |
exprNodes
| .github/workflows/test.yml:1:1:40:53 | on: push |
| .github/workflows/test.yml:5:5:31:2 | runs-on ... -latest |
| .github/workflows/test.yml:8:7:10:4 | job_out ... alue }} |
| .github/workflows/test.yml:8:7:10:4 | Job outputs node |
| .github/workflows/test.yml:8:19:8:49 | ${{ ste ... alue }} |
| .github/workflows/test.yml:11:9:15:6 | uses: a ... kout@v4 |
| .github/workflows/test.yml:15:9:19:6 | name: G ... d files |
| .github/workflows/test.yml:19:9:26:6 | name: R ... d files |
| .github/workflows/test.yml:11:9:15:6 | Uses Step |
| .github/workflows/test.yml:15:9:19:6 | Uses Step: source |
| .github/workflows/test.yml:19:9:26:6 | Uses Step: step |
| .github/workflows/test.yml:23:19:23:63 | ${{ ste ... iles }} |
| .github/workflows/test.yml:26:9:28:6 | id: simplesink1 |
| .github/workflows/test.yml:26:9:28:6 | Run Step: simplesink1 |
| .github/workflows/test.yml:27:14:27:63 | echo ${ ... iles }} |
| .github/workflows/test.yml:28:9:31:2 | id: simplesink2 |
| .github/workflows/test.yml:28:9:31:2 | Run Step: simplesink2 |
| .github/workflows/test.yml:29:14:29:54 | ${{ git ... .ref }} |
| .github/workflows/test.yml:32:5:40:53 | runs-on ... -latest |
| .github/workflows/test.yml:39:9:40:53 | id: sink |
| .github/workflows/test.yml:39:9:40:53 | Run Step: sink |
| .github/workflows/test.yml:40:14:40:52 | echo ${ ... utput}} |
argumentNodes
| .github/workflows/test.yml:23:19:23:63 | ${{ ste ... iles }} |
usesIds
| .github/workflows/test.yml:15:9:19:6 | name: G ... d files | source |
| .github/workflows/test.yml:19:9:26:6 | name: R ... d files | step |
| .github/workflows/test.yml:15:9:19:6 | Uses Step: source | source |
| .github/workflows/test.yml:19:9:26:6 | Uses Step: step | step |
nodeLocations
| .github/workflows/test.yml:1:1:40:53 | on: push | .github/workflows/test.yml:1:1:40:53 | .github/workflows/test.yml@1:1:40:53 |
| .github/workflows/test.yml:5:5:31:2 | runs-on ... -latest | .github/workflows/test.yml:5:5:31:2 | .github/workflows/test.yml@5:5:31:2 |
| .github/workflows/test.yml:8:7:10:4 | job_out ... alue }} | .github/workflows/test.yml:8:7:10:4 | .github/workflows/test.yml@8:7:10:4 |
| .github/workflows/test.yml:8:7:10:4 | Job outputs node | .github/workflows/test.yml:8:7:10:4 | .github/workflows/test.yml@8:7:10:4 |
| .github/workflows/test.yml:8:19:8:49 | ${{ ste ... alue }} | .github/workflows/test.yml:8:19:8:49 | .github/workflows/test.yml@8:19:8:49 |
| .github/workflows/test.yml:11:9:15:6 | uses: a ... kout@v4 | .github/workflows/test.yml:11:9:15:6 | .github/workflows/test.yml@11:9:15:6 |
| .github/workflows/test.yml:15:9:19:6 | name: G ... d files | .github/workflows/test.yml:15:9:19:6 | .github/workflows/test.yml@15:9:19:6 |
| .github/workflows/test.yml:19:9:26:6 | name: R ... d files | .github/workflows/test.yml:19:9:26:6 | .github/workflows/test.yml@19:9:26:6 |
| .github/workflows/test.yml:11:9:15:6 | Uses Step | .github/workflows/test.yml:11:9:15:6 | .github/workflows/test.yml@11:9:15:6 |
| .github/workflows/test.yml:15:9:19:6 | Uses Step: source | .github/workflows/test.yml:15:9:19:6 | .github/workflows/test.yml@15:9:19:6 |
| .github/workflows/test.yml:19:9:26:6 | Uses Step: step | .github/workflows/test.yml:19:9:26:6 | .github/workflows/test.yml@19:9:26:6 |
| .github/workflows/test.yml:23:19:23:63 | ${{ ste ... iles }} | .github/workflows/test.yml:23:19:23:63 | .github/workflows/test.yml@23:19:23:63 |
| .github/workflows/test.yml:26:9:28:6 | id: simplesink1 | .github/workflows/test.yml:26:9:28:6 | .github/workflows/test.yml@26:9:28:6 |
| .github/workflows/test.yml:26:9:28:6 | Run Step: simplesink1 | .github/workflows/test.yml:26:9:28:6 | .github/workflows/test.yml@26:9:28:6 |
| .github/workflows/test.yml:27:14:27:63 | echo ${ ... iles }} | .github/workflows/test.yml:27:14:27:63 | .github/workflows/test.yml@27:14:27:63 |
| .github/workflows/test.yml:28:9:31:2 | id: simplesink2 | .github/workflows/test.yml:28:9:31:2 | .github/workflows/test.yml@28:9:31:2 |
| .github/workflows/test.yml:28:9:31:2 | Run Step: simplesink2 | .github/workflows/test.yml:28:9:31:2 | .github/workflows/test.yml@28:9:31:2 |
| .github/workflows/test.yml:29:14:29:54 | ${{ git ... .ref }} | .github/workflows/test.yml:29:14:29:54 | .github/workflows/test.yml@29:14:29:54 |
| .github/workflows/test.yml:32:5:40:53 | runs-on ... -latest | .github/workflows/test.yml:32:5:40:53 | .github/workflows/test.yml@32:5:40:53 |
| .github/workflows/test.yml:39:9:40:53 | id: sink | .github/workflows/test.yml:39:9:40:53 | .github/workflows/test.yml@39:9:40:53 |
| .github/workflows/test.yml:39:9:40:53 | Run Step: sink | .github/workflows/test.yml:39:9:40:53 | .github/workflows/test.yml@39:9:40:53 |
| .github/workflows/test.yml:40:14:40:52 | echo ${ ... utput}} | .github/workflows/test.yml:40:14:40:52 | .github/workflows/test.yml@40:14:40:52 |
scopes
| .github/workflows/test.yml:1:1:40:53 | on: push |
@@ -371,8 +345,8 @@ summaries
| timheuer/base64-to-file | * | input.fileDir | output.filePath | taint |
| timheuer/base64-to-file | * | input.fileName | output.filePath | taint |
calls
| .github/workflows/test.yml:11:9:15:6 | uses: a ... kout@v4 | actions/checkout |
| .github/workflows/test.yml:15:9:19:6 | name: G ... d files | tj-actions/changed-files |
| .github/workflows/test.yml:19:9:26:6 | name: R ... d files | mad9000/actions-find-and-replace-string |
| .github/workflows/test.yml:11:9:15:6 | Uses Step | actions/checkout |
| .github/workflows/test.yml:15:9:19:6 | Uses Step: source | tj-actions/changed-files |
| .github/workflows/test.yml:19:9:26:6 | Uses Step: step | mad9000/actions-find-and-replace-string |
needs
| .github/workflows/test.yml:40:14:40:52 | echo ${ ... utput}} |

View File

@@ -1,4 +1,4 @@
import codeql.actions.ast.internal.Actions
import codeql.actions.ast.internal.Yaml
import codeql.actions.Ast
import codeql.actions.Cfg as Cfg
import codeql.actions.DataFlow
@@ -9,37 +9,23 @@ query predicate files(File f) { any() }
query predicate yamlNodes(YamlNode n) { any() }
query predicate jobNodes(JobStmt s) { any() }
query predicate jobNodes(Job s) { any() }
query predicate stepNodes(StepStmt s) { any() }
query predicate stepNodes(Step s) { any() }
query predicate allUsesNodes(UsesExpr s) { any() }
query predicate allUsesNodes(Uses s) { any() }
query predicate stepUsesNodes(StepUsesExpr s) { any() }
query predicate stepUsesNodes(UsesStep s) { any() }
query predicate jobUsesNodes(JobUsesExpr s) { any() }
query predicate jobUsesNodes(UsesStep s) { any() }
query predicate usesSteps(UsesExpr call, string argname, Expression arg) {
call.getArgumentExpr(argname) = arg
query predicate usesSteps(Uses call, string argname, Expression arg) {
call.getArgument(argname) = arg
}
query predicate runSteps1(RunExpr run, string body) { run.getScript() = body }
query predicate runSteps(Run run, string body) { run.getScript().getValue() = body }
query predicate runSteps2(RunExpr run, Expression bodyExpr) { run.getScriptExpr() = bodyExpr }
query predicate runStepChildren(RunExpr run, AstNode child) { child.getParentNode() = run }
query predicate varAccesses(ExprAccessExpr ea, string expr) { expr = ea.getExpression() }
query predicate orphanVarAccesses(ExprAccessExpr va, string var) {
var = va.getExpression() and
not exists(AstNode n | n = va.getParentNode())
}
query predicate nonOrphanVarAccesses(ExprAccessExpr va, string var, AstNode parent) {
var = va.getExpression() and
parent = va.getParentNode()
}
query predicate runStepChildren(Run run, AstNode child) { child.getParentNode() = run }
query predicate parentNodes(AstNode child, AstNode parent) { child.getParentNode() = parent }
@@ -47,11 +33,11 @@ query predicate cfgNodes(Cfg::Node n) { any() }
query predicate dfNodes(DataFlow::Node e) { any() }
query predicate exprNodes(DataFlow::ExprNode e) { any() }
query predicate exprNodes(DataFlow::Node e) { any() }
query predicate argumentNodes(DataFlow::ArgumentNode e) { any() }
query predicate usesIds(StepUsesExpr s, string a) { s.getId() = a }
query predicate usesIds(UsesStep s, string a) { s.getId() = a }
query predicate nodeLocations(DataFlow::Node n, Location l) { n.getLocation() = l }
@@ -67,4 +53,4 @@ query predicate summaries(string action, string version, string input, string ou
query predicate calls(DataFlow::CallNode call, string callee) { callee = call.getCallee() }
query predicate needs(DataFlow::ExprNode e) { e.asExpr() instanceof NeedsCtxAccessExpr }
query predicate needs(DataFlow::Node e) { e.asExpr() instanceof NeedsExpression }

View File

@@ -1,11 +1,11 @@
edges
| action1/action.yml:4:3:4:14 | input who-to-greet | action1/action.yml:28:17:28:42 | ${{ inp ... reet }} |
| action1/action.yml:4:3:4:14 | input who-to-greet | action1/action.yml:35:12:35:51 | echo "H ... et }}." |
| action1/action.yml:24:7:31:4 | name: Remove foo [value] | action1/action.yml:32:12:32:50 | echo ${ ... alue }} |
| action1/action.yml:28:17:28:42 | ${{ inp ... reet }} | action1/action.yml:24:7:31:4 | name: Remove foo [value] |
| action1/action.yml:24:7:31:4 | Uses Step: replace [value] | action1/action.yml:32:12:32:50 | echo ${ ... alue }} |
| action1/action.yml:28:17:28:42 | ${{ inp ... reet }} | action1/action.yml:24:7:31:4 | Uses Step: replace [value] |
nodes
| action1/action.yml:4:3:4:14 | input who-to-greet | semmle.label | input who-to-greet |
| action1/action.yml:24:7:31:4 | name: Remove foo [value] | semmle.label | name: Remove foo [value] |
| action1/action.yml:24:7:31:4 | Uses Step: replace [value] | semmle.label | Uses Step: replace [value] |
| action1/action.yml:28:17:28:42 | ${{ inp ... reet }} | semmle.label | ${{ inp ... reet }} |
| action1/action.yml:32:12:32:50 | echo ${ ... alue }} | semmle.label | echo ${ ... alue }} |
| action1/action.yml:35:12:35:51 | echo "H ... et }}." | semmle.label | echo "H ... et }}." |

View File

@@ -1,12 +1,12 @@
edges
| action1/action.yml:42:7:44:4 | id: changed-files | action1/action.yml:48:18:48:69 | ${{ ste ... iles }} |
| action1/action.yml:44:7:48:70 | id: source [tainted] | action1/action.yml:14:12:14:45 | ${{ ste ... inted}} |
| action1/action.yml:48:18:48:69 | ${{ ste ... iles }} | action1/action.yml:44:7:48:70 | id: source [tainted] |
| action1/action.yml:42:7:44:4 | Uses Step: changed-files | action1/action.yml:48:18:48:69 | ${{ ste ... iles }} |
| action1/action.yml:44:7:48:70 | Run Step: source [tainted] | action1/action.yml:14:12:14:45 | ${{ ste ... inted}} |
| action1/action.yml:48:18:48:69 | ${{ ste ... iles }} | action1/action.yml:44:7:48:70 | Run Step: source [tainted] |
nodes
| action1/action.yml:14:12:14:45 | ${{ ste ... inted}} | semmle.label | ${{ ste ... inted}} |
| action1/action.yml:42:7:44:4 | id: changed-files | semmle.label | id: changed-files |
| action1/action.yml:44:7:48:70 | id: source [tainted] | semmle.label | id: source [tainted] |
| action1/action.yml:42:7:44:4 | Uses Step: changed-files | semmle.label | Uses Step: changed-files |
| action1/action.yml:44:7:48:70 | Run Step: source [tainted] | semmle.label | Run Step: source [tainted] |
| action1/action.yml:48:18:48:69 | ${{ ste ... iles }} | semmle.label | ${{ ste ... iles }} |
subpaths
#select
| action1/action.yml:14:12:14:45 | ${{ ste ... inted}} | action1/action.yml:42:7:44:4 | id: changed-files | action1/action.yml:14:12:14:45 | ${{ ste ... inted}} | Source |
| action1/action.yml:14:12:14:45 | ${{ ste ... inted}} | action1/action.yml:42:7:44:4 | Uses Step: changed-files | action1/action.yml:14:12:14:45 | ${{ ste ... inted}} | Source |

View File

@@ -1,11 +1,11 @@
edges
| action1/action.yml:4:3:4:14 | input who-to-greet | action1/action.yml:41:29:41:54 | ${{ inp ... reet }} |
| action1/action.yml:37:7:42:4 | id: reflector [reflected] | action1/action.yml:11:12:11:51 | ${{ ste ... cted }} |
| action1/action.yml:41:29:41:54 | ${{ inp ... reet }} | action1/action.yml:37:7:42:4 | id: reflector [reflected] |
| action1/action.yml:37:7:42:4 | Run Step: reflector [reflected] | action1/action.yml:11:12:11:51 | ${{ ste ... cted }} |
| action1/action.yml:41:29:41:54 | ${{ inp ... reet }} | action1/action.yml:37:7:42:4 | Run Step: reflector [reflected] |
nodes
| action1/action.yml:4:3:4:14 | input who-to-greet | semmle.label | input who-to-greet |
| action1/action.yml:11:12:11:51 | ${{ ste ... cted }} | semmle.label | ${{ ste ... cted }} |
| action1/action.yml:37:7:42:4 | id: reflector [reflected] | semmle.label | id: reflector [reflected] |
| action1/action.yml:37:7:42:4 | Run Step: reflector [reflected] | semmle.label | Run Step: reflector [reflected] |
| action1/action.yml:41:29:41:54 | ${{ inp ... reet }} | semmle.label | ${{ inp ... reet }} |
subpaths
#select

View File

@@ -1,12 +1,12 @@
edges
| .github/workflows/reusable_workflow.yml:22:7:24:4 | job-out ... utput}} [job-output2] | .github/workflows/reusable_workflow.yml:13:16:13:51 | ${{ job ... put2 }} |
| .github/workflows/reusable_workflow.yml:23:20:23:62 | ${{ ste ... files}} | .github/workflows/reusable_workflow.yml:22:7:24:4 | job-out ... utput}} [job-output2] |
| .github/workflows/reusable_workflow.yml:31:9:33:43 | name: G ... d files | .github/workflows/reusable_workflow.yml:23:20:23:62 | ${{ ste ... files}} |
| .github/workflows/reusable_workflow.yml:22:7:24:4 | Job outputs node [job-output2] | .github/workflows/reusable_workflow.yml:13:16:13:51 | ${{ job ... put2 }} |
| .github/workflows/reusable_workflow.yml:23:20:23:62 | ${{ ste ... files}} | .github/workflows/reusable_workflow.yml:22:7:24:4 | Job outputs node [job-output2] |
| .github/workflows/reusable_workflow.yml:31:9:33:43 | Uses Step: step2 | .github/workflows/reusable_workflow.yml:23:20:23:62 | ${{ ste ... files}} |
nodes
| .github/workflows/reusable_workflow.yml:13:16:13:51 | ${{ job ... put2 }} | semmle.label | ${{ job ... put2 }} |
| .github/workflows/reusable_workflow.yml:22:7:24:4 | job-out ... utput}} [job-output2] | semmle.label | job-out ... utput}} [job-output2] |
| .github/workflows/reusable_workflow.yml:22:7:24:4 | Job outputs node [job-output2] | semmle.label | Job outputs node [job-output2] |
| .github/workflows/reusable_workflow.yml:23:20:23:62 | ${{ ste ... files}} | semmle.label | ${{ ste ... files}} |
| .github/workflows/reusable_workflow.yml:31:9:33:43 | name: G ... d files | semmle.label | name: G ... d files |
| .github/workflows/reusable_workflow.yml:31:9:33:43 | Uses Step: step2 | semmle.label | Uses Step: step2 |
subpaths
#select
| .github/workflows/reusable_workflow.yml:13:16:13:51 | ${{ job ... put2 }} | .github/workflows/reusable_workflow.yml:31:9:33:43 | name: G ... d files | .github/workflows/reusable_workflow.yml:13:16:13:51 | ${{ job ... put2 }} | Source |
| .github/workflows/reusable_workflow.yml:13:16:13:51 | ${{ job ... put2 }} | .github/workflows/reusable_workflow.yml:31:9:33:43 | Uses Step: step2 | .github/workflows/reusable_workflow.yml:13:16:13:51 | ${{ job ... put2 }} | Source |

View File

@@ -1,15 +1,15 @@
edges
| .github/workflows/reusable_workflow.yml:6:7:6:17 | input config-path | .github/workflows/reusable_workflow.yml:27:24:27:48 | ${{ inp ... path }} |
| .github/workflows/reusable_workflow.yml:22:7:24:4 | job-out ... utput}} [job-output1] | .github/workflows/reusable_workflow.yml:11:16:11:51 | ${{ job ... put1 }} |
| .github/workflows/reusable_workflow.yml:22:20:22:56 | ${{ ste ... utput}} | .github/workflows/reusable_workflow.yml:22:7:24:4 | job-out ... utput}} [job-output1] |
| .github/workflows/reusable_workflow.yml:25:9:31:6 | id: step1 [step-output] | .github/workflows/reusable_workflow.yml:22:20:22:56 | ${{ ste ... utput}} |
| .github/workflows/reusable_workflow.yml:27:24:27:48 | ${{ inp ... path }} | .github/workflows/reusable_workflow.yml:25:9:31:6 | id: step1 [step-output] |
| .github/workflows/reusable_workflow.yml:22:7:24:4 | Job outputs node [job-output1] | .github/workflows/reusable_workflow.yml:11:16:11:51 | ${{ job ... put1 }} |
| .github/workflows/reusable_workflow.yml:22:20:22:56 | ${{ ste ... utput}} | .github/workflows/reusable_workflow.yml:22:7:24:4 | Job outputs node [job-output1] |
| .github/workflows/reusable_workflow.yml:25:9:31:6 | Run Step: step1 [step-output] | .github/workflows/reusable_workflow.yml:22:20:22:56 | ${{ ste ... utput}} |
| .github/workflows/reusable_workflow.yml:27:24:27:48 | ${{ inp ... path }} | .github/workflows/reusable_workflow.yml:25:9:31:6 | Run Step: step1 [step-output] |
nodes
| .github/workflows/reusable_workflow.yml:6:7:6:17 | input config-path | semmle.label | input config-path |
| .github/workflows/reusable_workflow.yml:11:16:11:51 | ${{ job ... put1 }} | semmle.label | ${{ job ... put1 }} |
| .github/workflows/reusable_workflow.yml:22:7:24:4 | job-out ... utput}} [job-output1] | semmle.label | job-out ... utput}} [job-output1] |
| .github/workflows/reusable_workflow.yml:22:7:24:4 | Job outputs node [job-output1] | semmle.label | Job outputs node [job-output1] |
| .github/workflows/reusable_workflow.yml:22:20:22:56 | ${{ ste ... utput}} | semmle.label | ${{ ste ... utput}} |
| .github/workflows/reusable_workflow.yml:25:9:31:6 | id: step1 [step-output] | semmle.label | id: step1 [step-output] |
| .github/workflows/reusable_workflow.yml:25:9:31:6 | Run Step: step1 [step-output] | semmle.label | Run Step: step1 [step-output] |
| .github/workflows/reusable_workflow.yml:27:24:27:48 | ${{ inp ... path }} | semmle.label | ${{ inp ... path }} |
subpaths
#select

View File

@@ -1,6 +1,13 @@
on: push
jn: push
jobs:
job0:
runs-on: ubuntu-latest
outputs:
job_output: foo
steps:
- run: echo "foo"
job1:
runs-on: ubuntu-latest

View File

@@ -0,0 +1,43 @@
on: push
jobs:
job0:
runs-on: ubuntu-latest
outputs:
job_output: foo
steps:
- run: echo "foo"
job1:
runs-on: ubuntu-latest
outputs:
job_output: ${{ steps.step.outputs.value }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get changed files
id: source
uses: tj-actions/changed-files@v40
- name: Remove foo from changed files
id: step
uses: mad9000/actions-find-and-replace-string@3
with:
source: ${{ steps.source.outputs.all_changed_files }}
find: 'foo'
replace: ''
job2:
runs-on: ubuntu-latest
if: ${{ always() }}
needs: [job0, job1]
steps:
- id: sink
run: echo ${{needs.job1.outputs.job_output}}

View File

@@ -0,0 +1,45 @@
on: push
jobs:
job0:
runs-on: ubuntu-latest
outputs:
job_output: foo
steps:
- run: echo "foo"
job1:
runs-on: ubuntu-latest
outputs:
job_output: ${{ steps.step.outputs.value }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get changed files
id: source
uses: tj-actions/changed-files@v40
- name: Remove foo from changed files
id: step
uses: mad9000/actions-find-and-replace-string@3
with:
source: ${{ steps.source.outputs.all_changed_files }}
find: 'foo'
replace: ''
job2:
runs-on: ubuntu-latest
if: ${{ always() }}
needs:
- job0
- job1
steps:
- id: sink
run: echo ${{needs.job1.outputs.job_output}}

View File

@@ -0,0 +1,44 @@
jn: push
jobs:
job0:
runs-on: ubuntu-latest
outputs:
job_output: foo
steps:
- run: echo "foo"
job1:
runs-on: ubuntu-latest
outputs:
job_output: ${{ steps.step.outputs.value }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get changed files
id: source
uses: tj-actions/changed-files@v40
- name: Remove foo from changed files
id: step
uses: mad9000/actions-find-and-replace-string@3
with:
source: ${{ steps.source.outputs.all_changed_files }}
find: 'foo'
replace: ''
job2:
runs-on: ubuntu-latest
if: ${{ always() }}
needs:
- job1
steps:
- id: sink
run: echo ${{needs.job1.outputs.job_output}}

View File

@@ -0,0 +1,45 @@
jn: push
jobs:
job0:
runs-on: ubuntu-latest
outputs:
job_output: foo
steps:
- run: echo "foo"
job1:
runs-on: ubuntu-latest
outputs:
job_output: ${{ steps.step.outputs.value }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get changed files
id: source
uses: tj-actions/changed-files@v40
- name: Remove foo from changed files
id: step
uses: mad9000/actions-find-and-replace-string@3
with:
source: ${{ steps.source.outputs.all_changed_files }}
find: 'foo'
replace: ''
job2:
runs-on: ubuntu-latest
if: ${{ always() }}
needs:
- job0
steps:
- id: sink
# Should not be reported since job1 is not needed
run: echo ${{needs.job1.outputs.job_output}}

View File

@@ -1,58 +1,73 @@
edges
| .github/workflows/argus_case_study.yml:15:9:24:6 | name: R ... g chars [replaced] | .github/workflows/argus_case_study.yml:26:14:27:95 | \| |
| .github/workflows/argus_case_study.yml:15:9:24:6 | Uses Step: remove_quotations [replaced] | .github/workflows/argus_case_study.yml:26:14:27:95 | \| |
| .github/workflows/argus_case_study.yml:17:24:17:52 | ${{gith ... title}} | .github/workflows/argus_case_study.yml:22:19:22:38 | ${{env.ISSUE_TITLE}} |
| .github/workflows/argus_case_study.yml:22:19:22:38 | ${{env.ISSUE_TITLE}} | .github/workflows/argus_case_study.yml:15:9:24:6 | name: R ... g chars [replaced] |
| .github/workflows/changed-files.yml:16:9:20:6 | name: G ... d files | .github/workflows/changed-files.yml:21:14:24:15 | \| |
| .github/workflows/cross3.yml:27:7:37:4 | name: R ... g chars [replaced] | .github/workflows/cross3.yml:39:30:39:74 | ${{step ... laced}} |
| .github/workflows/cross3.yml:27:7:37:4 | name: R ... g chars [replaced] | .github/workflows/cross3.yml:57:28:57:72 | ${{step ... laced}} |
| .github/workflows/cross3.yml:32:17:32:52 | ${{gith ... ssage}} | .github/workflows/cross3.yml:27:7:37:4 | name: R ... g chars [replaced] |
| .github/workflows/argus_case_study.yml:22:19:22:38 | ${{env.ISSUE_TITLE}} | .github/workflows/argus_case_study.yml:15:9:24:6 | Uses Step: remove_quotations [replaced] |
| .github/workflows/changed-files.yml:16:9:20:6 | Uses Step: changed-files | .github/workflows/changed-files.yml:21:14:24:15 | \| |
| .github/workflows/cross3.yml:27:7:37:4 | Uses Step: remove_quotations [replaced] | .github/workflows/cross3.yml:39:30:39:74 | ${{step ... laced}} |
| .github/workflows/cross3.yml:27:7:37:4 | Uses Step: remove_quotations [replaced] | .github/workflows/cross3.yml:57:28:57:72 | ${{step ... laced}} |
| .github/workflows/cross3.yml:32:17:32:52 | ${{gith ... ssage}} | .github/workflows/cross3.yml:27:7:37:4 | Uses Step: remove_quotations [replaced] |
| .github/workflows/cross3.yml:39:30:39:74 | ${{step ... laced}} | .github/workflows/cross3.yml:41:12:43:5 | \| |
| .github/workflows/cross3.yml:57:28:57:72 | ${{step ... laced}} | .github/workflows/cross3.yml:61:21:68:47 | \| |
| .github/workflows/cross3.yml:61:21:68:47 | \| | .github/workflows/cross3.yml:47:12:53:109 | \| |
| .github/workflows/image_link_generator.yml:15:9:22:6 | name: E ... ial URL [initial_url] | .github/workflows/image_link_generator.yml:25:24:25:67 | ${{ ste ... _url }} |
| .github/workflows/image_link_generator.yml:18:17:18:48 | ${{ git ... body }} | .github/workflows/image_link_generator.yml:15:9:22:6 | name: E ... ial URL [initial_url] |
| .github/workflows/image_link_generator.yml:22:9:28:6 | name: G ... bugging [redirected_url] | .github/workflows/image_link_generator.yml:31:27:31:66 | ${{ ste ... _url }} |
| .github/workflows/image_link_generator.yml:25:24:25:67 | ${{ ste ... _url }} | .github/workflows/image_link_generator.yml:22:9:28:6 | name: G ... bugging [redirected_url] |
| .github/workflows/image_link_generator.yml:28:9:35:6 | name: T ... ter PNG [trimmed_url] | .github/workflows/image_link_generator.yml:36:14:37:126 | \| |
| .github/workflows/image_link_generator.yml:31:27:31:66 | ${{ ste ... _url }} | .github/workflows/image_link_generator.yml:28:9:35:6 | name: T ... ter PNG [trimmed_url] |
| .github/workflows/inter-job.yml:8:7:10:4 | job_out ... alue }} [job_output] | .github/workflows/inter-job.yml:36:14:36:52 | echo ${ ... utput}} |
| .github/workflows/inter-job.yml:8:19:8:49 | ${{ ste ... alue }} | .github/workflows/inter-job.yml:8:7:10:4 | job_out ... alue }} [job_output] |
| .github/workflows/inter-job.yml:15:9:19:6 | name: G ... d files | .github/workflows/inter-job.yml:23:19:23:63 | ${{ ste ... iles }} |
| .github/workflows/inter-job.yml:19:9:27:2 | name: R ... d files [value] | .github/workflows/inter-job.yml:8:19:8:49 | ${{ ste ... alue }} |
| .github/workflows/inter-job.yml:23:19:23:63 | ${{ ste ... iles }} | .github/workflows/inter-job.yml:19:9:27:2 | name: R ... d files [value] |
| .github/workflows/image_link_generator.yml:15:9:22:6 | Run Step: extract-url [initial_url] | .github/workflows/image_link_generator.yml:25:24:25:67 | ${{ ste ... _url }} |
| .github/workflows/image_link_generator.yml:18:17:18:48 | ${{ git ... body }} | .github/workflows/image_link_generator.yml:15:9:22:6 | Run Step: extract-url [initial_url] |
| .github/workflows/image_link_generator.yml:22:9:28:6 | Run Step: curl [redirected_url] | .github/workflows/image_link_generator.yml:31:27:31:66 | ${{ ste ... _url }} |
| .github/workflows/image_link_generator.yml:25:24:25:67 | ${{ ste ... _url }} | .github/workflows/image_link_generator.yml:22:9:28:6 | Run Step: curl [redirected_url] |
| .github/workflows/image_link_generator.yml:28:9:35:6 | Run Step: trim-url [trimmed_url] | .github/workflows/image_link_generator.yml:36:14:37:126 | \| |
| .github/workflows/image_link_generator.yml:31:27:31:66 | ${{ ste ... _url }} | .github/workflows/image_link_generator.yml:28:9:35:6 | Run Step: trim-url [trimmed_url] |
| .github/workflows/inter-job0.yml:15:7:17:4 | Job outputs node [job_output] | .github/workflows/inter-job0.yml:43:14:43:52 | echo ${ ... utput}} |
| .github/workflows/inter-job0.yml:15:19:15:49 | ${{ ste ... alue }} | .github/workflows/inter-job0.yml:15:7:17:4 | Job outputs node [job_output] |
| .github/workflows/inter-job0.yml:22:9:26:6 | Uses Step: source | .github/workflows/inter-job0.yml:30:19:30:63 | ${{ ste ... iles }} |
| .github/workflows/inter-job0.yml:26:9:34:2 | Uses Step: step [value] | .github/workflows/inter-job0.yml:15:19:15:49 | ${{ ste ... alue }} |
| .github/workflows/inter-job0.yml:30:19:30:63 | ${{ ste ... iles }} | .github/workflows/inter-job0.yml:26:9:34:2 | Uses Step: step [value] |
| .github/workflows/inter-job1.yml:15:7:17:4 | Job outputs node [job_output] | .github/workflows/inter-job1.yml:43:14:43:52 | echo ${ ... utput}} |
| .github/workflows/inter-job1.yml:15:19:15:49 | ${{ ste ... alue }} | .github/workflows/inter-job1.yml:15:7:17:4 | Job outputs node [job_output] |
| .github/workflows/inter-job1.yml:22:9:26:6 | Uses Step: source | .github/workflows/inter-job1.yml:30:19:30:63 | ${{ ste ... iles }} |
| .github/workflows/inter-job1.yml:26:9:34:2 | Uses Step: step [value] | .github/workflows/inter-job1.yml:15:19:15:49 | ${{ ste ... alue }} |
| .github/workflows/inter-job1.yml:30:19:30:63 | ${{ ste ... iles }} | .github/workflows/inter-job1.yml:26:9:34:2 | Uses Step: step [value] |
| .github/workflows/inter-job2.yml:15:7:17:4 | Job outputs node [job_output] | .github/workflows/inter-job2.yml:45:14:45:52 | echo ${ ... utput}} |
| .github/workflows/inter-job2.yml:15:19:15:49 | ${{ ste ... alue }} | .github/workflows/inter-job2.yml:15:7:17:4 | Job outputs node [job_output] |
| .github/workflows/inter-job2.yml:22:9:26:6 | Uses Step: source | .github/workflows/inter-job2.yml:30:19:30:63 | ${{ ste ... iles }} |
| .github/workflows/inter-job2.yml:26:9:34:2 | Uses Step: step [value] | .github/workflows/inter-job2.yml:15:19:15:49 | ${{ ste ... alue }} |
| .github/workflows/inter-job2.yml:30:19:30:63 | ${{ ste ... iles }} | .github/workflows/inter-job2.yml:26:9:34:2 | Uses Step: step [value] |
| .github/workflows/inter-job4.yml:15:7:17:4 | Job outputs node [job_output] | .github/workflows/inter-job4.yml:44:14:44:52 | echo ${ ... utput}} |
| .github/workflows/inter-job4.yml:15:19:15:49 | ${{ ste ... alue }} | .github/workflows/inter-job4.yml:15:7:17:4 | Job outputs node [job_output] |
| .github/workflows/inter-job4.yml:22:9:26:6 | Uses Step: source | .github/workflows/inter-job4.yml:30:19:30:63 | ${{ ste ... iles }} |
| .github/workflows/inter-job4.yml:26:9:34:2 | Uses Step: step [value] | .github/workflows/inter-job4.yml:15:19:15:49 | ${{ ste ... alue }} |
| .github/workflows/inter-job4.yml:30:19:30:63 | ${{ ste ... iles }} | .github/workflows/inter-job4.yml:26:9:34:2 | Uses Step: step [value] |
| .github/workflows/issues.yaml:4:15:4:45 | ${{ git ... itle }} | .github/workflows/issues.yaml:15:12:15:39 | echo '$ ... env }}' |
| .github/workflows/issues.yaml:10:16:10:46 | ${{ git ... itle }} | .github/workflows/issues.yaml:17:12:17:36 | echo '$ ... env }}' |
| .github/workflows/issues.yaml:20:19:20:49 | ${{ git ... itle }} | .github/workflows/issues.yaml:18:12:18:37 | echo '$ ... env }}' |
| .github/workflows/matrix.yml:15:7:16:4 | matrix: ... iles }} [matrix] | .github/workflows/matrix.yml:34:19:34:69 | ${{ fro ... rix) }} |
| .github/workflows/matrix.yml:15:15:15:63 | ${{ ste ... iles }} | .github/workflows/matrix.yml:15:7:16:4 | matrix: ... iles }} [matrix] |
| .github/workflows/matrix.yml:17:9:21:2 | name: G ... d files | .github/workflows/matrix.yml:15:15:15:63 | ${{ ste ... iles }} |
| .github/workflows/matrix.yml:15:7:16:4 | Job outputs node [matrix] | .github/workflows/matrix.yml:34:19:34:69 | ${{ fro ... rix) }} |
| .github/workflows/matrix.yml:15:15:15:63 | ${{ ste ... iles }} | .github/workflows/matrix.yml:15:7:16:4 | Job outputs node [matrix] |
| .github/workflows/matrix.yml:17:9:21:2 | Uses Step: set-matrix | .github/workflows/matrix.yml:15:15:15:63 | ${{ ste ... iles }} |
| .github/workflows/matrix.yml:34:19:34:69 | ${{ fro ... rix) }} | .github/workflows/matrix.yml:41:12:42:31 | \| |
| .github/workflows/simple1.yml:8:9:14:6 | id: summary [value] | .github/workflows/simple1.yml:15:14:16:50 | \| |
| .github/workflows/simple1.yml:11:19:11:57 | ${{ git ... sage }} | .github/workflows/simple1.yml:8:9:14:6 | id: summary [value] |
| .github/workflows/simple2.yml:14:9:18:6 | name: G ... d files | .github/workflows/simple2.yml:22:19:22:63 | ${{ ste ... iles }} |
| .github/workflows/simple2.yml:18:9:26:6 | name: R ... d files [value] | .github/workflows/simple2.yml:28:14:31:15 | \| |
| .github/workflows/simple2.yml:22:19:22:63 | ${{ ste ... iles }} | .github/workflows/simple2.yml:18:9:26:6 | name: R ... d files [value] |
| .github/workflows/test.yml:8:7:10:4 | job_out ... test }} [job_output] | .github/workflows/test.yml:37:14:37:52 | echo ${ ... utput}} |
| .github/workflows/test.yml:8:19:8:49 | ${{ ste ... test }} | .github/workflows/test.yml:8:7:10:4 | job_out ... test }} [job_output] |
| .github/workflows/test.yml:12:9:18:6 | id: step0 [value] | .github/workflows/test.yml:20:17:20:47 | ${{ ste ... value}} |
| .github/workflows/test.yml:15:19:15:57 | ${{ git ... sage }} | .github/workflows/test.yml:12:9:18:6 | id: step0 [value] |
| .github/workflows/test.yml:18:9:24:6 | id: step1 [MSG] | .github/workflows/test.yml:26:18:26:45 | ${{step ... s.MSG}} |
| .github/workflows/test.yml:20:17:20:47 | ${{ ste ... value}} | .github/workflows/test.yml:18:9:24:6 | id: step1 [MSG] |
| .github/workflows/test.yml:24:9:29:2 | id: step2 [test] | .github/workflows/test.yml:8:19:8:49 | ${{ ste ... test }} |
| .github/workflows/test.yml:26:18:26:45 | ${{step ... s.MSG}} | .github/workflows/test.yml:24:9:29:2 | id: step2 [test] |
| .github/workflows/simple1.yml:8:9:14:6 | Uses Step: summary [value] | .github/workflows/simple1.yml:15:14:16:50 | \| |
| .github/workflows/simple1.yml:11:19:11:57 | ${{ git ... sage }} | .github/workflows/simple1.yml:8:9:14:6 | Uses Step: summary [value] |
| .github/workflows/simple2.yml:14:9:18:6 | Uses Step: source | .github/workflows/simple2.yml:22:19:22:63 | ${{ ste ... iles }} |
| .github/workflows/simple2.yml:18:9:26:6 | Uses Step: step [value] | .github/workflows/simple2.yml:28:14:31:15 | \| |
| .github/workflows/simple2.yml:22:19:22:63 | ${{ ste ... iles }} | .github/workflows/simple2.yml:18:9:26:6 | Uses Step: step [value] |
| .github/workflows/test.yml:8:7:10:4 | Job outputs node [job_output] | .github/workflows/test.yml:37:14:37:52 | echo ${ ... utput}} |
| .github/workflows/test.yml:8:19:8:49 | ${{ ste ... test }} | .github/workflows/test.yml:8:7:10:4 | Job outputs node [job_output] |
| .github/workflows/test.yml:12:9:18:6 | Uses Step: step0 [value] | .github/workflows/test.yml:20:17:20:47 | ${{ ste ... value}} |
| .github/workflows/test.yml:15:19:15:57 | ${{ git ... sage }} | .github/workflows/test.yml:12:9:18:6 | Uses Step: step0 [value] |
| .github/workflows/test.yml:18:9:24:6 | Run Step: step1 [MSG] | .github/workflows/test.yml:26:18:26:45 | ${{step ... s.MSG}} |
| .github/workflows/test.yml:20:17:20:47 | ${{ ste ... value}} | .github/workflows/test.yml:18:9:24:6 | Run Step: step1 [MSG] |
| .github/workflows/test.yml:24:9:29:2 | Run Step: step2 [test] | .github/workflows/test.yml:8:19:8:49 | ${{ ste ... test }} |
| .github/workflows/test.yml:26:18:26:45 | ${{step ... s.MSG}} | .github/workflows/test.yml:24:9:29:2 | Run Step: step2 [test] |
nodes
| .github/workflows/argus_case_study.yml:15:9:24:6 | name: R ... g chars [replaced] | semmle.label | name: R ... g chars [replaced] |
| .github/workflows/argus_case_study.yml:15:9:24:6 | Uses Step: remove_quotations [replaced] | semmle.label | Uses Step: remove_quotations [replaced] |
| .github/workflows/argus_case_study.yml:17:24:17:52 | ${{gith ... title}} | semmle.label | ${{gith ... title}} |
| .github/workflows/argus_case_study.yml:22:19:22:38 | ${{env.ISSUE_TITLE}} | semmle.label | ${{env.ISSUE_TITLE}} |
| .github/workflows/argus_case_study.yml:26:14:27:95 | \| | semmle.label | \| |
| .github/workflows/changed-files.yml:16:9:20:6 | name: G ... d files | semmle.label | name: G ... d files |
| .github/workflows/changed-files.yml:16:9:20:6 | Uses Step: changed-files | semmle.label | Uses Step: changed-files |
| .github/workflows/changed-files.yml:21:14:24:15 | \| | semmle.label | \| |
| .github/workflows/comment_issue.yml:7:12:8:48 | \| | semmle.label | \| |
| .github/workflows/comment_issue.yml:13:12:13:50 | echo '$ ... ody }}' | semmle.label | echo '$ ... ody }}' |
| .github/workflows/comment_issue.yml:14:12:14:48 | echo '$ ... ody }}' | semmle.label | echo '$ ... ody }}' |
| .github/workflows/comment_issue.yml:15:12:15:49 | echo '$ ... tle }}' | semmle.label | echo '$ ... tle }}' |
| .github/workflows/comment_issue_newline.yml:9:14:10:50 | \| | semmle.label | \| |
| .github/workflows/cross3.yml:27:7:37:4 | name: R ... g chars [replaced] | semmle.label | name: R ... g chars [replaced] |
| .github/workflows/cross3.yml:27:7:37:4 | Uses Step: remove_quotations [replaced] | semmle.label | Uses Step: remove_quotations [replaced] |
| .github/workflows/cross3.yml:32:17:32:52 | ${{gith ... ssage}} | semmle.label | ${{gith ... ssage}} |
| .github/workflows/cross3.yml:39:30:39:74 | ${{step ... laced}} | semmle.label | ${{step ... laced}} |
| .github/workflows/cross3.yml:41:12:43:5 | \| | semmle.label | \| |
@@ -68,19 +83,37 @@ nodes
| .github/workflows/gollum.yml:8:12:8:53 | echo '$ ... tle }}' | semmle.label | echo '$ ... tle }}' |
| .github/workflows/gollum.yml:9:12:9:56 | echo '$ ... ame }}' | semmle.label | echo '$ ... ame }}' |
| .github/workflows/gollum.yml:10:12:10:59 | echo '$ ... ame }}' | semmle.label | echo '$ ... ame }}' |
| .github/workflows/image_link_generator.yml:15:9:22:6 | name: E ... ial URL [initial_url] | semmle.label | name: E ... ial URL [initial_url] |
| .github/workflows/image_link_generator.yml:15:9:22:6 | Run Step: extract-url [initial_url] | semmle.label | Run Step: extract-url [initial_url] |
| .github/workflows/image_link_generator.yml:18:17:18:48 | ${{ git ... body }} | semmle.label | ${{ git ... body }} |
| .github/workflows/image_link_generator.yml:22:9:28:6 | name: G ... bugging [redirected_url] | semmle.label | name: G ... bugging [redirected_url] |
| .github/workflows/image_link_generator.yml:22:9:28:6 | Run Step: curl [redirected_url] | semmle.label | Run Step: curl [redirected_url] |
| .github/workflows/image_link_generator.yml:25:24:25:67 | ${{ ste ... _url }} | semmle.label | ${{ ste ... _url }} |
| .github/workflows/image_link_generator.yml:28:9:35:6 | name: T ... ter PNG [trimmed_url] | semmle.label | name: T ... ter PNG [trimmed_url] |
| .github/workflows/image_link_generator.yml:28:9:35:6 | Run Step: trim-url [trimmed_url] | semmle.label | Run Step: trim-url [trimmed_url] |
| .github/workflows/image_link_generator.yml:31:27:31:66 | ${{ ste ... _url }} | semmle.label | ${{ ste ... _url }} |
| .github/workflows/image_link_generator.yml:36:14:37:126 | \| | semmle.label | \| |
| .github/workflows/inter-job.yml:8:7:10:4 | job_out ... alue }} [job_output] | semmle.label | job_out ... alue }} [job_output] |
| .github/workflows/inter-job.yml:8:19:8:49 | ${{ ste ... alue }} | semmle.label | ${{ ste ... alue }} |
| .github/workflows/inter-job.yml:15:9:19:6 | name: G ... d files | semmle.label | name: G ... d files |
| .github/workflows/inter-job.yml:19:9:27:2 | name: R ... d files [value] | semmle.label | name: R ... d files [value] |
| .github/workflows/inter-job.yml:23:19:23:63 | ${{ ste ... iles }} | semmle.label | ${{ ste ... iles }} |
| .github/workflows/inter-job.yml:36:14:36:52 | echo ${ ... utput}} | semmle.label | echo ${ ... utput}} |
| .github/workflows/inter-job0.yml:15:7:17:4 | Job outputs node [job_output] | semmle.label | Job outputs node [job_output] |
| .github/workflows/inter-job0.yml:15:19:15:49 | ${{ ste ... alue }} | semmle.label | ${{ ste ... alue }} |
| .github/workflows/inter-job0.yml:22:9:26:6 | Uses Step: source | semmle.label | Uses Step: source |
| .github/workflows/inter-job0.yml:26:9:34:2 | Uses Step: step [value] | semmle.label | Uses Step: step [value] |
| .github/workflows/inter-job0.yml:30:19:30:63 | ${{ ste ... iles }} | semmle.label | ${{ ste ... iles }} |
| .github/workflows/inter-job0.yml:43:14:43:52 | echo ${ ... utput}} | semmle.label | echo ${ ... utput}} |
| .github/workflows/inter-job1.yml:15:7:17:4 | Job outputs node [job_output] | semmle.label | Job outputs node [job_output] |
| .github/workflows/inter-job1.yml:15:19:15:49 | ${{ ste ... alue }} | semmle.label | ${{ ste ... alue }} |
| .github/workflows/inter-job1.yml:22:9:26:6 | Uses Step: source | semmle.label | Uses Step: source |
| .github/workflows/inter-job1.yml:26:9:34:2 | Uses Step: step [value] | semmle.label | Uses Step: step [value] |
| .github/workflows/inter-job1.yml:30:19:30:63 | ${{ ste ... iles }} | semmle.label | ${{ ste ... iles }} |
| .github/workflows/inter-job1.yml:43:14:43:52 | echo ${ ... utput}} | semmle.label | echo ${ ... utput}} |
| .github/workflows/inter-job2.yml:15:7:17:4 | Job outputs node [job_output] | semmle.label | Job outputs node [job_output] |
| .github/workflows/inter-job2.yml:15:19:15:49 | ${{ ste ... alue }} | semmle.label | ${{ ste ... alue }} |
| .github/workflows/inter-job2.yml:22:9:26:6 | Uses Step: source | semmle.label | Uses Step: source |
| .github/workflows/inter-job2.yml:26:9:34:2 | Uses Step: step [value] | semmle.label | Uses Step: step [value] |
| .github/workflows/inter-job2.yml:30:19:30:63 | ${{ ste ... iles }} | semmle.label | ${{ ste ... iles }} |
| .github/workflows/inter-job2.yml:45:14:45:52 | echo ${ ... utput}} | semmle.label | echo ${ ... utput}} |
| .github/workflows/inter-job4.yml:15:7:17:4 | Job outputs node [job_output] | semmle.label | Job outputs node [job_output] |
| .github/workflows/inter-job4.yml:15:19:15:49 | ${{ ste ... alue }} | semmle.label | ${{ ste ... alue }} |
| .github/workflows/inter-job4.yml:22:9:26:6 | Uses Step: source | semmle.label | Uses Step: source |
| .github/workflows/inter-job4.yml:26:9:34:2 | Uses Step: step [value] | semmle.label | Uses Step: step [value] |
| .github/workflows/inter-job4.yml:30:19:30:63 | ${{ ste ... iles }} | semmle.label | ${{ ste ... iles }} |
| .github/workflows/inter-job4.yml:44:14:44:52 | echo ${ ... utput}} | semmle.label | echo ${ ... utput}} |
| .github/workflows/issues.yaml:4:15:4:45 | ${{ git ... itle }} | semmle.label | ${{ git ... itle }} |
| .github/workflows/issues.yaml:10:16:10:46 | ${{ git ... itle }} | semmle.label | ${{ git ... itle }} |
| .github/workflows/issues.yaml:13:12:13:49 | echo '$ ... tle }}' | semmle.label | echo '$ ... tle }}' |
@@ -89,9 +122,9 @@ nodes
| .github/workflows/issues.yaml:17:12:17:36 | echo '$ ... env }}' | semmle.label | echo '$ ... env }}' |
| .github/workflows/issues.yaml:18:12:18:37 | echo '$ ... env }}' | semmle.label | echo '$ ... env }}' |
| .github/workflows/issues.yaml:20:19:20:49 | ${{ git ... itle }} | semmle.label | ${{ git ... itle }} |
| .github/workflows/matrix.yml:15:7:16:4 | matrix: ... iles }} [matrix] | semmle.label | matrix: ... iles }} [matrix] |
| .github/workflows/matrix.yml:15:7:16:4 | Job outputs node [matrix] | semmle.label | Job outputs node [matrix] |
| .github/workflows/matrix.yml:15:15:15:63 | ${{ ste ... iles }} | semmle.label | ${{ ste ... iles }} |
| .github/workflows/matrix.yml:17:9:21:2 | name: G ... d files | semmle.label | name: G ... d files |
| .github/workflows/matrix.yml:17:9:21:2 | Uses Step: set-matrix | semmle.label | Uses Step: set-matrix |
| .github/workflows/matrix.yml:34:19:34:69 | ${{ fro ... rix) }} | semmle.label | ${{ fro ... rix) }} |
| .github/workflows/matrix.yml:41:12:42:31 | \| | semmle.label | \| |
| .github/workflows/pull_request_review.yml:7:12:7:56 | echo '$ ... tle }}' | semmle.label | echo '$ ... tle }}' |
@@ -130,20 +163,20 @@ nodes
| .github/workflows/push.yml:14:12:14:64 | echo '$ ... ame }}' | semmle.label | echo '$ ... ame }}' |
| .github/workflows/push.yml:15:12:15:65 | echo '$ ... ail }}' | semmle.label | echo '$ ... ail }}' |
| .github/workflows/push.yml:16:12:16:64 | echo '$ ... ame }}' | semmle.label | echo '$ ... ame }}' |
| .github/workflows/simple1.yml:8:9:14:6 | id: summary [value] | semmle.label | id: summary [value] |
| .github/workflows/simple1.yml:8:9:14:6 | Uses Step: summary [value] | semmle.label | Uses Step: summary [value] |
| .github/workflows/simple1.yml:11:19:11:57 | ${{ git ... sage }} | semmle.label | ${{ git ... sage }} |
| .github/workflows/simple1.yml:15:14:16:50 | \| | semmle.label | \| |
| .github/workflows/simple2.yml:14:9:18:6 | name: G ... d files | semmle.label | name: G ... d files |
| .github/workflows/simple2.yml:18:9:26:6 | name: R ... d files [value] | semmle.label | name: R ... d files [value] |
| .github/workflows/simple2.yml:14:9:18:6 | Uses Step: source | semmle.label | Uses Step: source |
| .github/workflows/simple2.yml:18:9:26:6 | Uses Step: step [value] | semmle.label | Uses Step: step [value] |
| .github/workflows/simple2.yml:22:19:22:63 | ${{ ste ... iles }} | semmle.label | ${{ ste ... iles }} |
| .github/workflows/simple2.yml:28:14:31:15 | \| | semmle.label | \| |
| .github/workflows/test.yml:8:7:10:4 | job_out ... test }} [job_output] | semmle.label | job_out ... test }} [job_output] |
| .github/workflows/test.yml:8:7:10:4 | Job outputs node [job_output] | semmle.label | Job outputs node [job_output] |
| .github/workflows/test.yml:8:19:8:49 | ${{ ste ... test }} | semmle.label | ${{ ste ... test }} |
| .github/workflows/test.yml:12:9:18:6 | id: step0 [value] | semmle.label | id: step0 [value] |
| .github/workflows/test.yml:12:9:18:6 | Uses Step: step0 [value] | semmle.label | Uses Step: step0 [value] |
| .github/workflows/test.yml:15:19:15:57 | ${{ git ... sage }} | semmle.label | ${{ git ... sage }} |
| .github/workflows/test.yml:18:9:24:6 | id: step1 [MSG] | semmle.label | id: step1 [MSG] |
| .github/workflows/test.yml:18:9:24:6 | Run Step: step1 [MSG] | semmle.label | Run Step: step1 [MSG] |
| .github/workflows/test.yml:20:17:20:47 | ${{ ste ... value}} | semmle.label | ${{ ste ... value}} |
| .github/workflows/test.yml:24:9:29:2 | id: step2 [test] | semmle.label | id: step2 [test] |
| .github/workflows/test.yml:24:9:29:2 | Run Step: step2 [test] | semmle.label | Run Step: step2 [test] |
| .github/workflows/test.yml:26:18:26:45 | ${{step ... s.MSG}} | semmle.label | ${{step ... s.MSG}} |
| .github/workflows/test.yml:37:14:37:52 | echo ${ ... utput}} | semmle.label | echo ${ ... utput}} |
| .github/workflows/workflow_run.yml:9:12:9:64 | echo '$ ... tle }}' | semmle.label | echo '$ ... tle }}' |
@@ -215,7 +248,7 @@ subpaths
| .github/workflows/push.yml:15:12:15:65 | echo '$ ... ail }}' | .github/workflows/push.yml:15:12:15:65 | echo '$ ... ail }}' | .github/workflows/push.yml:15:12:15:65 | echo '$ ... ail }}' | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/push.yml:16:12:16:64 | echo '$ ... ame }}' | .github/workflows/push.yml:16:12:16:64 | echo '$ ... ame }}' | .github/workflows/push.yml:16:12:16:64 | echo '$ ... ame }}' | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/simple1.yml:15:14:16:50 | \| | .github/workflows/simple1.yml:11:19:11:57 | ${{ git ... sage }} | .github/workflows/simple1.yml:15:14:16:50 | \| | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/simple2.yml:28:14:31:15 | \| | .github/workflows/simple2.yml:14:9:18:6 | name: G ... d files | .github/workflows/simple2.yml:28:14:31:15 | \| | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/simple2.yml:28:14:31:15 | \| | .github/workflows/simple2.yml:14:9:18:6 | Uses Step: source | .github/workflows/simple2.yml:28:14:31:15 | \| | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/test.yml:37:14:37:52 | echo ${ ... utput}} | .github/workflows/test.yml:15:19:15:57 | ${{ git ... sage }} | .github/workflows/test.yml:37:14:37:52 | echo ${ ... utput}} | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/workflow_run.yml:9:12:9:64 | echo '$ ... tle }}' | .github/workflows/workflow_run.yml:9:12:9:64 | echo '$ ... tle }}' | .github/workflows/workflow_run.yml:9:12:9:64 | echo '$ ... tle }}' | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/workflow_run.yml:10:12:10:70 | echo '$ ... age }}' | .github/workflows/workflow_run.yml:10:12:10:70 | echo '$ ... age }}' | .github/workflows/workflow_run.yml:10:12:10:70 | echo '$ ... age }}' | Potential expression injection, which may be controlled by an external user. |

View File

@@ -1,58 +1,73 @@
edges
| .github/workflows/argus_case_study.yml:15:9:24:6 | name: R ... g chars [replaced] | .github/workflows/argus_case_study.yml:26:14:27:95 | \| |
| .github/workflows/argus_case_study.yml:15:9:24:6 | Uses Step: remove_quotations [replaced] | .github/workflows/argus_case_study.yml:26:14:27:95 | \| |
| .github/workflows/argus_case_study.yml:17:24:17:52 | ${{gith ... title}} | .github/workflows/argus_case_study.yml:22:19:22:38 | ${{env.ISSUE_TITLE}} |
| .github/workflows/argus_case_study.yml:22:19:22:38 | ${{env.ISSUE_TITLE}} | .github/workflows/argus_case_study.yml:15:9:24:6 | name: R ... g chars [replaced] |
| .github/workflows/changed-files.yml:16:9:20:6 | name: G ... d files | .github/workflows/changed-files.yml:21:14:24:15 | \| |
| .github/workflows/cross3.yml:27:7:37:4 | name: R ... g chars [replaced] | .github/workflows/cross3.yml:39:30:39:74 | ${{step ... laced}} |
| .github/workflows/cross3.yml:27:7:37:4 | name: R ... g chars [replaced] | .github/workflows/cross3.yml:57:28:57:72 | ${{step ... laced}} |
| .github/workflows/cross3.yml:32:17:32:52 | ${{gith ... ssage}} | .github/workflows/cross3.yml:27:7:37:4 | name: R ... g chars [replaced] |
| .github/workflows/argus_case_study.yml:22:19:22:38 | ${{env.ISSUE_TITLE}} | .github/workflows/argus_case_study.yml:15:9:24:6 | Uses Step: remove_quotations [replaced] |
| .github/workflows/changed-files.yml:16:9:20:6 | Uses Step: changed-files | .github/workflows/changed-files.yml:21:14:24:15 | \| |
| .github/workflows/cross3.yml:27:7:37:4 | Uses Step: remove_quotations [replaced] | .github/workflows/cross3.yml:39:30:39:74 | ${{step ... laced}} |
| .github/workflows/cross3.yml:27:7:37:4 | Uses Step: remove_quotations [replaced] | .github/workflows/cross3.yml:57:28:57:72 | ${{step ... laced}} |
| .github/workflows/cross3.yml:32:17:32:52 | ${{gith ... ssage}} | .github/workflows/cross3.yml:27:7:37:4 | Uses Step: remove_quotations [replaced] |
| .github/workflows/cross3.yml:39:30:39:74 | ${{step ... laced}} | .github/workflows/cross3.yml:41:12:43:5 | \| |
| .github/workflows/cross3.yml:57:28:57:72 | ${{step ... laced}} | .github/workflows/cross3.yml:61:21:68:47 | \| |
| .github/workflows/cross3.yml:61:21:68:47 | \| | .github/workflows/cross3.yml:47:12:53:109 | \| |
| .github/workflows/image_link_generator.yml:15:9:22:6 | name: E ... ial URL [initial_url] | .github/workflows/image_link_generator.yml:25:24:25:67 | ${{ ste ... _url }} |
| .github/workflows/image_link_generator.yml:18:17:18:48 | ${{ git ... body }} | .github/workflows/image_link_generator.yml:15:9:22:6 | name: E ... ial URL [initial_url] |
| .github/workflows/image_link_generator.yml:22:9:28:6 | name: G ... bugging [redirected_url] | .github/workflows/image_link_generator.yml:31:27:31:66 | ${{ ste ... _url }} |
| .github/workflows/image_link_generator.yml:25:24:25:67 | ${{ ste ... _url }} | .github/workflows/image_link_generator.yml:22:9:28:6 | name: G ... bugging [redirected_url] |
| .github/workflows/image_link_generator.yml:28:9:35:6 | name: T ... ter PNG [trimmed_url] | .github/workflows/image_link_generator.yml:36:14:37:126 | \| |
| .github/workflows/image_link_generator.yml:31:27:31:66 | ${{ ste ... _url }} | .github/workflows/image_link_generator.yml:28:9:35:6 | name: T ... ter PNG [trimmed_url] |
| .github/workflows/inter-job.yml:8:7:10:4 | job_out ... alue }} [job_output] | .github/workflows/inter-job.yml:36:14:36:52 | echo ${ ... utput}} |
| .github/workflows/inter-job.yml:8:19:8:49 | ${{ ste ... alue }} | .github/workflows/inter-job.yml:8:7:10:4 | job_out ... alue }} [job_output] |
| .github/workflows/inter-job.yml:15:9:19:6 | name: G ... d files | .github/workflows/inter-job.yml:23:19:23:63 | ${{ ste ... iles }} |
| .github/workflows/inter-job.yml:19:9:27:2 | name: R ... d files [value] | .github/workflows/inter-job.yml:8:19:8:49 | ${{ ste ... alue }} |
| .github/workflows/inter-job.yml:23:19:23:63 | ${{ ste ... iles }} | .github/workflows/inter-job.yml:19:9:27:2 | name: R ... d files [value] |
| .github/workflows/image_link_generator.yml:15:9:22:6 | Run Step: extract-url [initial_url] | .github/workflows/image_link_generator.yml:25:24:25:67 | ${{ ste ... _url }} |
| .github/workflows/image_link_generator.yml:18:17:18:48 | ${{ git ... body }} | .github/workflows/image_link_generator.yml:15:9:22:6 | Run Step: extract-url [initial_url] |
| .github/workflows/image_link_generator.yml:22:9:28:6 | Run Step: curl [redirected_url] | .github/workflows/image_link_generator.yml:31:27:31:66 | ${{ ste ... _url }} |
| .github/workflows/image_link_generator.yml:25:24:25:67 | ${{ ste ... _url }} | .github/workflows/image_link_generator.yml:22:9:28:6 | Run Step: curl [redirected_url] |
| .github/workflows/image_link_generator.yml:28:9:35:6 | Run Step: trim-url [trimmed_url] | .github/workflows/image_link_generator.yml:36:14:37:126 | \| |
| .github/workflows/image_link_generator.yml:31:27:31:66 | ${{ ste ... _url }} | .github/workflows/image_link_generator.yml:28:9:35:6 | Run Step: trim-url [trimmed_url] |
| .github/workflows/inter-job0.yml:15:7:17:4 | Job outputs node [job_output] | .github/workflows/inter-job0.yml:43:14:43:52 | echo ${ ... utput}} |
| .github/workflows/inter-job0.yml:15:19:15:49 | ${{ ste ... alue }} | .github/workflows/inter-job0.yml:15:7:17:4 | Job outputs node [job_output] |
| .github/workflows/inter-job0.yml:22:9:26:6 | Uses Step: source | .github/workflows/inter-job0.yml:30:19:30:63 | ${{ ste ... iles }} |
| .github/workflows/inter-job0.yml:26:9:34:2 | Uses Step: step [value] | .github/workflows/inter-job0.yml:15:19:15:49 | ${{ ste ... alue }} |
| .github/workflows/inter-job0.yml:30:19:30:63 | ${{ ste ... iles }} | .github/workflows/inter-job0.yml:26:9:34:2 | Uses Step: step [value] |
| .github/workflows/inter-job1.yml:15:7:17:4 | Job outputs node [job_output] | .github/workflows/inter-job1.yml:43:14:43:52 | echo ${ ... utput}} |
| .github/workflows/inter-job1.yml:15:19:15:49 | ${{ ste ... alue }} | .github/workflows/inter-job1.yml:15:7:17:4 | Job outputs node [job_output] |
| .github/workflows/inter-job1.yml:22:9:26:6 | Uses Step: source | .github/workflows/inter-job1.yml:30:19:30:63 | ${{ ste ... iles }} |
| .github/workflows/inter-job1.yml:26:9:34:2 | Uses Step: step [value] | .github/workflows/inter-job1.yml:15:19:15:49 | ${{ ste ... alue }} |
| .github/workflows/inter-job1.yml:30:19:30:63 | ${{ ste ... iles }} | .github/workflows/inter-job1.yml:26:9:34:2 | Uses Step: step [value] |
| .github/workflows/inter-job2.yml:15:7:17:4 | Job outputs node [job_output] | .github/workflows/inter-job2.yml:45:14:45:52 | echo ${ ... utput}} |
| .github/workflows/inter-job2.yml:15:19:15:49 | ${{ ste ... alue }} | .github/workflows/inter-job2.yml:15:7:17:4 | Job outputs node [job_output] |
| .github/workflows/inter-job2.yml:22:9:26:6 | Uses Step: source | .github/workflows/inter-job2.yml:30:19:30:63 | ${{ ste ... iles }} |
| .github/workflows/inter-job2.yml:26:9:34:2 | Uses Step: step [value] | .github/workflows/inter-job2.yml:15:19:15:49 | ${{ ste ... alue }} |
| .github/workflows/inter-job2.yml:30:19:30:63 | ${{ ste ... iles }} | .github/workflows/inter-job2.yml:26:9:34:2 | Uses Step: step [value] |
| .github/workflows/inter-job4.yml:15:7:17:4 | Job outputs node [job_output] | .github/workflows/inter-job4.yml:44:14:44:52 | echo ${ ... utput}} |
| .github/workflows/inter-job4.yml:15:19:15:49 | ${{ ste ... alue }} | .github/workflows/inter-job4.yml:15:7:17:4 | Job outputs node [job_output] |
| .github/workflows/inter-job4.yml:22:9:26:6 | Uses Step: source | .github/workflows/inter-job4.yml:30:19:30:63 | ${{ ste ... iles }} |
| .github/workflows/inter-job4.yml:26:9:34:2 | Uses Step: step [value] | .github/workflows/inter-job4.yml:15:19:15:49 | ${{ ste ... alue }} |
| .github/workflows/inter-job4.yml:30:19:30:63 | ${{ ste ... iles }} | .github/workflows/inter-job4.yml:26:9:34:2 | Uses Step: step [value] |
| .github/workflows/issues.yaml:4:15:4:45 | ${{ git ... itle }} | .github/workflows/issues.yaml:15:12:15:39 | echo '$ ... env }}' |
| .github/workflows/issues.yaml:10:16:10:46 | ${{ git ... itle }} | .github/workflows/issues.yaml:17:12:17:36 | echo '$ ... env }}' |
| .github/workflows/issues.yaml:20:19:20:49 | ${{ git ... itle }} | .github/workflows/issues.yaml:18:12:18:37 | echo '$ ... env }}' |
| .github/workflows/matrix.yml:15:7:16:4 | matrix: ... iles }} [matrix] | .github/workflows/matrix.yml:34:19:34:69 | ${{ fro ... rix) }} |
| .github/workflows/matrix.yml:15:15:15:63 | ${{ ste ... iles }} | .github/workflows/matrix.yml:15:7:16:4 | matrix: ... iles }} [matrix] |
| .github/workflows/matrix.yml:17:9:21:2 | name: G ... d files | .github/workflows/matrix.yml:15:15:15:63 | ${{ ste ... iles }} |
| .github/workflows/matrix.yml:15:7:16:4 | Job outputs node [matrix] | .github/workflows/matrix.yml:34:19:34:69 | ${{ fro ... rix) }} |
| .github/workflows/matrix.yml:15:15:15:63 | ${{ ste ... iles }} | .github/workflows/matrix.yml:15:7:16:4 | Job outputs node [matrix] |
| .github/workflows/matrix.yml:17:9:21:2 | Uses Step: set-matrix | .github/workflows/matrix.yml:15:15:15:63 | ${{ ste ... iles }} |
| .github/workflows/matrix.yml:34:19:34:69 | ${{ fro ... rix) }} | .github/workflows/matrix.yml:41:12:42:31 | \| |
| .github/workflows/simple1.yml:8:9:14:6 | id: summary [value] | .github/workflows/simple1.yml:15:14:16:50 | \| |
| .github/workflows/simple1.yml:11:19:11:57 | ${{ git ... sage }} | .github/workflows/simple1.yml:8:9:14:6 | id: summary [value] |
| .github/workflows/simple2.yml:14:9:18:6 | name: G ... d files | .github/workflows/simple2.yml:22:19:22:63 | ${{ ste ... iles }} |
| .github/workflows/simple2.yml:18:9:26:6 | name: R ... d files [value] | .github/workflows/simple2.yml:28:14:31:15 | \| |
| .github/workflows/simple2.yml:22:19:22:63 | ${{ ste ... iles }} | .github/workflows/simple2.yml:18:9:26:6 | name: R ... d files [value] |
| .github/workflows/test.yml:8:7:10:4 | job_out ... test }} [job_output] | .github/workflows/test.yml:37:14:37:52 | echo ${ ... utput}} |
| .github/workflows/test.yml:8:19:8:49 | ${{ ste ... test }} | .github/workflows/test.yml:8:7:10:4 | job_out ... test }} [job_output] |
| .github/workflows/test.yml:12:9:18:6 | id: step0 [value] | .github/workflows/test.yml:20:17:20:47 | ${{ ste ... value}} |
| .github/workflows/test.yml:15:19:15:57 | ${{ git ... sage }} | .github/workflows/test.yml:12:9:18:6 | id: step0 [value] |
| .github/workflows/test.yml:18:9:24:6 | id: step1 [MSG] | .github/workflows/test.yml:26:18:26:45 | ${{step ... s.MSG}} |
| .github/workflows/test.yml:20:17:20:47 | ${{ ste ... value}} | .github/workflows/test.yml:18:9:24:6 | id: step1 [MSG] |
| .github/workflows/test.yml:24:9:29:2 | id: step2 [test] | .github/workflows/test.yml:8:19:8:49 | ${{ ste ... test }} |
| .github/workflows/test.yml:26:18:26:45 | ${{step ... s.MSG}} | .github/workflows/test.yml:24:9:29:2 | id: step2 [test] |
| .github/workflows/simple1.yml:8:9:14:6 | Uses Step: summary [value] | .github/workflows/simple1.yml:15:14:16:50 | \| |
| .github/workflows/simple1.yml:11:19:11:57 | ${{ git ... sage }} | .github/workflows/simple1.yml:8:9:14:6 | Uses Step: summary [value] |
| .github/workflows/simple2.yml:14:9:18:6 | Uses Step: source | .github/workflows/simple2.yml:22:19:22:63 | ${{ ste ... iles }} |
| .github/workflows/simple2.yml:18:9:26:6 | Uses Step: step [value] | .github/workflows/simple2.yml:28:14:31:15 | \| |
| .github/workflows/simple2.yml:22:19:22:63 | ${{ ste ... iles }} | .github/workflows/simple2.yml:18:9:26:6 | Uses Step: step [value] |
| .github/workflows/test.yml:8:7:10:4 | Job outputs node [job_output] | .github/workflows/test.yml:37:14:37:52 | echo ${ ... utput}} |
| .github/workflows/test.yml:8:19:8:49 | ${{ ste ... test }} | .github/workflows/test.yml:8:7:10:4 | Job outputs node [job_output] |
| .github/workflows/test.yml:12:9:18:6 | Uses Step: step0 [value] | .github/workflows/test.yml:20:17:20:47 | ${{ ste ... value}} |
| .github/workflows/test.yml:15:19:15:57 | ${{ git ... sage }} | .github/workflows/test.yml:12:9:18:6 | Uses Step: step0 [value] |
| .github/workflows/test.yml:18:9:24:6 | Run Step: step1 [MSG] | .github/workflows/test.yml:26:18:26:45 | ${{step ... s.MSG}} |
| .github/workflows/test.yml:20:17:20:47 | ${{ ste ... value}} | .github/workflows/test.yml:18:9:24:6 | Run Step: step1 [MSG] |
| .github/workflows/test.yml:24:9:29:2 | Run Step: step2 [test] | .github/workflows/test.yml:8:19:8:49 | ${{ ste ... test }} |
| .github/workflows/test.yml:26:18:26:45 | ${{step ... s.MSG}} | .github/workflows/test.yml:24:9:29:2 | Run Step: step2 [test] |
nodes
| .github/workflows/argus_case_study.yml:15:9:24:6 | name: R ... g chars [replaced] | semmle.label | name: R ... g chars [replaced] |
| .github/workflows/argus_case_study.yml:15:9:24:6 | Uses Step: remove_quotations [replaced] | semmle.label | Uses Step: remove_quotations [replaced] |
| .github/workflows/argus_case_study.yml:17:24:17:52 | ${{gith ... title}} | semmle.label | ${{gith ... title}} |
| .github/workflows/argus_case_study.yml:22:19:22:38 | ${{env.ISSUE_TITLE}} | semmle.label | ${{env.ISSUE_TITLE}} |
| .github/workflows/argus_case_study.yml:26:14:27:95 | \| | semmle.label | \| |
| .github/workflows/changed-files.yml:16:9:20:6 | name: G ... d files | semmle.label | name: G ... d files |
| .github/workflows/changed-files.yml:16:9:20:6 | Uses Step: changed-files | semmle.label | Uses Step: changed-files |
| .github/workflows/changed-files.yml:21:14:24:15 | \| | semmle.label | \| |
| .github/workflows/comment_issue.yml:7:12:8:48 | \| | semmle.label | \| |
| .github/workflows/comment_issue.yml:13:12:13:50 | echo '$ ... ody }}' | semmle.label | echo '$ ... ody }}' |
| .github/workflows/comment_issue.yml:14:12:14:48 | echo '$ ... ody }}' | semmle.label | echo '$ ... ody }}' |
| .github/workflows/comment_issue.yml:15:12:15:49 | echo '$ ... tle }}' | semmle.label | echo '$ ... tle }}' |
| .github/workflows/comment_issue_newline.yml:9:14:10:50 | \| | semmle.label | \| |
| .github/workflows/cross3.yml:27:7:37:4 | name: R ... g chars [replaced] | semmle.label | name: R ... g chars [replaced] |
| .github/workflows/cross3.yml:27:7:37:4 | Uses Step: remove_quotations [replaced] | semmle.label | Uses Step: remove_quotations [replaced] |
| .github/workflows/cross3.yml:32:17:32:52 | ${{gith ... ssage}} | semmle.label | ${{gith ... ssage}} |
| .github/workflows/cross3.yml:39:30:39:74 | ${{step ... laced}} | semmle.label | ${{step ... laced}} |
| .github/workflows/cross3.yml:41:12:43:5 | \| | semmle.label | \| |
@@ -68,19 +83,37 @@ nodes
| .github/workflows/gollum.yml:8:12:8:53 | echo '$ ... tle }}' | semmle.label | echo '$ ... tle }}' |
| .github/workflows/gollum.yml:9:12:9:56 | echo '$ ... ame }}' | semmle.label | echo '$ ... ame }}' |
| .github/workflows/gollum.yml:10:12:10:59 | echo '$ ... ame }}' | semmle.label | echo '$ ... ame }}' |
| .github/workflows/image_link_generator.yml:15:9:22:6 | name: E ... ial URL [initial_url] | semmle.label | name: E ... ial URL [initial_url] |
| .github/workflows/image_link_generator.yml:15:9:22:6 | Run Step: extract-url [initial_url] | semmle.label | Run Step: extract-url [initial_url] |
| .github/workflows/image_link_generator.yml:18:17:18:48 | ${{ git ... body }} | semmle.label | ${{ git ... body }} |
| .github/workflows/image_link_generator.yml:22:9:28:6 | name: G ... bugging [redirected_url] | semmle.label | name: G ... bugging [redirected_url] |
| .github/workflows/image_link_generator.yml:22:9:28:6 | Run Step: curl [redirected_url] | semmle.label | Run Step: curl [redirected_url] |
| .github/workflows/image_link_generator.yml:25:24:25:67 | ${{ ste ... _url }} | semmle.label | ${{ ste ... _url }} |
| .github/workflows/image_link_generator.yml:28:9:35:6 | name: T ... ter PNG [trimmed_url] | semmle.label | name: T ... ter PNG [trimmed_url] |
| .github/workflows/image_link_generator.yml:28:9:35:6 | Run Step: trim-url [trimmed_url] | semmle.label | Run Step: trim-url [trimmed_url] |
| .github/workflows/image_link_generator.yml:31:27:31:66 | ${{ ste ... _url }} | semmle.label | ${{ ste ... _url }} |
| .github/workflows/image_link_generator.yml:36:14:37:126 | \| | semmle.label | \| |
| .github/workflows/inter-job.yml:8:7:10:4 | job_out ... alue }} [job_output] | semmle.label | job_out ... alue }} [job_output] |
| .github/workflows/inter-job.yml:8:19:8:49 | ${{ ste ... alue }} | semmle.label | ${{ ste ... alue }} |
| .github/workflows/inter-job.yml:15:9:19:6 | name: G ... d files | semmle.label | name: G ... d files |
| .github/workflows/inter-job.yml:19:9:27:2 | name: R ... d files [value] | semmle.label | name: R ... d files [value] |
| .github/workflows/inter-job.yml:23:19:23:63 | ${{ ste ... iles }} | semmle.label | ${{ ste ... iles }} |
| .github/workflows/inter-job.yml:36:14:36:52 | echo ${ ... utput}} | semmle.label | echo ${ ... utput}} |
| .github/workflows/inter-job0.yml:15:7:17:4 | Job outputs node [job_output] | semmle.label | Job outputs node [job_output] |
| .github/workflows/inter-job0.yml:15:19:15:49 | ${{ ste ... alue }} | semmle.label | ${{ ste ... alue }} |
| .github/workflows/inter-job0.yml:22:9:26:6 | Uses Step: source | semmle.label | Uses Step: source |
| .github/workflows/inter-job0.yml:26:9:34:2 | Uses Step: step [value] | semmle.label | Uses Step: step [value] |
| .github/workflows/inter-job0.yml:30:19:30:63 | ${{ ste ... iles }} | semmle.label | ${{ ste ... iles }} |
| .github/workflows/inter-job0.yml:43:14:43:52 | echo ${ ... utput}} | semmle.label | echo ${ ... utput}} |
| .github/workflows/inter-job1.yml:15:7:17:4 | Job outputs node [job_output] | semmle.label | Job outputs node [job_output] |
| .github/workflows/inter-job1.yml:15:19:15:49 | ${{ ste ... alue }} | semmle.label | ${{ ste ... alue }} |
| .github/workflows/inter-job1.yml:22:9:26:6 | Uses Step: source | semmle.label | Uses Step: source |
| .github/workflows/inter-job1.yml:26:9:34:2 | Uses Step: step [value] | semmle.label | Uses Step: step [value] |
| .github/workflows/inter-job1.yml:30:19:30:63 | ${{ ste ... iles }} | semmle.label | ${{ ste ... iles }} |
| .github/workflows/inter-job1.yml:43:14:43:52 | echo ${ ... utput}} | semmle.label | echo ${ ... utput}} |
| .github/workflows/inter-job2.yml:15:7:17:4 | Job outputs node [job_output] | semmle.label | Job outputs node [job_output] |
| .github/workflows/inter-job2.yml:15:19:15:49 | ${{ ste ... alue }} | semmle.label | ${{ ste ... alue }} |
| .github/workflows/inter-job2.yml:22:9:26:6 | Uses Step: source | semmle.label | Uses Step: source |
| .github/workflows/inter-job2.yml:26:9:34:2 | Uses Step: step [value] | semmle.label | Uses Step: step [value] |
| .github/workflows/inter-job2.yml:30:19:30:63 | ${{ ste ... iles }} | semmle.label | ${{ ste ... iles }} |
| .github/workflows/inter-job2.yml:45:14:45:52 | echo ${ ... utput}} | semmle.label | echo ${ ... utput}} |
| .github/workflows/inter-job4.yml:15:7:17:4 | Job outputs node [job_output] | semmle.label | Job outputs node [job_output] |
| .github/workflows/inter-job4.yml:15:19:15:49 | ${{ ste ... alue }} | semmle.label | ${{ ste ... alue }} |
| .github/workflows/inter-job4.yml:22:9:26:6 | Uses Step: source | semmle.label | Uses Step: source |
| .github/workflows/inter-job4.yml:26:9:34:2 | Uses Step: step [value] | semmle.label | Uses Step: step [value] |
| .github/workflows/inter-job4.yml:30:19:30:63 | ${{ ste ... iles }} | semmle.label | ${{ ste ... iles }} |
| .github/workflows/inter-job4.yml:44:14:44:52 | echo ${ ... utput}} | semmle.label | echo ${ ... utput}} |
| .github/workflows/issues.yaml:4:15:4:45 | ${{ git ... itle }} | semmle.label | ${{ git ... itle }} |
| .github/workflows/issues.yaml:10:16:10:46 | ${{ git ... itle }} | semmle.label | ${{ git ... itle }} |
| .github/workflows/issues.yaml:13:12:13:49 | echo '$ ... tle }}' | semmle.label | echo '$ ... tle }}' |
@@ -89,9 +122,9 @@ nodes
| .github/workflows/issues.yaml:17:12:17:36 | echo '$ ... env }}' | semmle.label | echo '$ ... env }}' |
| .github/workflows/issues.yaml:18:12:18:37 | echo '$ ... env }}' | semmle.label | echo '$ ... env }}' |
| .github/workflows/issues.yaml:20:19:20:49 | ${{ git ... itle }} | semmle.label | ${{ git ... itle }} |
| .github/workflows/matrix.yml:15:7:16:4 | matrix: ... iles }} [matrix] | semmle.label | matrix: ... iles }} [matrix] |
| .github/workflows/matrix.yml:15:7:16:4 | Job outputs node [matrix] | semmle.label | Job outputs node [matrix] |
| .github/workflows/matrix.yml:15:15:15:63 | ${{ ste ... iles }} | semmle.label | ${{ ste ... iles }} |
| .github/workflows/matrix.yml:17:9:21:2 | name: G ... d files | semmle.label | name: G ... d files |
| .github/workflows/matrix.yml:17:9:21:2 | Uses Step: set-matrix | semmle.label | Uses Step: set-matrix |
| .github/workflows/matrix.yml:34:19:34:69 | ${{ fro ... rix) }} | semmle.label | ${{ fro ... rix) }} |
| .github/workflows/matrix.yml:41:12:42:31 | \| | semmle.label | \| |
| .github/workflows/pull_request_review.yml:7:12:7:56 | echo '$ ... tle }}' | semmle.label | echo '$ ... tle }}' |
@@ -130,20 +163,20 @@ nodes
| .github/workflows/push.yml:14:12:14:64 | echo '$ ... ame }}' | semmle.label | echo '$ ... ame }}' |
| .github/workflows/push.yml:15:12:15:65 | echo '$ ... ail }}' | semmle.label | echo '$ ... ail }}' |
| .github/workflows/push.yml:16:12:16:64 | echo '$ ... ame }}' | semmle.label | echo '$ ... ame }}' |
| .github/workflows/simple1.yml:8:9:14:6 | id: summary [value] | semmle.label | id: summary [value] |
| .github/workflows/simple1.yml:8:9:14:6 | Uses Step: summary [value] | semmle.label | Uses Step: summary [value] |
| .github/workflows/simple1.yml:11:19:11:57 | ${{ git ... sage }} | semmle.label | ${{ git ... sage }} |
| .github/workflows/simple1.yml:15:14:16:50 | \| | semmle.label | \| |
| .github/workflows/simple2.yml:14:9:18:6 | name: G ... d files | semmle.label | name: G ... d files |
| .github/workflows/simple2.yml:18:9:26:6 | name: R ... d files [value] | semmle.label | name: R ... d files [value] |
| .github/workflows/simple2.yml:14:9:18:6 | Uses Step: source | semmle.label | Uses Step: source |
| .github/workflows/simple2.yml:18:9:26:6 | Uses Step: step [value] | semmle.label | Uses Step: step [value] |
| .github/workflows/simple2.yml:22:19:22:63 | ${{ ste ... iles }} | semmle.label | ${{ ste ... iles }} |
| .github/workflows/simple2.yml:28:14:31:15 | \| | semmle.label | \| |
| .github/workflows/test.yml:8:7:10:4 | job_out ... test }} [job_output] | semmle.label | job_out ... test }} [job_output] |
| .github/workflows/test.yml:8:7:10:4 | Job outputs node [job_output] | semmle.label | Job outputs node [job_output] |
| .github/workflows/test.yml:8:19:8:49 | ${{ ste ... test }} | semmle.label | ${{ ste ... test }} |
| .github/workflows/test.yml:12:9:18:6 | id: step0 [value] | semmle.label | id: step0 [value] |
| .github/workflows/test.yml:12:9:18:6 | Uses Step: step0 [value] | semmle.label | Uses Step: step0 [value] |
| .github/workflows/test.yml:15:19:15:57 | ${{ git ... sage }} | semmle.label | ${{ git ... sage }} |
| .github/workflows/test.yml:18:9:24:6 | id: step1 [MSG] | semmle.label | id: step1 [MSG] |
| .github/workflows/test.yml:18:9:24:6 | Run Step: step1 [MSG] | semmle.label | Run Step: step1 [MSG] |
| .github/workflows/test.yml:20:17:20:47 | ${{ ste ... value}} | semmle.label | ${{ ste ... value}} |
| .github/workflows/test.yml:24:9:29:2 | id: step2 [test] | semmle.label | id: step2 [test] |
| .github/workflows/test.yml:24:9:29:2 | Run Step: step2 [test] | semmle.label | Run Step: step2 [test] |
| .github/workflows/test.yml:26:18:26:45 | ${{step ... s.MSG}} | semmle.label | ${{step ... s.MSG}} |
| .github/workflows/test.yml:37:14:37:52 | echo ${ ... utput}} | semmle.label | echo ${ ... utput}} |
| .github/workflows/workflow_run.yml:9:12:9:64 | echo '$ ... tle }}' | semmle.label | echo '$ ... tle }}' |
@@ -158,7 +191,7 @@ nodes
subpaths
#select
| .github/workflows/argus_case_study.yml:26:14:27:95 | \| | .github/workflows/argus_case_study.yml:17:24:17:52 | ${{gith ... title}} | .github/workflows/argus_case_study.yml:26:14:27:95 | \| | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/changed-files.yml:21:14:24:15 | \| | .github/workflows/changed-files.yml:16:9:20:6 | name: G ... d files | .github/workflows/changed-files.yml:21:14:24:15 | \| | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/changed-files.yml:21:14:24:15 | \| | .github/workflows/changed-files.yml:16:9:20:6 | Uses Step: changed-files | .github/workflows/changed-files.yml:21:14:24:15 | \| | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/comment_issue.yml:7:12:8:48 | \| | .github/workflows/comment_issue.yml:7:12:8:48 | \| | .github/workflows/comment_issue.yml:7:12:8:48 | \| | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/comment_issue.yml:13:12:13:50 | echo '$ ... ody }}' | .github/workflows/comment_issue.yml:13:12:13:50 | echo '$ ... ody }}' | .github/workflows/comment_issue.yml:13:12:13:50 | echo '$ ... ody }}' | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/comment_issue.yml:14:12:14:48 | echo '$ ... ody }}' | .github/workflows/comment_issue.yml:14:12:14:48 | echo '$ ... ody }}' | .github/workflows/comment_issue.yml:14:12:14:48 | echo '$ ... ody }}' | Potential expression injection, which may be controlled by an external user. |
@@ -176,13 +209,16 @@ subpaths
| .github/workflows/gollum.yml:9:12:9:56 | echo '$ ... ame }}' | .github/workflows/gollum.yml:9:12:9:56 | echo '$ ... ame }}' | .github/workflows/gollum.yml:9:12:9:56 | echo '$ ... ame }}' | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/gollum.yml:10:12:10:59 | echo '$ ... ame }}' | .github/workflows/gollum.yml:10:12:10:59 | echo '$ ... ame }}' | .github/workflows/gollum.yml:10:12:10:59 | echo '$ ... ame }}' | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/image_link_generator.yml:36:14:37:126 | \| | .github/workflows/image_link_generator.yml:18:17:18:48 | ${{ git ... body }} | .github/workflows/image_link_generator.yml:36:14:37:126 | \| | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/inter-job.yml:36:14:36:52 | echo ${ ... utput}} | .github/workflows/inter-job.yml:15:9:19:6 | name: G ... d files | .github/workflows/inter-job.yml:36:14:36:52 | echo ${ ... utput}} | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/inter-job0.yml:43:14:43:52 | echo ${ ... utput}} | .github/workflows/inter-job0.yml:22:9:26:6 | Uses Step: source | .github/workflows/inter-job0.yml:43:14:43:52 | echo ${ ... utput}} | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/inter-job1.yml:43:14:43:52 | echo ${ ... utput}} | .github/workflows/inter-job1.yml:22:9:26:6 | Uses Step: source | .github/workflows/inter-job1.yml:43:14:43:52 | echo ${ ... utput}} | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/inter-job2.yml:45:14:45:52 | echo ${ ... utput}} | .github/workflows/inter-job2.yml:22:9:26:6 | Uses Step: source | .github/workflows/inter-job2.yml:45:14:45:52 | echo ${ ... utput}} | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/inter-job4.yml:44:14:44:52 | echo ${ ... utput}} | .github/workflows/inter-job4.yml:22:9:26:6 | Uses Step: source | .github/workflows/inter-job4.yml:44:14:44:52 | echo ${ ... utput}} | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/issues.yaml:13:12:13:49 | echo '$ ... tle }}' | .github/workflows/issues.yaml:13:12:13:49 | echo '$ ... tle }}' | .github/workflows/issues.yaml:13:12:13:49 | echo '$ ... tle }}' | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/issues.yaml:14:12:14:48 | echo '$ ... ody }}' | .github/workflows/issues.yaml:14:12:14:48 | echo '$ ... ody }}' | .github/workflows/issues.yaml:14:12:14:48 | echo '$ ... ody }}' | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/issues.yaml:15:12:15:39 | echo '$ ... env }}' | .github/workflows/issues.yaml:4:15:4:45 | ${{ git ... itle }} | .github/workflows/issues.yaml:15:12:15:39 | echo '$ ... env }}' | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/issues.yaml:17:12:17:36 | echo '$ ... env }}' | .github/workflows/issues.yaml:10:16:10:46 | ${{ git ... itle }} | .github/workflows/issues.yaml:17:12:17:36 | echo '$ ... env }}' | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/issues.yaml:18:12:18:37 | echo '$ ... env }}' | .github/workflows/issues.yaml:20:19:20:49 | ${{ git ... itle }} | .github/workflows/issues.yaml:18:12:18:37 | echo '$ ... env }}' | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/matrix.yml:41:12:42:31 | \| | .github/workflows/matrix.yml:17:9:21:2 | name: G ... d files | .github/workflows/matrix.yml:41:12:42:31 | \| | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/matrix.yml:41:12:42:31 | \| | .github/workflows/matrix.yml:17:9:21:2 | Uses Step: set-matrix | .github/workflows/matrix.yml:41:12:42:31 | \| | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/pull_request_review.yml:7:12:7:56 | echo '$ ... tle }}' | .github/workflows/pull_request_review.yml:7:12:7:56 | echo '$ ... tle }}' | .github/workflows/pull_request_review.yml:7:12:7:56 | echo '$ ... tle }}' | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/pull_request_review.yml:8:12:8:55 | echo '$ ... ody }}' | .github/workflows/pull_request_review.yml:8:12:8:55 | echo '$ ... ody }}' | .github/workflows/pull_request_review.yml:8:12:8:55 | echo '$ ... ody }}' | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/pull_request_review.yml:9:12:9:61 | echo '$ ... bel }}' | .github/workflows/pull_request_review.yml:9:12:9:61 | echo '$ ... bel }}' | .github/workflows/pull_request_review.yml:9:12:9:61 | echo '$ ... bel }}' | Potential expression injection, which may be controlled by an external user. |
@@ -220,7 +256,7 @@ subpaths
| .github/workflows/push.yml:15:12:15:65 | echo '$ ... ail }}' | .github/workflows/push.yml:15:12:15:65 | echo '$ ... ail }}' | .github/workflows/push.yml:15:12:15:65 | echo '$ ... ail }}' | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/push.yml:16:12:16:64 | echo '$ ... ame }}' | .github/workflows/push.yml:16:12:16:64 | echo '$ ... ame }}' | .github/workflows/push.yml:16:12:16:64 | echo '$ ... ame }}' | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/simple1.yml:15:14:16:50 | \| | .github/workflows/simple1.yml:11:19:11:57 | ${{ git ... sage }} | .github/workflows/simple1.yml:15:14:16:50 | \| | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/simple2.yml:28:14:31:15 | \| | .github/workflows/simple2.yml:14:9:18:6 | name: G ... d files | .github/workflows/simple2.yml:28:14:31:15 | \| | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/simple2.yml:28:14:31:15 | \| | .github/workflows/simple2.yml:14:9:18:6 | Uses Step: source | .github/workflows/simple2.yml:28:14:31:15 | \| | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/test.yml:37:14:37:52 | echo ${ ... utput}} | .github/workflows/test.yml:15:19:15:57 | ${{ git ... sage }} | .github/workflows/test.yml:37:14:37:52 | echo ${ ... utput}} | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/workflow_run.yml:9:12:9:64 | echo '$ ... tle }}' | .github/workflows/workflow_run.yml:9:12:9:64 | echo '$ ... tle }}' | .github/workflows/workflow_run.yml:9:12:9:64 | echo '$ ... tle }}' | Potential expression injection, which may be controlled by an external user. |
| .github/workflows/workflow_run.yml:10:12:10:70 | echo '$ ... age }}' | .github/workflows/workflow_run.yml:10:12:10:70 | echo '$ ... age }}' | .github/workflows/workflow_run.yml:10:12:10:70 | echo '$ ... age }}' | Potential expression injection, which may be controlled by an external user. |

View File

@@ -1 +1 @@
| .github/workflows/missing_perms.yml:6:5:9:32 | name: Build and test | Actions Job or Workflow does not set permissions |
| .github/workflows/missing_perms.yml:6:5:9:32 | Job: build | Actions Job or Workflow does not set permissions |

View File

@@ -1,7 +1,7 @@
| .github/workflows/actor_trusted_checkout.yml:19:7:23:4 | uses: c ... tion@v2 | Unpinned 3rd party Action 'actor_trusted_checkout.yml' step $@ uses 'completely/fakeaction' with ref 'v2', not a pinned commit hash | .github/workflows/actor_trusted_checkout.yml:19:7:23:4 | uses: c ... tion@v2 | uses: c ... tion@v2 |
| .github/workflows/actor_trusted_checkout.yml:23:7:26:21 | uses: f ... n-pr@v1 | Unpinned 3rd party Action 'actor_trusted_checkout.yml' step $@ uses 'fakerepo/comment-on-pr' with ref 'v1', not a pinned commit hash | .github/workflows/actor_trusted_checkout.yml:23:7:26:21 | uses: f ... n-pr@v1 | uses: f ... n-pr@v1 |
| .github/workflows/label_trusted_checkout.yml:20:7:24:4 | uses: c ... tion@v2 | Unpinned 3rd party Action 'label_trusted_checkout.yml' step $@ uses 'completely/fakeaction' with ref 'v2', not a pinned commit hash | .github/workflows/label_trusted_checkout.yml:20:7:24:4 | uses: c ... tion@v2 | uses: c ... tion@v2 |
| .github/workflows/label_trusted_checkout.yml:24:7:27:21 | uses: f ... n-pr@v1 | Unpinned 3rd party Action 'label_trusted_checkout.yml' step $@ uses 'fakerepo/comment-on-pr' with ref 'v1', not a pinned commit hash | .github/workflows/label_trusted_checkout.yml:24:7:27:21 | uses: f ... n-pr@v1 | uses: f ... n-pr@v1 |
| .github/workflows/unpinned_tags.yml:10:7:11:4 | uses: foo/bar@v1 | Unpinned 3rd party Action 'unpinned_tags.yml' step $@ uses 'foo/bar' with ref 'v1', not a pinned commit hash | .github/workflows/unpinned_tags.yml:10:7:11:4 | uses: foo/bar@v1 | uses: foo/bar@v1 |
| .github/workflows/untrusted_checkout.yml:18:7:22:4 | uses: c ... tion@v2 | Unpinned 3rd party Action 'untrusted_checkout.yml' step $@ uses 'completely/fakeaction' with ref 'v2', not a pinned commit hash | .github/workflows/untrusted_checkout.yml:18:7:22:4 | uses: c ... tion@v2 | uses: c ... tion@v2 |
| .github/workflows/untrusted_checkout.yml:22:7:25:21 | uses: f ... n-pr@v1 | Unpinned 3rd party Action 'untrusted_checkout.yml' step $@ uses 'fakerepo/comment-on-pr' with ref 'v1', not a pinned commit hash | .github/workflows/untrusted_checkout.yml:22:7:25:21 | uses: f ... n-pr@v1 | uses: f ... n-pr@v1 |
| .github/workflows/actor_trusted_checkout.yml:19:7:23:4 | Uses Step | Unpinned 3rd party Action 'actor_trusted_checkout.yml' step $@ uses 'completely/fakeaction' with ref 'v2', not a pinned commit hash | .github/workflows/actor_trusted_checkout.yml:19:7:23:4 | Uses Step | Uses Step |
| .github/workflows/actor_trusted_checkout.yml:23:7:26:21 | Uses Step | Unpinned 3rd party Action 'actor_trusted_checkout.yml' step $@ uses 'fakerepo/comment-on-pr' with ref 'v1', not a pinned commit hash | .github/workflows/actor_trusted_checkout.yml:23:7:26:21 | Uses Step | Uses Step |
| .github/workflows/label_trusted_checkout.yml:20:7:24:4 | Uses Step | Unpinned 3rd party Action 'label_trusted_checkout.yml' step $@ uses 'completely/fakeaction' with ref 'v2', not a pinned commit hash | .github/workflows/label_trusted_checkout.yml:20:7:24:4 | Uses Step | Uses Step |
| .github/workflows/label_trusted_checkout.yml:24:7:27:21 | Uses Step | Unpinned 3rd party Action 'label_trusted_checkout.yml' step $@ uses 'fakerepo/comment-on-pr' with ref 'v1', not a pinned commit hash | .github/workflows/label_trusted_checkout.yml:24:7:27:21 | Uses Step | Uses Step |
| .github/workflows/unpinned_tags.yml:10:7:11:4 | Uses Step | Unpinned 3rd party Action 'unpinned_tags.yml' step $@ uses 'foo/bar' with ref 'v1', not a pinned commit hash | .github/workflows/unpinned_tags.yml:10:7:11:4 | Uses Step | Uses Step |
| .github/workflows/untrusted_checkout.yml:18:7:22:4 | Uses Step | Unpinned 3rd party Action 'untrusted_checkout.yml' step $@ uses 'completely/fakeaction' with ref 'v2', not a pinned commit hash | .github/workflows/untrusted_checkout.yml:18:7:22:4 | Uses Step | Uses Step |
| .github/workflows/untrusted_checkout.yml:22:7:25:21 | Uses Step | Unpinned 3rd party Action 'untrusted_checkout.yml' step $@ uses 'fakerepo/comment-on-pr' with ref 'v1', not a pinned commit hash | .github/workflows/untrusted_checkout.yml:22:7:25:21 | Uses Step | Uses Step |

View File

@@ -1 +1 @@
| .github/workflows/untrusted_checkout.yml:9:7:13:4 | uses: a ... kout@v2 | Potential unsafe checkout of untrusted pull request on 'pull_request_target'. |
| .github/workflows/untrusted_checkout.yml:9:7:13:4 | Uses Step | Potential unsafe checkout of untrusted pull request on 'pull_request_target'. |