fix(extension): mint reCAPTCHA via hidden widget — unblocks generate after the 2026-09-22 build - #62
Merged
crisng95 merged 1 commit intoSep 24, 2026
Conversation
… bundles
The 2026-09-22 frontend build (boq_labs-ai-sandbox-frontend_20260922.00_p0)
started rejecting tokens obtained by calling
grecaptcha.enterprise.execute(SITE_KEY, {action}) directly — every generate
RPC answers PUBLIC_ERROR_UNUSUAL_ACTIVITY, while clicking Generate in the
Flow UI still works. Sitekey, action, payload and headers were verified
byte-for-byte identical to the UI, so the constraint moved into the mint
mechanism itself.
Fix ported from FlowBridge2's mint, which passes on the same build (A/B
tested with the same account/project, 2026-09-24):
- resolveSitekey(): read the real sitekey off ___grecaptcha_cfg (fallback
to the hardcoded one)
- grecaptcha.enterprise.ready() -> render an invisible widget in a hidden
div -> execute(widgetId, {action}) with retry, mint serialized
- content.js now preloads recaptcha_enterprise.js + recaptcha__en.js
(bundled from the reCAPTCHA CDN) into the MAIN world: flow.google.com no
longer ships grecaptcha at page load and its Trusted-Types CSP blocks
<script src=google.com/...>, so the only exible route is the extension's
own chrome-extension:// URL
- cache-buster ?v=<manifest.version> on all injected scripts (Chrome has
been observed to reuse a stale injected.js after reload otherwise)
- bump extension to 0.3.4, add both bundles to web_accessible_resources
Verified end to end: direct generate (ogiZ0b) COMPLETED + image bytes
served from flow-content.google; the full pipeline (POST /api/requests ->
worker queue -> generate -> media_id/url persisted) COMPLETED. Rejection
before the fix was 100% reproducible on three independent requests.
Refs crisng95#58
|
@Matro81 it did work for a few hours, then, it does not work anymore. At this time of commenting, it does not work for me. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Since frontend build
boq_labs-ai-sandbox-frontend_20260922.00_p0(deployed ~2026-09-22 16:45–17:52 UTC), every generate RPC this extension submits fails withPUBLIC_ERROR_UNUSUAL_ACTIVITY(grpc 7) — while clicking Generate in the Flow UI on the same tab still works. This is the break reported in #58.The conclusion in #58 ("self-minted tokens are now rejected regardless") is not quite right: the constraint moved into how the token is minted, not into self-minting as such. A token obtained by calling
grecaptcha.enterprise.execute(SITE_KEY, {action})directly — the wayinjected.jsdid it — is now rejected. A token minted the way the page's own code does it (render a widget, execute the widget id) still passes.Evidence (A/B, same account, same build, same project, 2026-09-24)
main(0.3.2)execute(SITE_KEY, {action})UNUSUAL_ACTIVITY, 3/3 requests (each byte-compared against UI: sitekey/action/payload/headers identical)ready()→render(hiddenDiv, {sitekey, size:'invisible'})→execute(widgetId, {action})media_id e2f6fd77-02ff-4e7b-889e-403e370537b24209e716-4155-45d8-8d89-c2392d333b6c; full pipeline (POST /api/requests→ worker → scene row)3bd7ff3b-ab16-461a-8194-e6fe267210d7, JPEG bytes verified fromflow-content.googleWhat changed
extension/injected.jsmintCaptcha()rewritten:resolveSitekey()reads the real sitekey off___grecaptcha_cfg(hardcoded key kept as fallback) →enterprise.ready()→ render an invisible widget into a hidden div →execute(widgetId, {action}), with retry. Mints stay serialized as before.extension/content.js+ 2 new bundled filesgrecaptchaat page load, and its Trusted-Types CSP blocks<script src="https://www.google.com/…">from the page. The only exempt route is the extension's ownchrome-extension://URL, so content.js preloadsrecaptcha_enterprise.js+recaptcha__en.js(same bundles as the reference bridge, byte-identical) into the MAIN world.grecaptcha not available(hit exactly that while landing this fix).?v=<manifest.version>— Chrome was observed reusing a staleinjected.jsafter a plain reload otherwise.extension/manifest.jsonweb_accessible_resources.Notes
maseQ) kept working through the break becauseMEDIA_UPLOADwas apparently not gated the same way — a useful, misleading data point for anyone triaging Every captcha-gated RPC returns PUBLIC_ERROR_UNUSUAL_ACTIVITY since the Flow frontend build of 2026-09-22, while the UI itself still works #58: a passing upload probe does not clear the mint path.PUBLIC_ERROR_UNSAFE_GENERATION,[3], 0 credits) — worth distinguishing in the retry policy from Harden Flow generation and restore project lifecycle #59's cooldown logic so moderation rejections don't look like a captcha regression.Refs #58