Skip to content

ext/mysqlnd: Guard against short server scramble in sha256_password auth - #22356

Open
iliaal wants to merge 1 commit into
php:PHP-8.4from
iliaal:fix-mysqlnd-sha256-scramble
Open

iliaal wants to merge 1 commit into
php:PHP-8.4from
iliaal:fix-mysqlnd-sha256-scramble

Conversation

@iliaal

@iliaal iliaal commented Jun 17, 2026

Copy link
Copy Markdown
Member

mysqlnd_sha256_auth_get_auth_data() XORs SCRAMBLE_LENGTH (20) bytes of the server-supplied scramble into the password without checking the scramble is at least that long, unlike the native and caching_sha2 plugins which reject a short scramble with CR_MALFORMED_PACKET. A server reporting a scramble shorter than 20 bytes shrinks the heap buffer the scramble is copied into, so the XOR reads past it. Add the same length guard the sibling plugins use.

@morrisonlevi morrisonlevi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks okay but... how would we test it to be sure?

@iliaal
iliaal force-pushed the fix-mysqlnd-sha256-scramble branch from 4d5c8c9 to c910401 Compare June 18, 2026 17:02
@iliaal

iliaal commented Jun 18, 2026

Copy link
Copy Markdown
Member Author

Added a regression test (a fake_server.inc scenario + .phpt): the fake server sends an AuthSwitchRequest to sha256_password with an 8-byte scramble, and the client now fails with CR_MALFORMED_PACKET instead of running the 20-byte XOR over the short heap copy. The over-read itself reproduces under ASAN (mysqlnd_xor_string reading past the mnd_emalloc'd scramble buffer).

@iliaal
iliaal requested a review from morrisonlevi June 18, 2026 17:03
Comment thread ext/mysqli/tests/mysqli_sha256_password_short_scramble.phpt Outdated
@kamil-tekiela

Copy link
Copy Markdown
Member

#21711

@iliaal iliaal changed the title Guard against short server scramble in sha256_password auth ext/mysqlnd: Guard against short server scramble in sha256_password auth Oct 13, 2026
@iliaal
iliaal force-pushed the fix-mysqlnd-sha256-scramble branch 2 times, most recently from 2310856 to d844a6d Compare October 13, 2026 13:33
Comment thread ext/mysqli/tests/mysqli_sha256_password_short_scramble.phpt Outdated
@kamil-tekiela

Copy link
Copy Markdown
Member

@bukka I leave it up to you to decide on this. It's basically identical to my PR. I don't actually know if it fixes anything or just swaps one error message for another.

mysqlnd_sha256_auth_get_auth_data() XORs SCRAMBLE_LENGTH bytes of the
server-supplied scramble into the password without checking the scramble
is at least that long, unlike the native and caching_sha2 plugins which
reject a short scramble with CR_MALFORMED_PACKET. A server reporting a
scramble shorter than 20 bytes shrinks the heap buffer the scramble is
copied into, so the XOR reads past it. Add the same length guard the
sibling plugins use.
@iliaal

iliaal commented Oct 13, 2026

Copy link
Copy Markdown
Member Author

It does fix a heap over-read; the old test just never reached it, since without a public key the XOR doesn't run. With a key and a longer password, valgrind on the unpatched build reports an invalid read in mysqlnd_xor_string() past the 8-byte scramble. #21711 came first and covers the same read, so I'm fine closing this one if the test moves there.

@iliaal
iliaal force-pushed the fix-mysqlnd-sha256-scramble branch from d844a6d to 1ebfb1f Compare October 13, 2026 14:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants