Skip to content

SQLi: store a variable value without the leading '@', matching C - #3

Merged
ndreno merged 1 commit into
mainfrom
fix/variable-value-without-at
Sep 11, 2026
Merged

ndreno merged 1 commit into
mainfrom
fix/variable-value-without-at

Conversation

@ndreno

@ndreno ndreno commented Sep 11, 2026

Copy link
Copy Markdown

The 2-hour differential fuzz campaign (added in the previous PR) found
this about 2.8M executions in, well beyond the per-pull-request smoke
test's reach. It is a false negative and the first divergence outside the
strchr-NUL family.

The divergence

@pasSword(pasSword(2 is f(f(1 in C (a blacklisted pattern, so SQLi)
but was v(f(1 in the port (benign). The function fold converts a
bareword or variable named PASSWORD/USER/... followed by ( into a
function. C's parse_var stores the variable value from after the @
(the name alone; the @ count is a separate field), so the fold compares
pasSword and fires. The port stored the @ in the value, so it compared
@pasSword, which never matched, and the variable kept its type.

Fix

Assign the variable value from after the @ symbols, matching C. The
printed source form is reconstructed from the @ count where it is needed
(the token-file and folding test formatters), exactly as C's print_var
does. A dedicated differential test pins @pasSword(.

Gate

Full-corpus differential (162,963 inputs) stays at 0 on verdicts and
fingerprints. The nightly campaign continues from here.

C's parse_var assigns the token value from after the '@' symbols, so the
value is the name alone and the '@' count is kept separately. The port
stored the '@' in the value, so the function fold that matches a variable
named like PASSWORD/USER/... compared against "@password" and never fired,
typing `@pasSword(` as a variable where C types it as a function. The
fingerprints then diverged (`v(f(1` vs the blacklisted `f(f(1`).

Assign the value from after the '@' and reconstruct the '@' prefix from
`count` where the source form is printed (the token-file and folding test
formatters), as C's print_var does. Found by the 2-hour fuzz campaign,
about 2.8M executions in. A dedicated differential test pins it; full
corpus stays at 0.
@ndreno
ndreno merged commit 7f35f80 into main Sep 11, 2026
4 checks passed
@ndreno
ndreno deleted the fix/variable-value-without-at branch September 11, 2026 13:12
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.

1 participant