fix: apply SASLprep (RFC 4013) to passwords before SCRAM-SHA-256 PBKDF2#33
Open
avallete wants to merge 1 commit into
Open
fix: apply SASLprep (RFC 4013) to passwords before SCRAM-SHA-256 PBKDF2#33avallete wants to merge 1 commit into
avallete wants to merge 1 commit into
Conversation
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.
Summary
pg's SCRAM-SHA-256 client passes the raw password into PBKDF2 with no normalization, while PostgreSQL's server (andlibpq) apply SASLprep (B.1mapping →C.1.2mapping → NFKC → prohibition + bidi check) when computing the stored verifier. Passwords whose NFKC form differs from themselves authenticate againstpsql/libpqbut fail againstpgwith28P01.This bug bites real users: a password like
abcd123456789123456789¨‑¼###authenticates fine inpsqlbut fails in any consumer usingpg.Fix
Inline a minimal SASLprep helper in
packages/pg/lib/crypto/sasl.jsand call it incontinueSessionimmediately beforecrypto.deriveKey. The helper performs only the three RFC 4013 steps that change the byte content fed to PBKDF2:Prohibition (RFC 4013 §2.3) and bidi (RFC 3454 §6) checks are intentionally omitted:
libpq'spg_saslprepand Postgres's ownsaslprep.care forgiving on those paths for legacy roles, so omitting them keeps existing accounts working without adding complexity. Because the three remaining steps cannot throw on a string input, no try/catch fallback is needed.Why in-tree, no dependency
Updated in response to review feedback from @brianc and @charmander on this PR:
Why no behavior change for existing users
What changed
Commits
Happy to squash to one commit on merge if you prefer; I kept them separate so the diff in response to your feedback is easy to read.
Test plan