Een gegenereerde abstracte illustratie op een donker leikleurig veld: een lange horizontale band van fijne bleekcyaan en amberkleurige lichtlijnen loopt van rand tot rand, breekt op één exact punt nabij het midden, en een enkele heldere amberkleurige scherf ontsnapt naar boven in een leeg donker kanaal daarboven; zwakke concentrische cirkels en gelinieerde rasterlijnen suggereren een pijplijn. Er verschijnen geen tekst, mensen of organisatielogo's. Het OrcaRouter-logo is in de rechteronderhoek gecompositeerd.
AI Safety Incidents

Snowflakes Jira-token: een fout die Copilot mede ondertekende, en waarvan GitHub zegt dat een mens ze schreef

Auteur

Gideon Frost

Publicatiedatum

Nieuwste modellen · 20Bekijk alle modellen →
Benchmarks: Artificial Analysis · dagelijks bijgewerkt
Terug naar alle berichten

Op 23 juni 2026 opende Red Agent, een autonome beveiligingsagent gebouwd door Wiz, een issue op een openbare GitHub-repository van Snowflake en kwam terug met een credential. De repository was snowflakedb/snowflake-connector-net, en de foutieve workflow, .github/workflows/jira_issue.yml, dient om een Jira-ticket aan te maken telkens wanneer iemand een issue opent — de titel van het ticket werd in een shellcommando verwerkt in plaats van via een omgevingsvariabele te worden doorgegeven, waardoor een speciaal samengestelde titel als code werd uitgevoerd op de GitHub Actions-runner. De token die Red Agent wist te bemachtigen, authenticeerde als qa@snowflake.net bij snowflakecomputing.atlassian.net en had leesrechten op de engineering-, security-compliance- en bug-bounty-Jira-projecten van Snowflake. De kwetsbaarheid was al vijf dagen actief. Wiz publiceerde op 17 augustus 2026 de volledige analyse. Dit incident is opgenomen als record 2026-08-17-snowflake-jira-zhao-dao-can in het Orca AI Incident Archive, dat de volledige recordset bevat met de betrouwbaarheidsgraden en geciteerde bronnen.

De interpolatie, en de guard die nooit werd uitgevoerd

De workflow werd getriggerd door het GitHub-event "issues: opened". Iedereen met een GitHub-account kon het in gang zetten door een issue te openen in een openbare repository — geen uitnodiging, geen maintainerrol, geen fork. De kwetsbare stap las de issue-titel in een shell-variabele: TITLE=$(echo '${{ github.event.issue.title }}' | sed ...), met twee filters die bedoeld waren om dubbele aanhalingstekens en enkele aanhalingstekens te escapen voordat de string werd samengesteld.

De fout zit in de volgorde van bewerkingen, niet in het escapen. GitHub vervangt de inhoud van de expressie door de scripttekst voordat bash die ooit parseert, dus een enkel aanhalingsteken in de issuetitel sluit de geciteerde tekenreeks die echo openhoudt. De twee sed-filters worden binnen datzelfde script uitgevoerd, na de vervanging, en kunnen de quoting niet herstellen die al heeft veranderd hoe de regel wordt geparseerd. Wiz' uiteenzetting is expliciet dat het escapen te laat komt om de uitbraak te voorkomen, en dat een titel die is gemaakt met een sluitend aanhalingsteken en een puntkomma opdrachten naar keuze van de aanvaller aan de run-stap toevoegt.

Een tweede controle had het publiek moeten beperken en deed dat niet. De job bevatte een if-voorwaarde die github.event.pull_request.user.login vergeleek met de login van de whitesource-for-github-com-bot, klaarblijkelijk om te voorkomen dat geautomatiseerde dependency-pull-requests tickets aanmaakten. Bij een issues-event is er helemaal geen pull request-object, dus de vergelijking wordt uitgevoerd tegen een null-eigenschap. GitHub's eigen documentatie, geciteerd door The Hacker News, stelt dat het derefereren van een niet-bestaande eigenschap een lege string oplevert; de analyse van Wiz komt via de null-waarde tot hetzelfde resultaat. Hoe dan ook evalueerde de voorwaarde voor elke gebruiker als true, en de uitzondering voor de bot werd een pass-through voor het internet.

Wat de injectie het melden waard maakte in plaats van routine, was de context waarin ze zich bevond. Dezelfde stap bevatte JIRA_BASE_URL, JIRA_USER_EMAIL en JIRA_API_TOKEN als omgevingsvariabelen, zodat bij willekeurige opdrachtexecutie op de runner inloggegevens binnen bereik waren in plaats van een leeg substraat. Er werd geen release van Snowflake Connector for .NET als getroffen geïdentificeerd: de zwakheid lag in de CI/CD-automatisering van de repository, niet in de geleverde connectorcode.

Wat Red Agent heeft meegenomen, en wat het zegt te hebben weggegooid.

Wiz' verslag van de exploitatie is het deel dat dit onderscheidt van een scannerbevinding. De eerste payload gebruikte een hekje, waardoor de sluitende haak van de TITLE=$(...)-toewijzing werd uitgecommentarieerd en er een bash-syntaxfout ontstond in plaats van een callback. De agent las de fout en herschreef de payload om het shellblok af te sluiten met een puntkomma en een nieuw echo-aanhalingsteken, en ontving vervolgens een out-of-band-aanroep. De payload gebruikte curl om een subdomein van oast.me te bereiken met base64-gecodeerde waarden van de drie inloggegevensvariabelen, en de callback kwam van Azure-IP 20.106.182.197, een adres dat Wiz toeschrijft aan een GitHub Actions-runner.

Het token dat het teruggaf, was een Jira API-token voor qa@snowflake.net, en Wiz beschrijft zijn bereik als leestoegang tot projecten voor engineering, security-compliance en bug-bounty-tracking op de Atlassian-cloudomgeving van Snowflake. Dat is de schade die in het archief wordt vastgelegd: niet vijf dagen lang code-uitvoering op een buildmachine, maar een credential dat de ticketwachtrijen kon lezen waarin niet-opgeloste engineering- en beveiligingsbugs worden geregistreerd — waaronder, volgens Wiz' beschrijving, de bug-bounty-tracker.

A self-built HTML card titled 'What the run step could reach', badged 'snowflakedb/snowflake-connector-net · .github/workflows/jira_issue.yml · 18-23 June 2026'. A left panel lists the environment variables held by the step: JIRA_BASE_URL, JIRA_USER_EMAIL, JIRA_API_TOKEN. A right panel reads: identity qa@snowflake.net; Jira host snowflakecomputing.atlassian.net; access, read across engineering, security-compliance and bug-bounty Jira projects. Three tiles read: trigger 'issues: opened'; account required 'any GitHub user'; token rotated '24 June 2026'. A footer cites Wiz Research, published 17 August 2026, and notes no CVE identifier accompanies the flaw.

Wiz zegt dat het alles wat het tijdens het proof of concept heeft benaderd, veilig heeft verwijderd. Snowflake zei in een verklaring aan CSO Online dat het rapport "onmiddellijk werd onderzocht en verholpen" en dat "ons onderzoek geen bewijs van ongeautoriseerde toegang heeft gevonden"; de blog van Wiz voegt toe dat Snowflake de auditlogs voor het venster van vijf dagen heeft bekeken en geen gebruik door derden heeft gevonden buiten de eigen testadressen van Wiz. Snowflake heeft die logs niet gepubliceerd, dus de conclusie dat er geen andere actor was, berust op zijn verklaring en op de samenvatting daarvan door Wiz, niet op documenten die iemand buiten de twee organisaties kan lezen.

Wie schreef de kwetsbare regel?

Die vraag leverde het tweede, grotere verhaal op. PR #1218, getiteld "SNOW-2069227: Update jira workflows", werd op 18 juni 2026 squash-merged als commit 4a1b8ce, en de squash-commit vermeldt Copilot Autofix powered by AI onder zijn medeauteurs. De oorspronkelijke kop van Wiz leunde precies daarop en beschreef het probleem als liggend in een door GitHub Copilot ondersteunde pull request, en de vroege vakpersberichtgeving volgde dezelfde lijn — de kop van SC Media luidde "Wiz agent finds Snowflake repo flaw in code co-authored by GitHub Copilot Autofix".

Het standpunt van GitHub, dat door The Next Web werd gemeld en in een onderzoeksnotitie van de Cloud Security Alliance werd samengevat, is dat zijn interne onderzoek uitwees dat "een mens de bijdragen heeft geschreven die tot de kwetsbaarheid hebben geleid" en dat Copilot Autofix "ze niet heeft beoordeeld en er niet aan heeft bijgedragen". De technische basis voor die weerlegging ligt in de git-geschiedenis. Bij squash-merging wordt een pull request samengevouwen tot één commit en wordt elke co-author-trailer doorgegeven, ongeacht welke regels die auteur heeft aangeraakt; een co-auteurregel registreert dus deelname aan de pull request, niet auteurschap van een bepaald hunk. De door Copilot mede-auteurschap toegekende commit in dezelfde pull request, 6d0e2fa, wijzigde jira_close.yml — een andere workflow dan de kwetsbare jira_issue.yml. De onveilige interpolatie wordt toegeschreven aan commit 094038e, gedateerd 25 augustus 2025 en door GitHub toegeschreven aan een Snowflake-engineer, sfc-ghpathak; PR #1218 bracht dat patroon in juni 2026 op de standaardbranch.

Wiz trok de bevinding niet in en wijzigde de framing op de dag van publicatie. Op de blog van Wiz staat een update die op 17 augustus om 19:57 UTC is gepost en waarin Copilot wordt beschreven als "een medeauteur die de samengevoegde PR en codewijziging controleerde", die "het als veilig bestempelde" zonder de kwetsbaarheden op te merken, en waarin wordt toegegeven dat "het onduidelijk is of de codewijziging door AI is ondersteund." In die weergave ligt de fout van de AI bij de review, niet bij de auteursrol: de samengevoegde pull request had een medeondertekening van Copilot en de injectie overleefde die. CSO Online citeert Wiz-CTO Ami Luttwak, die zegt dat duidelijke toerekening tussen mens en AI "iets moeilijker vast te stellen wordt", en dat "alleen naar de medeauteurs van de PR kijken niet genoeg is."

A self-built HTML card titled 'Two accounts of one commit', badged 'PR #1218 · SNOW-2069227 · squash-merged 18 June 2026 as commit 4a1b8ce'. A cyan-headed left panel, 'GitHub, internal review', reads: a human wrote the contributions that led to the vulnerability; Copilot Autofix neither reviewed nor contributed to them; Copilot's co-authored commit 6d0e2fa changed jira_close.yml, not the vulnerable file; the unsafe pattern traces to commit 094038e of 25 August 2025; squash-merging carries each co-author trailer forward regardless of which lines that author touched. An amber-headed right panel, 'Wiz, blog update, 17 August 2026, 19:57 UTC', reads: Copilot was a co-author that checked the merged PR and code change; it identified it as all-clear without noticing the vulnerabilities; it is unclear whether the code-change was AI-assisted; Copilot Autofix is listed among the squash commit's co-authors; the post was revised on the evening of publication without retracting the finding. Below, an open-question strip asks whether Copilot reviewed jira_issue.yml inside PR #1218, and a dashed band lists what is not in dispute.

Wat de twee lezingen gemeen hebben, is het waard te scheiden van wat ze betwisten. Beide zijn het erover eens dat de squashcommit de co-auteur-trailer van Copilot Autofix bevat en dat de workflow exploiteerbaar was. Geen van beide betwist dat GitHub Advanced Security de definitieve revisie van de pull request scande, jira_issue.yml eruit haalde en de injectie niet markeerde — Wiz meldt het als een gemiste detectie, en GitHub weerlegt het met een punt over auteurschap, niet over de scan. Wat onopgelost blijft, is of Copilot de kwetsbare regels überhaupt heeft beoordeeld: Wiz zegt dat er een beoordeling is uitgevoerd en dat die de regels heeft goedgekeurd, GitHub zegt dat het hulpmiddel daarbij geen rol speelde, en de logs die uitsluitsel zouden geven, bevinden zich bij een van de twee bedrijven. Het dossier bevat beide lezingen en kiest geen van beide.

Vijf dagen, en wat er daarna veranderde

De reparatie was snel zodra de melding binnenkwam. Wiz diende via Snowflake's HackerOne-programma melding #3819931 in op 23 juni en informeerde het beveiligingsteam van Snowflake diezelfde dag via Slack; Snowflake mergeerde PR #1402, commit 1dc7766, waarmee directe expressie-expansie werd vervangen door omgevingsvariabelen die als argumenten aan jq werden doorgegeven. Wiz' tijdlijn plaatst de rotatie van het Jira-token op 24 juni, en The Hacker News meldt dezelfde splitsing. Wiz' eigen inleiding zegt echter dat Snowflake de kwetsbaarheid heeft verholpen en de inloggegevens "dezelfde dag" heeft geroteerd — een discrepantie binnen de primaire bron die het verslag niet mag verdoezelen. De fix kwam er op 23 juni; de rotatie is in Wiz' tabel gedateerd op 24 juni.

De openbaarmaking volgde Snowflakes eigen tijdlijn: Wiz noemt een deadline voor openbare openbaarmaking van 25 juli 2026, dertig dagen na een resolutie van 25 juni onder de beleidsregels van het programma, en publiceerde de analyse op 17 augustus. In zijn verklaring aan CSO Online zei Snowflake dat het bedrijf "de verantwoorde rapportage van Wiz waardeert" en dat het met Wiz samenwerkte om de lessen met de branche te delen. Noch de analyse van Wiz, noch de rapportage van The Hacker News bevat een CVE-identifier, een CVSS-score of een vermelding in CISA's catalogus van bekende misbruikte kwetsbaarheden; het probleem betrof een workflowconfiguratie in een openbaar repository, geen meegeleverde bibliotheek, en kwam daardoor nooit op de gebruikelijke manier in een kwetsbaarhedendatabase terecht.

A self-built HTML card titled 'Five days live, five weeks to publication', subtitled 'Every date below is day-precision, as reported by Wiz Research and The Hacker News'. A vertical timeline lists six entries: 25 August 2025, commit 094038e introduces the unsafe jira_issue.yml refactor, attributed by GitHub to a Snowflake engineer; 18 June 2026, PR #1218 squash-merged as 4a1b8ce and the flaw goes live on the default branch; 23 June 2026, Wiz reports via HackerOne #3819931 and Snowflake merges fix PR #1402 as 1dc7766; 24 June 2026, Jira API token rotated, the fix having landed a day earlier; 25 July 2026, public disclosure deadline under Snowflake's HackerOne policy; 17 August 2026, Wiz publishes the full analysis, blog updated at 19:57 UTC. An amber band reads 'Exposure window: five days, 18 to 23 June 2026'. A footer notes no CVE identifier, CVSS score or known-exploited entry accompanies the record.

Wat het dossier vaststelt, en wat niet.

Het archief classificeert dit als een onderzoeksbevinding in plaats van een deploymentgebeurtenis, met hoge ernst, een betrouwbaarheidsgraad van A, bevestigde AI-betrokkenheid en geregistreerde reële schade; zijn datum, 17 augustus 2026, is de dag waarop Wiz publiceerde, en het incident zelf loopt van 18 tot 23 juni. De vastgestelde kern is smal en controleerbaar: een openbare workflow interpoleerde door aanvallers gecontroleerde tekst in een shell-opdracht, de guardvoorwaarde daarvan werd vergeleken met een eigenschap die bij dat event null is, een Jira-token stond in dezelfde stap, een autonome agent exploiteerde het, en Snowflake voegde binnen een dag een fix samen en roteerde de credential.

De delen die gevolgtrekkingen zijn en geen vastgelegde feiten, zijn precies de delen die losse navertellingen doorgaans afvlakken. Copilot Autofix staat gedocumenteerd als medeauteur van de pull request en niet als auteur van de kwetsbare regels; de AI-tegen-AI-framing die de eerste nieuwscyclus bepaalde, werd binnen enkele uren deels teruggetrokken door de organisatie die het nieuws bracht en door GitHub weerlegd. Of de AI-review van de samengevoegde pull request naar jira_issue.yml heeft gekeken, is nog steeds een openstaande feitelijke vraag, geen uitgemaakte zaak. En de omvang van de toegang is wel tot in detail door Wiz beschreven, maar niet onafhankelijk gecontroleerd: er zijn geen Jira-machtigingen, workflow-runs of auditrecords openbaar gemaakt.

Het fixpatroon is het patroon dat de eigen richtlijnen van GitHub sinds juli 2025 hadden aanbevolen — niet-vertrouwde issuegegevens in een omgevingsvariabele doorgeven en ze als argument aan jq meegeven, in plaats van ze binnen een run-blok uit te vouwen. De samengevoegde commit van Snowflake doet precies dat, en de gecorrigeerde verwerking blijft op de standaardbranch. Voor iedereen die het verslag als precedent leest, gaat de blijvende bevinding over toeschrijving en niet over injectie: wanneer een pull request meerdere mensen en meerdere agents bevat, kan de co-author-trailer je niet vertellen wie een regel heeft geschreven, en zowel Wiz als GitHub hebben dat uiteindelijk in andere bewoordingen gezegd.