103 строки
2.9 KiB
Plaintext
103 строки
2.9 KiB
Plaintext
/**
|
|
* @name Undeclared action input
|
|
* @description Code tries to use an input parameter that is not defined for this action.
|
|
Perhaps this code is shared by multiple actions.
|
|
* @kind problem
|
|
* @problem.severity error
|
|
* @id javascript/codeql-action/undeclared-action-input
|
|
*/
|
|
|
|
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)
|
|
}
|
|
|
|
YamlDocument getRootNode() {
|
|
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").
|
|
(YamlMapping).lookup("main").
|
|
(YamlString).getValue().regexpReplaceAll("\\.\\./lib/(.*)\\.js", "src/$1.ts") and
|
|
result.getName() = "run"
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
}
|
|
|
|
/*
|
|
* Result is a function that is called from the body of the given function `f`
|
|
*/
|
|
Function calledBy(Function f) {
|
|
result = getAFunctionChildExpr(f).(InvokeExpr).getResolvedCallee()
|
|
or
|
|
// 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()
|
|
}
|
|
}
|
|
|
|
from ActionDeclaration action, GetInputMethodCallExpr getInputCall, string inputName
|
|
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() |