Skip to content

Product1 publisher3 min readPublished

CodeQL 2.26.3 treats workflow files as code, and cache poisoning as a finding you must triage

GitHub's August release retunes Actions queries for cache poisoning, output clobbering and untrusted checkouts. Most of the work went into cutting false positives, not adding coverage.

The Product Desk · Product desk

Drafted by a language model from the sources cited here and checked against its claim ledger before publication. How we use AISend a correction

What happened

  • CodeQL 2.26.3 was released August 12 and detailed in GitHub's changelog on August 19.
  • CodeQL 2.26.3 sharpens GitHub Actions security queries for cache poisoning, output clobbering and untrusted checkouts.
  • GitHub Actions pipelines pull in third-party actions, cache dependencies and pass secrets between jobs, often without anyone reviewing the workflow file as closely as they would review application code, and that gap is where cache-poisoning and output-clobbering attacks live.
  • The release keeps CodeQL's default security suite at 497 queries covering 170 CWE categories, with an extended suite adding another 131 queries across 32 more CWEs.
  • Default and extended suites combined total 628 queries and 202 CWE categories.

Compiled by The Product DeskSomething wrong?How this is made

Why it matters

GitHub shipped CodeQL 2.26.3 on August 12 and documented it in its changelog on August 19, with the Actions-facing changes aimed at cache poisoning, output clobbering and untrusted checkouts [1][2]. The practical consequence for platform teams is that a class of CI risk that used to live in unreviewed YAML now arrives as an alert with a path, an owner and a triage cost [3][12].

The framing is worth stating plainly. Actions pipelines pull in third-party actions, cache dependencies and pass secrets between jobs, usually without anyone reading the workflow file as closely as they read application code, and that gap is where cache-poisoning and output-clobbering attacks live [3]. "Workflow files are production code that nobody reviews like production code," said Mitch Ashley, an analyst with Futurum Group, who added that platform teams inherit the fallout when a poisoned cache reaches a build [12].

Almost none of this release is new coverage. The default security suite stays at 497 queries across 170 CWE categories, with an extended suite adding 131 more queries across 32 additional CWEs [4], for a combined 628 queries and 202 CWEs [5]. The effort went into precision instead. The output-clobbering query now tailors its message to the specific output channel it flags, and it stops flagging simple jq path filters whose output remains JSON-encoded [6]. GitHub also fixed a performance problem in that query caused by unescaped source-code input in a regular expression [7].

The routing change matters more than it sounds. Alert paths for the cache-poisoning and untrusted-checkout queries now start at the expressions that control the untrusted checkout, so the alert points at the responsible code rather than upstream, leaving the reader to trace it back [8]. The cache-poisoning queries also account for read-only cache access in low-trust triggers, which should stop alerts on workflows that touch a cache but cannot poison it [9]. Two related fixes narrow the blast radius further: CodeQL now classifies the schedule event correctly when deciding whether a workflow is externally triggerable [10], and the environment-variable injection query requires the untrusted source and the privileged context to come from the same trigger event before it fires [11]. Every one of those is a bet that triage capacity, not query count, is the binding constraint [12].

There is a breaking change. GitHub removed the codeql.actions.security.SelfHostedQuery module because runner labels alone could not reliably distinguish self-hosted runners from GitHub-hosted ones, so custom queries built on it need rework [13]. That is an honest admission about a signal many teams have been treating as authoritative.

On the JavaScript and TypeScript side, Vue Router's useRoute() is now a client-side remote flow source and flow models were added for Composition API helpers including ref, shallowRef, toRef, reactive and computed [14]. CodeQL also added Sails Action2 controllers, treating declared input properties as remote flow sources, recognises @fastify/rate-limit when checking for missing rate limiting, and now tracks promise-wrapped client response data into promise fulfillment values [15][16][17]. Custom queries can reference specific files with file:<path> syntax, which lets you tie sources and sinks to one exported API instead of a whole package [18].

What to watch: whether alert volume on Actions queries actually falls after the read-only-cache and same-trigger-event conditions land, and how many internal query packs break on the SelfHostedQuery removal.

Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories