From 39ddf6b89cc5013f6e1ded90a238cd8b610e6597 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Fri, 23 Apr 2021 15:28:11 +0200 Subject: [PATCH] Fix #67792: HTTP Authorization schemes are treated as case-sensitive We use `zend_binary_strncasecmp()` to avoid any locale issues, and refactor. We also add a test case for Digest authentication. Closes GH-6900. --- NEWS | 2 ++ main/main.c | 7 ++--- sapi/cli/tests/php_cli_server_021.phpt | 37 ++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 sapi/cli/tests/php_cli_server_021.phpt diff --git a/NEWS b/NEWS index e3fac310312..cb7179bd40c 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,8 @@ PHP NEWS call_user_func_array). (twosee) . Fixed bug #80960 (opendir() warning wrong info when failed on Windows). (cmb) + . Fixed bug #67792 (HTTP Authorization schemes are treated as case-sensitive). + (cmb) - pgsql: . Fixed php_pgsql_fd_cast() wrt. php_stream_can_cast(). (cmb) diff --git a/main/main.c b/main/main.c index 3450b4197f3..b17bbd7fe7b 100644 --- a/main/main.c +++ b/main/main.c @@ -2712,12 +2712,13 @@ PHPAPI void php_handle_aborted_connection(void) PHPAPI int php_handle_auth_data(const char *auth) { int ret = -1; + size_t auth_len = auth != NULL ? strlen(auth) : 0; - if (auth && auth[0] != '\0' && strncmp(auth, "Basic ", 6) == 0) { + if (auth && auth_len > 0 && zend_binary_strncasecmp(auth, auth_len, "Basic ", sizeof("Basic ")-1, sizeof("Basic ")-1) == 0) { char *pass; zend_string *user; - user = php_base64_decode((const unsigned char*)auth + 6, strlen(auth) - 6); + user = php_base64_decode((const unsigned char*)auth + 6, auth_len - 6); if (user) { pass = strchr(ZSTR_VAL(user), ':'); if (pass) { @@ -2736,7 +2737,7 @@ PHPAPI int php_handle_auth_data(const char *auth) SG(request_info).auth_digest = NULL; } - if (ret == -1 && auth && auth[0] != '\0' && strncmp(auth, "Digest ", 7) == 0) { + if (ret == -1 && auth && auth_len > 0 && zend_binary_strncasecmp(auth, auth_len, "Digest ", sizeof("Digest ")-1, sizeof("Digest ")-1) == 0) { SG(request_info).auth_digest = estrdup(auth + 7); ret = 0; } diff --git a/sapi/cli/tests/php_cli_server_021.phpt b/sapi/cli/tests/php_cli_server_021.phpt new file mode 100644 index 00000000000..6269871b4c8 --- /dev/null +++ b/sapi/cli/tests/php_cli_server_021.phpt @@ -0,0 +1,37 @@ +--TEST-- +Digest Authentication +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +HTTP/1.1 200 OK +Host: %s +Date: %s +Connection: close +X-Powered-By: PHP/%s +Content-type: text/html; charset=UTF-8 + +bool(true) +bool(true) +string(242) "username="Mufasa", realm="testrealm@host.com", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", uri="/dir/index.html", qop=auth, nc=00000001, cnonce="0a4f113b", response="6629fae49393a05397450978507c4ef1", opaque="5ccc069c403ebaf9f0171e9517f40e41""