Skip to content

JSScriptInjection

JavaScript vulnerable to script injection.

Defined by ScriptInjectionRule which supports workflows, actions in the "Default" ruleset along with ShellScriptInjection.

Description

Using ${{ }} in actions/github-script JavaScript is vulnerable to script injection. Script injection is when a user can control part of the script, and can inject arbitrary code. In most cases this is a security vulnerability, but at the very least it's a bug. All user input must be sanitized before being executed as JavaScript code.

The simplest way to achieve this is using environment variables to pass data as inputs to script code. Node know how to handle them: process.env.XXX. With environment variables data travels in memory, rather than becoming part of the executable code.

References:

Compliant example

Script injection is impossible, because the script is a static constant. The input is provided via an Environment Variable, already typed as string.

example.yml

on: push
jobs:
  example:
    runs-on: ubuntu-latest
    steps:
      - name: "Remove prefix from PR title."
        uses: actions/github-script@v7
        env:
          PR_TITLE: ${{ github.event.pull_request.title }}
        with:
          script: |
            const title = process.env.PR_TITLE;
            return title.replaceAll(/JIRA-\d+ /, "");

Non-compliant example

Script injection breaks JavaScript execution.

The actual script input depends on the Pull Request's actual title. In most cases, it'll be ok:

const title = "JIRA-1234 Fix the thing";
return title.replaceAll(/JIRA-\d+ /, "");

But then there are a lot of titles which just break the syntax:

In the best case, it's a straight-up compilation error:

const title = "JIRA-1234 Remove " from logs";
return title.replaceAll(/JIRA-\d+ /, "");
but in the worst case, this can expose secrets or execute arbitrary code.

example.yml

on: pull_request
jobs:
  example:
    runs-on: ubuntu-latest
    steps:
      - name: "Remove prefix from PR title."
        uses: actions/github-script@v7
        with:
          script: |
            const title = "${{ github.event.pull_request.title }}";
            return title.replaceAll(/JIRA-\d+ /, "");

  • Line 6: Step["Remove prefix from PR title."] in Job[example] JavaScript contains GitHub Expressions.