php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #23232 safe_mode does not honor PHP_AUTH_* in apache2
Submitted: 2003-04-15 21:22 UTC Modified: 2003-04-16 18:32 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: raul at dias dot com dot br Assigned: moriyoshi
Status: Closed Package: Apache2 related
PHP Version: 4.3.2RC1 OS: Linux
Private report: No CVE-ID:
 [2003-04-15 21:22 UTC] raul at dias dot com dot br
When safe_mode is on PHP_AUTH_USER and PHP_AUTH_PW should set
to NULL only if there is an external authentication.

If there is no external authentication these variables should 
NOT be set to NULL.

In APACHE 1.x code this is done by checking the authtype(r) 
variable, which means that there is an authentication set in
either httpd.conf or a .htaccess file.

In APACHE 2.x code, there is no such checking.
If safe_mode is on those variables are NULLed without any
other type of checking for an external authentication.

I am not sure if this is a BUG or a "FEATURE", but because
of the lack of information about this in the code or 
documentation, I am assuming this is a bug.


I am still not familiar with APACHE 2.x API or all 
its features to suggest the best way to fix this or patch it.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2003-04-15 22:14 UTC] iliaa@php.net
Please try the patch at: 
http://bb.prohost.org/ap2.txt
and let me know if it fixes the problem.
 [2003-04-15 22:52 UTC] raul at dias dot com dot br
Thanks.

I am compiling it, right now.

Btw, shouldn't that be applyed to apache2filter/ dir too?
 [2003-04-16 15:54 UTC] raul at dias dot com dot br
That patch did not work quite well.
However it helped to rewrite a new one.

This is the patch that worked:

------------------------------>8-------------------------
diff -Nru php-4.3.2RC1/sapi/apache2filter/sapi_apache2.c php-4.3.2RC1.patch/sapi/apache2filter/sapi_apache2.c
--- php-4.3.2RC1/sapi/apache2filter/sapi_apache2.c	2003-03-05 13:12:41.000000000 -0300
+++ php-4.3.2RC1.patch/sapi/apache2filter/sapi_apache2.c	2003-04-16 12:33:00.000000000 -0300
@@ -367,6 +367,7 @@
 {
 	char *content_type;
 	const char *auth;
+	const char *auth_type;	
 	
 	PG(during_request_startup) = 0;
 	SG(sapi_headers).http_response_code = 200;
@@ -387,7 +388,7 @@
 	apr_table_unset(f->r->headers_out, "Expires");
 	apr_table_unset(f->r->headers_out, "ETag");
 	apr_table_unset(f->r->headers_in, "Connection");
-	if (!PG(safe_mode)) {
+	if (!PG(safe_mode) || (PG(safe_mode) && !(auth_type = ap_auth_type(f->r)))) {
 		auth = apr_table_get(f->r->headers_in, "Authorization");
 		php_handle_auth_data(auth TSRMLS_CC);
 	} else {
diff -Nru php-4.3.2RC1/sapi/apache2handler/sapi_apache2.c php-4.3.2RC1.patch/sapi/apache2handler/sapi_apache2.c
--- php-4.3.2RC1/sapi/apache2handler/sapi_apache2.c	2003-03-10 00:17:04.000000000 -0300
+++ php-4.3.2RC1.patch/sapi/apache2handler/sapi_apache2.c	2003-04-16 12:34:21.000000000 -0300
@@ -409,6 +409,7 @@
 {
 	char *content_type;
 	const char *auth;
+	const char *auth_type;
 
 	SG(sapi_headers).http_response_code = 200;
 	SG(request_info).content_type = apr_table_get(r->headers_in, "Content-Type");
@@ -426,7 +427,7 @@
 	apr_table_unset(r->headers_out, "Expires");
 	apr_table_unset(r->headers_out, "ETag");
 	apr_table_unset(r->headers_in, "Connection");
-	if (!PG(safe_mode)) {
+	if (!PG(safe_mode) || (PG(safe_mode) && !(auth_type = ap_auth_type(r)))) {
 		auth = apr_table_get(r->headers_in, "Authorization");
 		php_handle_auth_data(auth TSRMLS_CC);
 	} else {
--------------------------8<------------------------


This one now worked on a 4.3.1 php:
------------------------8<-------------------
diff -Nru php-4.3.2RC1/sapi/apache2filter/sapi_apache2.c php-4.3.2RC1.patch/sapi/apache2filter/sapi_apache2.c
--- php-4.3.2RC1/sapi/apache2filter/sapi_apache2.c	2003-03-05 13:12:41.000000000 -0300
+++ php-4.3.2RC1.patch/sapi/apache2filter/sapi_apache2.c	2003-04-16 12:33:00.000000000 -0300
@@ -367,6 +367,7 @@
 {
 	char *content_type;
 	const char *auth;
+	const char *auth_type;	
 	
 	PG(during_request_startup) = 0;
 	SG(sapi_headers).http_response_code = 200;
@@ -387,7 +388,7 @@
 	apr_table_unset(f->r->headers_out, "Expires");
 	apr_table_unset(f->r->headers_out, "ETag");
 	apr_table_unset(f->r->headers_in, "Connection");
-	if (!PG(safe_mode)) {
+	if (!PG(safe_mode) || (PG(safe_mode) && !(auth_type = ap_auth_type(f->r)))) {
 		auth = apr_table_get(f->r->headers_in, "Authorization");
 		php_handle_auth_data(auth TSRMLS_CC);
 	} else {
----------------------------->8-----------------------


I tested it with AuthType apache's authentication.
 [2003-04-16 16:00 UTC] iliaa@php.net
Is there a reason in your patch that you are not verifying that the authentication is basic? If my understanding is correct, then only basic authentication is allowed when safe_mode is enabled.
 [2003-04-16 16:30 UTC] raul at dias dot com dot br
From my understanding, the only way to do a http 
authentication in php is not having an external 
authentication like apache's "AuthType".

Does not matter if it is Basic or Digest.

From http://www.php.net/manual/en/features.http-auth.php :

---------------------
As of PHP 4.3.0, in order to prevent someone from writing a script which reveals the password for a page that was authenticated through a traditional external mechanism, the PHP_AUTH variables will not be set if external authentication is enabled for that particular page and safe mode is enabled. Regardless, REMOTE_USER can be used to identify the externally-authenticated user. So, you can use $_SERVER['REMOTE_USER'].
--------------------

Also, IIRC, you cannot do http authentication twice at the 
same time and at the same page. I could be wrong on this.


In the original patch, the line:
--------------------
if (!PG(safe_mode) || (PG(safe_mode) && (auth_type = ap_auth_type(r)) && !strcasecmp(auth_type, "Basic"))) {
---------------------

If safe_mode is on, the only way to see the PHP_AUTH*
variables was by _having_ an external authentication
different from Basic.
In these case an malicious script would expose the 
USER + PASSWORD.

So it still not possible to use a PHP pure http 
authentication.

The solution is to enable the authentication if ap_auth_type(f->r) returns FALSE, as this mean that
no external authentication took place.
 [2003-04-16 18:26 UTC] moriyoshi@php.net
This bug seems my fault.
Raul: your reasoning seems valid. I'll fix the problem soon.
 [2003-04-16 18:32 UTC] iliaa@php.net
This bug has been fixed in CVS.

In case this was a PHP problem, snapshots of the sources are packaged
every three hours; this change will be in the next snapshot. You can
grab the snapshot at http://snaps.php.net/.
 
In case this was a documentation problem, the fix will show up soon at
http://www.php.net/manual/.

In case this was a PHP.net website problem, the change will show
up on the PHP.net site and on the mirror sites in short time.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Thu Apr 17 18:02:13 2014 UTC