Repository navigation
fix(auth): handle binary SASL initial response correctly - #282
Open
KrisnaDana wants to merge 2 commits into
Open
KrisnaDana wants to merge 2 commits into
KrisnaDana wants to merge 2 commits into
Conversation
This branch has not been deployed
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
Fix intermittent SCRAM-SHA-256 authentication failures when connecting to PgDoorman using the Rust SQLx PostgreSQL driver.
The issue is caused by converting the entire binary SASL initial response into a UTF-8 string before extracting the SCRAM payload. This can corrupt byte offsets and cause authentication failures depending on the length of the SCRAM client-first-message.
This PR introduces binary-safe SASL parsing while preserving the existing
Cow<str>signature ofparse_client_first_message().Problem
During testing, SQLx produced inconsistent authentication results when establishing repeated connections through PgDoorman using the same connection configuration.
SQLx — 200 sequential connections:
The failures occurred during connection authentication, before executing
SELECT 1.The following PostgreSQL error was returned:
Some connections succeeded while others failed despite using identical credentials and connection settings.
This behavior suggests an intermittent issue in PgDoorman's SCRAM authentication handling, triggered by specific SASL message lengths generated by SQLx.
Root Cause
The previous implementation processed the binary SASL initial response using:
However, the SASL initial response contains:
When the encoded response length contains bytes that are not valid standalone UTF-8 sequences,
String::from_utf8_lossy()replaces them with Unicode replacement characters.This changes the byte representation and can invalidate the fixed byte offsets used to extract the SCRAM payload.
SQLx generates variable-length SCRAM nonces, making the issue appear intermittently depending on the resulting message length.
Changes
This PR:
parse_sasl_initial_response()to parse the SASL initial response directly from raw bytes.Cow<str>parameter inparse_client_first_message().auth_querypath.Testing
1. SQLx Connection Test (Before Patch)
The original SQLx test performed 200 sequential connections against PgDoorman.
Authentication failures occurred intermittently with SQLSTATE
28P01.The failure rate was approximately 31.5%, even though all connections used the same credentials and configuration.
These results were obtained before the patch and are not an end-to-end verification of the patched PgDoorman v3.11.0 build.
2. Binary-Safe Parsing Regression Test
A deterministic 200-iteration reproduction was used to compare the legacy parsing approach with binary-safe parsing.
Legacy parser:
Binary-safe parser:
The legacy parsing approach failed when the SCRAM client-first-message length reached 128 bytes or more.
The binary-safe parser successfully handled all 200 simulated inputs and rejected malformed response lengths.
These results demonstrate that binary-safe parsing resolves the reproduced byte-offset issue.
Note: This deterministic reproduction validates the parsing logic at the unit-test level. It is not an end-to-end authentication test against the patched PgDoorman server.
3. Existing SCRAM Unit Tests
The existing
good_parse_client_first_messageunit test was updated to reflect the new input contract.Previously, the parser received a string representation of the complete binary SASL initial response.
After the change, the parser receives only the extracted SCRAM text payload, while the binary header is handled separately by
parse_sasl_initial_response().This separates binary protocol parsing from SCRAM message parsing and maintains the existing
Cow<str>function signature.4. Full Library Unit Test Suite
The complete PgDoorman library unit test suite was executed after applying the patch and updating the existing SCRAM tests.
Command:
cargo test --libResult:
Status: PASSED
This confirms that the patched implementation passes the complete library unit test suite, including the updated SCRAM authentication tests.
Expected Behavior
PgDoorman should correctly process valid SCRAM-SHA-256 SASL initial responses regardless of their length.
SQLx connections should no longer experience intermittent authentication failures caused by binary-to-UTF-8 conversion.
The parser should also reject malformed SASL responses, including:
Environment
Additional Notes
This patch focuses specifically on the parsing of SASL initial responses.
It does not change the SCRAM cryptographic algorithm, password verification, or connection pooling behavior.
The goal is to improve PostgreSQL protocol correctness and compatibility with SQLx clients that generate variable-length SCRAM messages.
All 1,211 library unit tests pass after the changes. End-to-end SQLx connection testing against a patched PgDoorman container remains a separate verification step.