mirror of
https://github.com/github/codeql.git
synced 2026-04-30 03:05:15 +02:00
Merge pull request #26 from GitHubSecurityLab/refactor_ast
Refactor AST layer
This commit is contained in:
2
clean.sh
Executable file
2
clean.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
#! /bin/bash
|
||||
find . -type d -name "*testproj*" -exec rm -r {} +
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -442,4 +442,3 @@ class ConditionBlock extends BasicBlock {
|
||||
*/
|
||||
predicate controls(BasicBlock controlled, BooleanSuccessor s) { controls(this, controlled, s) }
|
||||
}
|
||||
|
||||
|
||||
@@ -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 { }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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" }
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
|
||||
@@ -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() }
|
||||
|
||||
@@ -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
|
||||
@@ -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() }
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'."
|
||||
|
||||
@@ -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}} |
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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 }}." |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
43
ql/test/query-tests/Security/CWE-094/.github/workflows/inter-job1.yml
vendored
Normal file
43
ql/test/query-tests/Security/CWE-094/.github/workflows/inter-job1.yml
vendored
Normal 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}}
|
||||
45
ql/test/query-tests/Security/CWE-094/.github/workflows/inter-job2.yml
vendored
Normal file
45
ql/test/query-tests/Security/CWE-094/.github/workflows/inter-job2.yml
vendored
Normal 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}}
|
||||
44
ql/test/query-tests/Security/CWE-094/.github/workflows/inter-job4.yml
vendored
Normal file
44
ql/test/query-tests/Security/CWE-094/.github/workflows/inter-job4.yml
vendored
Normal 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}}
|
||||
45
ql/test/query-tests/Security/CWE-094/.github/workflows/inter-job5.yml
vendored
Normal file
45
ql/test/query-tests/Security/CWE-094/.github/workflows/inter-job5.yml
vendored
Normal 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}}
|
||||
@@ -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. |
|
||||
|
||||
@@ -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. |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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'. |
|
||||
|
||||
Reference in New Issue
Block a user