Skip to content

Commit 39ddf6b

Browse files
committed
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.
1 parent 054fad6 commit 39ddf6b

File tree

3 files changed

+43
-3
lines changed

3 files changed

+43
-3
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ PHP NEWS
77
call_user_func_array). (twosee)
88
. Fixed bug #80960 (opendir() warning wrong info when failed on Windows).
99
(cmb)
10+
. Fixed bug #67792 (HTTP Authorization schemes are treated as case-sensitive).
11+
(cmb)
1012

1113
- pgsql:
1214
. Fixed php_pgsql_fd_cast() wrt. php_stream_can_cast(). (cmb)

main/main.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2712,12 +2712,13 @@ PHPAPI void php_handle_aborted_connection(void)
27122712
PHPAPI int php_handle_auth_data(const char *auth)
27132713
{
27142714
int ret = -1;
2715+
size_t auth_len = auth != NULL ? strlen(auth) : 0;
27152716

2716-
if (auth && auth[0] != '\0' && strncmp(auth, "Basic ", 6) == 0) {
2717+
if (auth && auth_len > 0 && zend_binary_strncasecmp(auth, auth_len, "Basic ", sizeof("Basic ")-1, sizeof("Basic ")-1) == 0) {
27172718
char *pass;
27182719
zend_string *user;
27192720

2720-
user = php_base64_decode((const unsigned char*)auth + 6, strlen(auth) - 6);
2721+
user = php_base64_decode((const unsigned char*)auth + 6, auth_len - 6);
27212722
if (user) {
27222723
pass = strchr(ZSTR_VAL(user), ':');
27232724
if (pass) {
@@ -2736,7 +2737,7 @@ PHPAPI int php_handle_auth_data(const char *auth)
27362737
SG(request_info).auth_digest = NULL;
27372738
}
27382739

2739-
if (ret == -1 && auth && auth[0] != '\0' && strncmp(auth, "Digest ", 7) == 0) {
2740+
if (ret == -1 && auth && auth_len > 0 && zend_binary_strncasecmp(auth, auth_len, "Digest ", sizeof("Digest ")-1, sizeof("Digest ")-1) == 0) {
27402741
SG(request_info).auth_digest = estrdup(auth + 7);
27412742
ret = 0;
27422743
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
--TEST--
2+
Digest Authentication
3+
--SKIPIF--
4+
<?php
5+
include "skipif.inc";
6+
?>
7+
--FILE--
8+
<?php
9+
include "php_cli_server.inc";
10+
php_cli_server_start('var_dump(!isset($_SERVER["PHP_AUTH_USER"]), !isset($_SERVER["PHP_AUTH_PW"]), $_SERVER["PHP_AUTH_DIGEST"]);');
11+
12+
$host = PHP_CLI_SERVER_HOSTNAME;
13+
$fp = php_cli_server_connect();
14+
15+
if(fwrite($fp, <<<HEADER
16+
GET / HTTP/1.1
17+
Host: {$host}
18+
Authorization: digest username="Mufasa", realm="testrealm@host.com", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", uri="/dir/index.html", qop=auth, nc=00000001, cnonce="0a4f113b", response="6629fae49393a05397450978507c4ef1", opaque="5ccc069c403ebaf9f0171e9517f40e41"
19+
20+
21+
HEADER
22+
)) {
23+
fpassthru($fp);
24+
}
25+
26+
?>
27+
--EXPECTF--
28+
HTTP/1.1 200 OK
29+
Host: %s
30+
Date: %s
31+
Connection: close
32+
X-Powered-By: PHP/%s
33+
Content-type: text/html; charset=UTF-8
34+
35+
bool(true)
36+
bool(true)
37+
string(242) "username="Mufasa", realm="testrealm@host.com", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", uri="/dir/index.html", qop=auth, nc=00000001, cnonce="0a4f113b", response="6629fae49393a05397450978507c4ef1", opaque="5ccc069c403ebaf9f0171e9517f40e41""

0 commit comments

Comments
 (0)