зеркало из https://github.com/github/codeql.git
Look for script injections in actions/github-script
This commit is contained in:
Родитель
e941218e30
Коммит
8ea418216c
|
@ -244,6 +244,40 @@ module Actions {
|
|||
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)
|
||||
}
|
||||
|
||||
/**
|
||||
* A `script:` field within an Actions `with:` specific to `actions/github-script` action.
|
||||
*
|
||||
* For example:
|
||||
* ```
|
||||
* uses: actions/github-script@v3
|
||||
* with:
|
||||
* script: console.log('${{ github.event.pull_request.head.sha }}')
|
||||
* ```
|
||||
*/
|
||||
class Script extends YamlNode, YamlString {
|
||||
With with;
|
||||
|
||||
Script() { with.lookup("script") = this }
|
||||
|
||||
/** Gets the `with` field this field belongs to. */
|
||||
With getWith() { result = with }
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
@ -255,20 +289,5 @@ module Actions {
|
|||
|
||||
/** Gets the step that executes this `run` command. */
|
||||
Step getStep() { result = step }
|
||||
|
||||
/**
|
||||
* Holds if `${{ e }}` is a GitHub Actions expression evaluated within this `run` command.
|
||||
* 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() {
|
||||
// We use `regexpFind` to obtain *all* matches of `${{...}}`,
|
||||
// not just the last (greedy match) or first (reluctant match).
|
||||
result =
|
||||
this.getValue()
|
||||
.regexpFind("\\$\\{\\{\\s*[A-Za-z0-9_\\[\\]\\*\\(\\)\\.\\-]+\\s*\\}\\}", _, _)
|
||||
.regexpCapture("\\$\\{\\{\\s*([A-Za-z0-9_\\[\\]\\*\\((\\)\\.\\-]+)\\s*\\}\\}", 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,10 +103,24 @@ private predicate isExternalUserControlledWorkflowRun(string context) {
|
|||
)
|
||||
}
|
||||
|
||||
from Actions::Run run, string context, Actions::On on
|
||||
from YamlNode node, string context, Actions::On on
|
||||
where
|
||||
run.getASimpleReferenceExpression() = context and
|
||||
run.getStep().getJob().getWorkflow().getOn() = on and
|
||||
(
|
||||
exists(Actions::Run run |
|
||||
node = run and
|
||||
Actions::getASimpleReferenceExpression(run) = context and
|
||||
run.getStep().getJob().getWorkflow().getOn() = on
|
||||
)
|
||||
or
|
||||
exists(Actions::Script script, Actions::Step step, Actions::Uses uses |
|
||||
node = script and
|
||||
script.getWith().getStep() = step and
|
||||
uses.getStep() = step and
|
||||
uses.getGitHubRepository() = "actions/github-script" and
|
||||
Actions::getASimpleReferenceExpression(script) = context and
|
||||
script.getWith().getStep().getJob().getWorkflow().getOn() = on
|
||||
)
|
||||
) and
|
||||
(
|
||||
exists(on.getNode("issues")) and
|
||||
isExternalUserControlledIssue(context)
|
||||
|
@ -138,6 +152,6 @@ where
|
|||
exists(on.getNode("workflow_run")) and
|
||||
isExternalUserControlledWorkflowRun(context)
|
||||
)
|
||||
select run,
|
||||
select node,
|
||||
"Potential injection from the " + context +
|
||||
" context, which may be controlled by an external user."
|
||||
|
|
|
@ -12,4 +12,17 @@ jobs:
|
|||
steps:
|
||||
- run: echo '${{ github.event.comment.body }}'
|
||||
- run: echo '${{ github.event.issue.body }}'
|
||||
- run: echo '${{ github.event.issue.title }}'
|
||||
- run: echo '${{ github.event.issue.title }}'
|
||||
|
||||
echo-chamber3:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/github-script@v3
|
||||
with:
|
||||
script: console.log('${{ github.event.comment.body }}')
|
||||
- uses: actions/github-script@v3
|
||||
with:
|
||||
script: console.log('${{ github.event.issue.body }}')
|
||||
- uses: actions/github-script@v3
|
||||
with:
|
||||
script: console.log('${{ github.event.issue.title }}')
|
|
@ -2,6 +2,9 @@
|
|||
| .github/workflows/comment_issue.yml:13:12:13:50 | echo '$ ... ody }}' | Potential injection from the github.event.comment.body context, which may be controlled by an external user. |
|
||||
| .github/workflows/comment_issue.yml:14:12:14:48 | echo '$ ... ody }}' | Potential injection from the github.event.issue.body context, which may be controlled by an external user. |
|
||||
| .github/workflows/comment_issue.yml:15:12:15:49 | echo '$ ... tle }}' | Potential injection from the github.event.issue.title context, which may be controlled by an external user. |
|
||||
| .github/workflows/comment_issue.yml:22:17:22:63 | console ... dy }}') | Potential injection from the github.event.comment.body context, which may be controlled by an external user. |
|
||||
| .github/workflows/comment_issue.yml:25:17:25:61 | console ... dy }}') | Potential injection from the github.event.issue.body context, which may be controlled by an external user. |
|
||||
| .github/workflows/comment_issue.yml:28:17:28:62 | console ... le }}') | Potential injection from the github.event.issue.title context, which may be controlled by an external user. |
|
||||
| .github/workflows/comment_issue_newline.yml:9:14:10:50 | \| | Potential injection from the github.event.comment.body context, which may be controlled by an external user. |
|
||||
| .github/workflows/discussion.yml:7:12:7:54 | echo '$ ... tle }}' | Potential injection from the github.event.discussion.title context, which may be controlled by an external user. |
|
||||
| .github/workflows/discussion.yml:8:12:8:53 | echo '$ ... ody }}' | Potential injection from the github.event.discussion.body context, which may be controlled by an external user. |
|
||||
|
|
Загрузка…
Ссылка в новой задаче