Your green CodeQL dashboard is not a security posture. It is a snapshot of what the current query pack agreed to ignore. Occasionally the query pack updates its mind. That is the interesting story inside the CodeQL 2.26.2 release note dated 4 August 2026: yes, it picks up Swift 6.3.3 and Kotlin 2.4.10, but the more useful line for anyone running code scanning in a pipeline is that several sanitizers just got taken off the safe list.
If you run CodeQL on github.com, this is already live. Every new CodeQL release is pushed automatically to hosted code scanning. Enterprise Server users wait for the next GHES cut, or upgrade the CLI manually. Either way, the next full analysis after the rollout may light up findings on code that was quiet last week. Not a bug.
The languages, first
The version-bump headline: Swift 6.3.3 is now analysable, and Kotlin support extends up to 2.4.10. If your iOS or Android repo was pinned to an older CodeQL image because the toolchain moved faster than the analyzer, that pin can come off. Practical: rerun the CodeQL extractor on your latest branch, confirm the build database is produced without falling back to a partial extraction, then let the queries run.
The quieter half of the note
Now the part that will actually change ticket counts. Four query-behaviour changes, each one a place where CodeQL used to swallow a taint flow it now surfaces:
- C#:
System.Web.HttpRequest.RawUrlno longer counts as a sanitizer for the URL redirection query. Thecs/useless-assignment-to-localcheck is also gone from the code-quality suite. - Go:
path/filepath.Relno longer sanitizes path injection or zipslip checks. - Java and Kotlin:
java.io.File.getName()no longer fully sanitizes path injection. - GitHub Actions: the
EnvironmentChecklogic was rewritten with TOCTOU (time-of-check to time-of-use) scenarios in mind.
Each one has the same shape. A method that felt "sanitize-y" was treated as a taint stopper. Someone eventually asked the awkward question: does calling File.getName() on a caller-controlled path actually neutralise the traversal? (Only for a limited definition of "neutralise".) So the query dropped it, and any place your code leaned on that assumption becomes a finding. That is CodeQL getting closer to the truth, not further from it.
The GitHub Actions rewrite is the one to read twice if you review workflows. TOCTOU in a job means the state a step checked at gate-time is not necessarily the state a later step operates on. Attacker control between check and use is where a lot of the recent poisoned-workflow reports live. The updated EnvironmentCheck is a step toward flagging those gaps.
Turning the surprise into a plan
A rollout playbook that keeps this from wrecking a Monday:
- Diff the alerts. On the first scan after the update, compare the new alert set against last week's for each affected language. Group by rule id: the ones tied to
cs/url-redirection,go/path-injection,java/path-injection, and anyactions/queries are the ones the release touched. - Triage before you dismiss. A "new" alert is a change in query behaviour, not necessarily new code. But it is also not a false positive by default. Read the flow.
- Fix upstream, not in the query. Do not add a
// lgtmor dismissal to make the number go down. IfFile.getName()was your defence, it was not a defence.
One deprecation to note while you are in the query files: alert messages no longer parse [[-style links. Use $@ placeholders in custom queries. If you maintain an internal query pack, grep before your next release.
How other analysers handle drift
Sanitizer drift is not a CodeQL quirk. It is what happens whenever an analyser has an opinion. Semgrep publishes rule changelogs per pack; Sonar labels rule updates by version and taxonomy; Snyk Code rev-locks its taint sources and sinks and calls out behavioural changes in release notes; Coverity ships checker updates on its own cadence with a diff document. The competent play is the same everywhere: pin the analyser version in CI, read the diff on upgrade, and treat "alert count went up on unchanged code" as a signal about your old baseline, not a regression in the tool.
Static analysis is a moving contract. When the sanitizer list shrinks, the honest response is to look at what got exposed. Not to file a bug against the tool for finally telling you.
Top comments (0)