Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions analyze/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ inputs:
description: The number of threads to be used by CodeQL.
required: false
default: "1"
checkout_path:
description: "The path at which the analyzed repository was checked out. Used to relativeize any absolute paths in the uploaded SARIF file."
required: false
default: ${{ github.workspace }}
token:
default: ${{ github.token }}
matrix:
Expand Down
42 changes: 40 additions & 2 deletions queries/undeclared-action-input.ql
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,17 @@

import javascript

/**
* A declaration of a github action, including its inputs and entrypoint.
*/
class ActionDeclaration extends File {
ActionDeclaration() {
getRelativePath().matches("%/action.yml")
}

/**
* The name of the action.
*/
string getName() {
result = getRelativePath().regexpCapture("(.*)/action.yml", 1)
}
Expand All @@ -22,10 +28,16 @@ class ActionDeclaration extends File {
result.getFile() = this
}

/**
* The name of any input to this action.
*/
string getAnInput() {
result = getRootNode().(YAMLMapping).lookup("inputs").(YAMLMapping).getKey(_).(YAMLString).getValue()
}

/**
* The function that is the entrypoint to this action.
*/
FunctionDeclStmt getEntrypoint() {
result.getFile().getRelativePath() = getRootNode().
(YAMLMapping).lookup("runs").
Expand All @@ -35,6 +47,21 @@ class ActionDeclaration extends File {
}
}

/**
* A function declared on CodeQL interface from codeql.ts
*/
class CodeQLFunction extends Function {
CodeQLFunction() {
exists(Function getCodeQLForCmd, ObjectExpr obj |
getCodeQLForCmd.getName() = "getCodeQLForCmd" and
obj = getCodeQLForCmd.getAStmt().(ReturnStmt).getExpr() and
obj.getAProperty().getInit() = this)
}
}

/**
* Any expr that is a transitive child of the given function.
*/
Expr getAFunctionChildExpr(Function f) {
result.getContainer() = f
}
Expand All @@ -45,14 +72,25 @@ Expr getAFunctionChildExpr(Function f) {
Function calledBy(Function f) {
result = getAFunctionChildExpr(f).(InvokeExpr).getResolvedCallee()
or
result.getEnclosingContainer() = f // assume outer function causes inner function to be called
// Assume outer function causes inner function to be called,
// except for the special case of the CodeQL functions.
(result.getEnclosingContainer() = f and not result instanceof CodeQLFunction)
or
// Handle calls to CodeQL functions by name
getAFunctionChildExpr(f).(InvokeExpr).getCalleeName() = result.(CodeQLFunction).getName()
}

/**
* A call to the core.getInput method.
*/
class GetInputMethodCallExpr extends MethodCallExpr {
GetInputMethodCallExpr() {
getMethodName() = "getInput"
}

/**
* The name of the input being accessed.
*/
string getInputName() {
result = getArgument(0).(StringLiteral).getValue()
}
Expand All @@ -62,4 +100,4 @@ from ActionDeclaration action, GetInputMethodCallExpr getInputCall, string input
where getAFunctionChildExpr(calledBy*(action.getEntrypoint())) = getInputCall and
inputName = getInputCall.getInputName() and
not inputName = action.getAnInput()
select getInputCall, "The $@ input is not defined for the $@ action", inputName, inputName, action, action.getName()
select getInputCall, "The $@ input is not defined for the $@ action", inputName, inputName, action, action.getName()