Skip to content

[Fix #30 #31 #32 #33] Close the dotted-value bypass and the remaining recall gaps - #45

Merged
svn-arv merged 2 commits into
mainfrom
svn-arv/bug/gemini-key-recall-and-code-reference-bypass
Aug 5, 2026
Merged

svn-arv merged 2 commits into
mainfrom
svn-arv/bug/gemini-key-recall-and-code-reference-bypass

Conversation

@svn-arv

@svn-arv svn-arv commented Aug 5, 2026

Copy link
Copy Markdown
Owner

What

Two things, in two commits.

Detection (adeecc9). A credential containing a dot escaped both identifier exemptions in skipMatch, plus the four remaining recall gaps from the accuracy advisory.

Landing page (864f027). Mobile overflow, teal accent, light/dark toggle. Tracked as svn-arv/notes#11.

The bypass

looksLikeCodeReference treats any mixed-case run of letters, digits and underscores containing a . or :: as a constant path, with no length or entropy bound. It is consulted before the keyword and scored tiers, so the key name never mattered:

Probe No dot One dot
SECRET= 32ch redacted leaked
AWS_SECRET_ACCESS_KEY= 40ch redacted leaked
ENCRYPTION_KEY= 64ch redacted leaked

The lenient :/=> arm from #26 had the same hole. Both now require that no ./:: segment scores as random.

Segments are scored without secretLike's 16-char length floor, which is the wrong instrument at segment granularity: with it, a credential split into two sub-16-char halves stays exempt. Gating on the whole value is not available, since the scorer rates MyApp::Config::TOKEN_V2 as secret-like and it has to stay clean.

The change is purely restrictive on the exemption, so it can only redact more, never less. No existing redact guardrail could regress by construction; the risk was entirely on clean rows.

Recall

Closes #30, #31, #32, #33. All engine.yml data except the hex gate, so the opencode plugin inherits them once #25 lands.

Decisions worth review

  • Not bare PWD, as the advisory proposed. The keyword prefix in envSecretRegex is optional, so PWD would redact the working directory in every shell env dump. Added MYSQL_PWD and pinned it with PWD=/OLDPWD= corpus rows.
  • Vendor token lengths are floors, not verified formats. No real samples for xai-, pplx-, tvly-, lsv2_; the prefix does the discriminating. The advisory flagged this drift risk and it stands.
  • The guard fix is Go-only, so the opencode plugin does not get it — its PatternFile parses neither heuristic nor allow_values. Widens the parity gap in chore: opencode TS/Go parity + cross-language conformance corpus #34.
  • landing/dist/index.html left alone. It is a stale copy still reachable under assets.directory: "landing", predating even the orange accent. Deleting it is a separate call.

Testing

Corpus rows written first and confirmed failing for the right reason in every case.

  • Recall 43/43 → 64/64, precision 11/11 clean corpus files, hook payload 9 → 10.
  • Full suite green across all 5 packages, zero flakes over 10 consecutive -count=1 runs (the corpus uses random values).
  • gofmt and go vet clean.
  • Fresh binary probed end to end: the reported key redacts in all ten contexts in both hyphenated and hyphen-free shapes; ENV.fetch, Rails.application.secrets.secret_key_base, MyApp::Config::TOKEN_V2, Base64.encode64 and the fk_rails annotation all still pass clean.

Landing page overflow was verified by computing min-content widths per viewport, not in a browser. Worth a visual check at 320/375/414 before merge.


This PR description was AI-generated.

svn-arv added 2 commits August 5, 2026 18:16
A credential containing a dot escaped both identifier exemptions in
skipMatch. looksLikeCodeReference treats any mixed-case run of letters,
digits and underscores holding a `.` or `::` as a constant path, with no
length or entropy bound, so a 50-char token qualified. The guard is
consulted before the keyword and scored tiers, so the key name did not
matter: SECRET, PASSWORD and AWS_SECRET_ACCESS_KEY all leaked once a dot
was present. The lenient `:`/`=>` arm added in #26 had the same hole.

Both arms now require that no `.`/`::` segment scores as random.
Segments are scored without secretLike's 16-char length floor, which is
the wrong instrument at segment granularity: with it, a credential split
into two sub-16-char halves stays exempt. Gating on the whole value
instead is not an option, since the scorer rates MyApp::Config::TOKEN_V2
as secret-like and it must stay clean.

Recall gaps closed, all as engine.yml data so the opencode plugin picks
them up once #25 lands:

- #33 truncated PEM with no END marker, the shape tool output takes at a
  capture limit. 16-char floor per line so it stops at trailing prose.
- #31 opaque Authorization headers. Token charset rather than \S, which
  would swallow the [REDACTED:jwt marker and double-redact.
- #30 ASIA, ghu_, xoxe-, whsec_, and the AI-stack prefixes. Lengths are
  floors, not verified formats.
- #32 PASSWD/MYSQL_PWD/CONNECTION_STRING keywords, and hex under a
  *_KEY name, which the scorer rejects as 2-class by design.
- new Google AQ. key format, which AIza does not cover.

Not bare PWD as the advisory proposed: the keyword prefix in
envSecretRegex is optional, so PWD would redact the working directory in
every shell env dump. Pinned with PWD= and OLDPWD= corpus rows.

Recall 43/43 to 64/64, precision 11/11, no flakes over 10 runs.
…me toggle

Mobile overflow was not the install row: .cmdline and .cmdline code
already carry min-width:0. Grid items default to min-width:auto, so the
existing overflow-x:auto on .term-body, .pane and .method pre never
engaged and the tracks widened instead. Measured at a 375px viewport
with a 335px page: 634px, 389px and 622px. Tracks are now minmax(0,...).
.claim code loses white-space:nowrap, which pushed a 306px command past
a 320px viewport; it already fit on one line at desktop widths, so
desktop rendering is unchanged. No body{overflow-x:hidden}.

Accent moves to teal, 6.36:1 on --paper in light and 8.29:1 in dark.
Note the light value is AA, not AAA as issue notes#11 claims in prose;
its own table says 6.36.

Theme toggle: the dark palette is declared twice, once behind
prefers-color-scheme for visitors who have not chosen and once behind
[data-theme="dark"], so an explicit choice wins in both directions. CSS
cannot share a property block across a media boundary, so the lists are
duplicated and have to be kept in sync. color-scheme is set per theme so
scrollbars follow. The stored theme is applied by a blocking script in
head, before the stylesheet, otherwise the page paints the OS theme and
flips. Control is a nav button without .opt, since it has to survive the
mobile cull; the label names the mode it switches to and tracks the OS
while no explicit choice is stored.

Also drops --bar-ink, declared in both palettes and referenced nowhere.
@cloudflare-workers-and-pages

Copy link
Copy Markdown
Contributor

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
redacted 864f027 Commit Preview URL

Branch Preview URL
Aug 05 2026, 11:17 AM

@svn-arv
svn-arv merged commit 0b4dd23 into main Aug 5, 2026
7 checks passed
@svn-arv
svn-arv deleted the svn-arv/bug/gemini-key-recall-and-code-reference-bypass branch August 5, 2026 11:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

recall: AI-stack + vendor token patterns (hf_, gsk_, ASIA, ghu_)

1 participant