Skip to content

caching_sha2_password fast-auth path is broken — every connection pays RSA cost it was designed to avoid #4244

@altmannmarcelo

Description

@altmannmarcelo

I have found these related issues/pull requests

N/A

Description

The caching_sha2_password plugin exists for one reason: after an initial full authentication (which requires TLS or a 2048-bit RSA decryption on the server), subsequent connections from the same user hit a server-side cache and skip the expensive key exchange entirely.
That's the "caching" in the name. The fast-auth scramble — XOR(SHA256(pw), SHA256(SHA256(SHA256(pw)) ‖ nonce)) — is designed so the server can cheaply validate it against its cached SHA256(SHA256(pw)) and respond with fast_auth_success (0x03) in a single round trip.

sqlx-mysql implements the scramble with the nonce and hash concatenated in the wrong order, so no spec-compliant server can ever validate it. Every sqlx connection to a MySQL server using caching_sha2_password takes the full-auth path — forever. The cache never helps.
The entire optimization the plugin was built to provide is silently defeated for sqlx users.

Two consecutive sqlx connections to stock MySQL 8.4 with the same user. The server responds with perform_full_authentication (0x04) both times — the second connection should have hit the cache and received fast_auth_success (0x03):

Image

Root cause

auth.rs

  ctx.update(nonce.first_ref());
  ctx.update(nonce.last_ref());
  ctx.update(pw_hash_hash);

This computes SHA256(nonce ‖ SHA256(SHA256(pw))). MySQL's computes SHA256(SHA256(SHA256(pw)) ‖ nonce). Since SHA-256 is not concat-commutative, the two hashes never match, and the server's XOR can never recover SHA256(pw).

Reproduction steps

  1. collect TCP dump / Wireshark
  2. Execute:
export DATABASE_URL='mysql://root:[email protected]:3306/test?ssl-mode=DISABLED'; sqlx database create

SQLx version

sqlx-cli 0.8.6

Enabled SQLx features

N/a

Database server and version

MySQL 8.4

Operating system

MacOS

Rust version

N/a

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions