Skip to content

Commit

Permalink
Showing 2 changed files with 44 additions and 2 deletions.
4 changes: 4 additions & 0 deletions analyze/action.yml
@@ -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:
42 changes: 40 additions & 2 deletions queries/undeclared-action-input.ql
@@ -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)
}
@@ -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").
@@ -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
}
@@ -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()
}
@@ -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()

0 comments on commit c7c1aa8

Please sign in to comment.