On 25 August 2026, David Buchanan published an AI-generated image carrying a valid C2PA Content Credential that says a Google Pixel camera captured it, along with a YouTube clip signed the same way. The official C2PA verification tool accepts both. The signing key was never extracted from the phone, and that detail is the reason this is hard to fix.
TL;DR: A Content Credential proves which key signed some bytes. It does not prove a sensor saw anything. On a Pixel rooted by a software exploit, StrongBox will sign attacker-supplied content with the real camera key, and the attestation certificate still reports a locked bootloader. Because Pixel issues one certificate per image, there is nothing to revoke. Score verified credentials as weak corroboration with a device-class caveat, and score a missing credential as nothing at all.
What does a valid Content Credential actually prove?
The C2PA binding runs from the manifest to the asset bytes, and from the signature to a certificate that chains to a trust list. At no point does anything in that chain observe the image sensor. The guarantee on offer is "a key on the trust list signed these bytes," and everything else people read into a green check is inference about how well that key is guarded.
On Pixel, the guard is real hardware. Google's September 2025 announcement states that Pixel Camera's "C2PA claim signing keys are generated and stored using Android StrongBox in the Titan M2 security chip," and that Pixel Camera reached Assurance Level 2, "the highest security rating currently defined by the C2PA Conformance Program," which Google notes is "currently only possible on the Android platform."
Buchanan's result leaves that hardware claim intact. Root on the device can call the KeyStore API while impersonating the camera app, hand StrongBox arbitrary bytes, and get a signature over them. His tool, Keystork, does exactly that. He states every C2PA camera app relying on Android_KeyAttestation or Google_PlayIntegrity is affected, which covers the Android field as it exists today.
The attestation certificate that ships alongside is the part that fools operators. It reports genuine hardware, a locked bootloader, unmodified AVB keys, and Play Protect Certified boot. Every one of those statements is still true on a phone rooted through a kernel bug. Attestation measures the boot chain. Root acquired after boot is invisible to it. Anyone who has argued about what a JWS on an agent card really certifies has met this gap before: the signature is honest about origin and silent about everything the operator cares about.
How expensive is the root that makes this work?
Cheap enough to stop treating as a nation-state problem. Buchanan attributes in-the-wild one-click root on fully patched Pixels to CVE-2026-43499, a Linux kernel rtmutex use-after-free (CWE-416) published to NVD on 21 May 2026 with a CVSS base score of 7.8, fixed in 6.1.175, 6.6.140, 6.12.86, 6.18.27 and 7.0.4. He reports testing on Pixel 8a and 9a at August patch levels. He also describes a hardware fault-injection path, flipping DRAM bits into page table entries, which no kernel patch closes.
Google's response was to close the report "Won't fix (infeasible)" and pay a $7,500 out-of-scope bounty. Read that as a statement about the threat model rather than a shrug: Android key attestation was designed to prove device integrity at boot for DRM and payments, and it does that job. C2PA asked it to prove something it was never built to prove, and Google is declining to redefine it.
Four different states, one identical verifier output
Most of the confusion in the last week comes from teams collapsing distinct situations into a single boolean.
| What the verifier shows | What actually happened | The check that separates it |
|---|---|---|
| Valid, trusted signer | Genuine capture | Nothing available today distinguishes this from row 2 |
| Valid, trusted signer | Forgery on a software-rooted device | Device class and attestation method in the manifest; treat Android AL2 as weak evidence |
| Valid, trusted signer | Certificate known-compromised and revoked | A manual revocation check; conforming validators skip it |
| No credential | Screenshot, CDN resize, re-encode, or a deliberate strip | Absence carries no signal in either direction |
Row four matters more than it looks. Stripping happens by accident on almost every resize and screenshot, and purpose-built C2PA strippers have been easy to find on GitHub this month. An intake policy that raises a risk score for missing provenance will spend its life flagging holiday photos that went through an image CDN.
Why revocation cannot save the Pixel design
Google describes a "One-and-Done" strategy where each key and certificate is used to sign exactly one image. That is excellent hygiene against key reuse and it removes the object you would revoke. There is no device certificate. Each forgery arrives with a fresh certificate, freshly attested. The remaining lever is refusing to provision new certificates to a compromised device, which requires detecting software root, which is precisely the thing attestation cannot see.
Nikon had the opposite design and used it. After Adam Horshack demonstrated the Z6 III's multiple-exposure mode signing an image the camera never captured, Nikon suspended its Authenticity Service and, per DPReview and Nikon Rumors, revoked every certificate issued since the 21 September 2025 launch. That invalidated legitimate photographs along with the forgeries. Those are the two shapes available in 2026: revoke nothing, or revoke everyone.
The academic picture is worse. The first formal-methods analysis of C2PA, by Golaszewski, Krawetz, Sherman and colleagues (IACR ePrint 2026/804, revised 2 June 2026), reports that "inadequate certificate revocation policies cause conforming validators to accept manifests signed with known-compromised certificates, violating all security goals." The same paper finds that generators and validators disagree on the trusted timestamp, that conforming validators return inconsistent results on the same asset, that the exclusion range permits undetectable alterations, and that "the conformance program certifies products without technical review or defined requirements." The authors note some fixes landed in Pixel 10 Pro and C2PA v2.3, so the specification is moving. The deployed fleet is not.
The timestamp is right for builds and wrong for cameras
The C2PA 2.2 specification (2025-05-01) directs generators to obtain an RFC 3161 countersignature so a manifest keeps verifying after its certificate expires or is revoked. For build provenance that is the correct default, and it is why a two-year-old release artifact still validates. Anyone who has fought through a Cosign v3 rollout and the trust-chain breakage that came with it knows how much that durability is worth.
Capture provenance wants the opposite behaviour. When a camera is known compromised, its output should stop verifying immediately, including images signed last year. C2PA inherited the build-provenance default and applied it to real-world claims, and the countersignature now works to keep forgeries alive. Decide which of those two claims your own signatures are making before you copy the pattern into anything else you sign.
Your verification gate is probably trusting nothing
c2patool -d asset.jpg prints the detailed manifest and certificate chain. Trust anchors are supplied through C2PATOOL_TRUST_ANCHORS, C2PATOOL_ALLOWED_LIST and C2PATOOL_TRUST_CONFIG, per the c2pa-rs CLI usage docs, and contentcredentials.org publishes anchors.pem and allowed.sha256.txt.
The failure mode to hunt for is the one that reports success while doing nothing. In a settings file, trust.trust_anchors takes PEM text rather than a path. Hand it a filename and the tool configures no anchors at all, then happily reports valid on assets that chain to nowhere. There is also a dead-list trap: the C2PA Interim Trust List was frozen as of 1 January 2026, leaving the Conformance Programme as the only issuance path, so a gate still pinning the ITL is validating against a list that stopped growing eight months ago.
What to change in your intake pipeline this week
- Rewrite any rule that reads
verified == true → accept. For the Android fleet, that rule is now wrong. Downgrade a passing Content Credential to weak corroborating evidence carrying a device-class caveat, and require a second, independent signal before an image drives a payout, a publication, or a KYC decision. - Delete any risk score attached to a missing manifest. Absence proves a resize happened, nothing more.
- Prove your gate pins an anchor. Put a known-untrusted signed asset in CI and require the pipeline to fail on it. If it passes, your
trust.trust_anchorsis holding a path instead of PEM text, and you have been rubber-stamping everything. - Re-pull
anchors.pemandallowed.sha256.txtfrom contentcredentials.org and confirm nothing in your config still references the Interim Trust List frozen on 1 January 2026. - Record the signer identity and attestation method (
Android_KeyAttestation,Google_PlayIntegrity, or a hardware vendor's own) from every manifest at intake, alongside the asset hash. When the next device class breaks, that field is how you find the affected corpus. The same discipline that makes a stored SBOM plus VEX useful the day a CVE lands applies here, and neither can be reconstructed after the fact. - Flag Pixel 8a and 9a class devices at August 2026 patch levels specifically, since those are the models Buchanan reports testing, and keep the flag until you can point at a device generation where the ePrint 2026/804 fixes shipped.
What I read for this: Buchanan's write-up for the mechanism, ePrint 2026/804 for the formal analysis of revocation and validator disagreement, Google's Pixel C2PA announcement for the StrongBox and Assurance Level 2 claims, NVD's entry for CVE-2026-43499 for the kernel bug and fixed versions, and the C2PA 2.2 specification for the RFC 3161 countersignature requirement.
Comments
Be the first to comment.