Skip to content

Twelve high-severity cache-poisoning alerts have been open on quality.yml since 13 August, so the CodeQL cell is red on every PR and reads as normal #737

Description

@rubenvdlinde

Filed after #736 was merged past a red CodeQL cell. The merge was right and the alert is inherited rather than introduced, and that is precisely the problem worth writing down: this cell has been red for a month, it is red on every PR, and the reason it is safe to merge past is now discovered by hand each time.

What is actually open

Queried today from the code scanning API, all state open:

count severity rule
12 high actions/cache-poisoning/poisonable-step
1 high actions/cache-poisoning/direct-cache
1 high py/bad-tag-filter
2 medium py/stack-trace-exposure

All 13 cache poisoning alerts are in one file, .github/workflows/quality.yml, and all 13 were created on 13 or 16 August:

 8  2026-08-13  quality.yml:3502     19  2026-08-16  quality.yml:3717
 9  2026-08-13  quality.yml:3589     13  2026-08-13  quality.yml:5939
10  2026-08-13  quality.yml:5390     14  2026-08-13  quality.yml:6908
11  2026-08-13  quality.yml:5438     15  2026-08-13  quality.yml:6978
12  2026-08-13  quality.yml:5562     16  2026-08-13  quality.yml:7275
17  2026-08-13  quality.yml:8288     18  2026-08-13  quality.yml:8399
 7  2026-08-13  quality.yml:8268     (direct-cache)

The rule is Cache Poisoning via execution of untrusted code. The shape is the familiar one: a job that runs repository code, in a context that can write the Actions cache, on a workflow that is pull_request-triggered. quality.yml is consumed by all 21 core apps, so whatever the right answer is, it is the same answer 21 times.

Why it needs an issue rather than a triage

The alerts were not suppressed and nobody has decided they are acceptable. What has happened instead is that each merge rediscovers, individually, that the red is old. For #736 the evidence was: alerts created a month before the branch existed, a branch first pushed the previous afternoon, a diff touching no workflow file at all, and a pull_request code scanning check that reports the alerts present in the merge commit rather than the alerts the PR introduced.

That evidence is sound and it is also the problem. A check that is red for everyone is a check nobody reads, and "we have many of these" is exactly what makes one more read as normal. The next PR that genuinely introduces a fourteenth alert arrives on a cell that has looked the same since August.

This is the same failure this repository has already paid for elsewhere, in the other direction: gate-112 printed FAIL on a run that did not fail, and two readers counted a failure that had not happened (#729). Here a real high severity finding sits inside a signal everyone has learned to step over. A check that always says the same thing carries no information either way.

What would close this

One of three, decided rather than defaulted:

  1. Fix them. Scope the cache writes so the poisonable steps cannot reach them, or drop caching from the jobs that run untrusted code. Thirteen sites in one file, one fix shape.
  2. Dismiss them with a reason, per alert or via a rule configuration, so the cell goes green and a new alert is visible the day it lands. A dismissal that states why is a decision; a permanently red cell is not.
  3. Change what the PR check reports, so it distinguishes alerts introduced by the diff from alerts present in the base. That is the only option that fixes the reading problem without touching the alerts themselves.

Option 2 or 3 restores the signal in an afternoon. Option 1 is the one that removes the finding. Doing none of them keeps a month old high severity alert in a place where its own age is the argument for ignoring it.

Not in scope here

py/bad-tag-filter and the two py/stack-trace-exposure alerts are unrelated to the cache family and are listed above only so the total is honest.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions