php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #13961 some characters in server variable names are silently changed
Submitted: 2001-11-06 16:09 UTC Modified: 2008-08-30 16:53 UTC
Votes:2
Avg. Score:4.0 ± 1.0
Reproduced:2 of 2 (100.0%)
Same Version:1 (50.0%)
Same OS:1 (50.0%)
From: lampa at fee dot vutbr dot cz Assigned:
Status: Closed Package: Apache related
PHP Version: 4CVS, 5CVS OS: any
Private report: No CVE-ID: None
 [2001-11-06 16:09 UTC] lampa at fee dot vutbr dot cz
Apache module mod_setenvif sets variables in 
r->subprocess_env. If variable name contains character ".", then mod_php4.c/sapi_apache_register_server_variables() will
replace it with "_". This breaks internal
variables like force-response-1.0 (php changes it to
force-response-1_0).

Solution: the key in the php_register_variable() call
should be a copy of the real key.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2001-11-06 16:30 UTC] jeroen@php.net
This is mentioned in http://uk.php.net/manual/en/faq.html.php#AEN63677 . Impossible to find if you don't know where to find it. So changing this to a documentation problem.

(the issue is that invalid characters in incoming variable names, like dots, are converted to underscores. This happens with any incoming variable name, be it GET, POST, ENV, or whatever.)

Changed subject
 [2001-11-07 01:56 UTC] lampa at fee dot vutbr dot cz
I don't think that FAQ solves that problem.
Look at the source code of Apache server. There
are several tests of the variable "force-response-1.0" 
there. The problem is not that php code variable
is $force-response-1_0, that's OK, but the real
problem is that apache variable name in r->subprocess_env
is changed too. That's side effect and not pleasent.
 [2001-11-07 04:33 UTC] derick@php.net
This is not okay, PHP should not change the original key here.
Checking it out.
 [2001-12-11 09:57 UTC] lampa at fee dot vutbr dot cz
Not fixed in 4.1.0. Why? To be clear, one call is neccessary:

for (i = 0; i < arr->nelts; i++) {
                char *val,*key;

                if (elts[i].val) {
                        val = elts[i].val;
                } else {
                        val = empty_string;
                }
                key = estrdup(elts[i].key); /* HERE */
                php_register_variable(key, val, track_vars_array  ELS_CC PLS_CC)
;
        }

 [2003-11-11 18:15 UTC] daniele at orlandi dot com
This bug is still present in php 4.3.4 and may be harmful since all the BrowserMatch functionality to workaround browser bugs in Apache is essentially disabled.

As a proof of concept i patched sapi/apache2handler/sapi_apache2.c (apache2filter is probably affected too) and the problem went away.

Note that the patch may not be perfect as I don't know how Apache and PHP work internally very well.

--- php-4.3.4/sapi/apache2handler/sapi_apache2.c        2003-10-02 05:24:43.000000000 +0200
+++ php-4.3.4-patched/sapi/apache2handler/sapi_apache2.c        2003-11-11 23:52:06.000000000 +0100
@@ -227,9 +227,14 @@
        char *key, *val;
        zval **path_translated_zv;
  
+       char *t;
+
        APR_ARRAY_FOREACH_OPEN(arr, key, val)
                if (!val) val = empty_string;
-               php_register_variable(key, val, track_vars_array TSRMLS_CC);
+
+               t = estrndup(key, strlen(key));
+               php_register_variable(t, val, track_vars_array TSRMLS_CC);
+               efree(t);
        APR_ARRAY_FOREACH_CLOSE()
 [2003-11-14 07:06 UTC] lampa at fee dot vutbr dot cz
Still not fixed in 4.3.4
 [2003-11-18 19:52 UTC] iliaa@php.net
This is infact fixed php_register_variable() is actually a wrapper around php_register_variable_safe() which always makes a copy of the original before passing it to php_register_variable_ex().
 [2004-03-31 12:39 UTC] daniele at orlandi dot com
It still isn't fixed in PHP 4.3.5, php still corrupts apache's environment and here's the proof:

--------------- httpd.conf
....
BrowserMatch "a" downgrade-1.0 force-response-1.0 nokeepalive
....

--------------- a.html
<html>
<body>
</body>
</html>

--------------- a.php
<?
 echo "ciao";
?>

------------------------------------
GET /a.html HTTP/1.1
Host: stef.uli.it
Connection: close
User-Agent: a

HTTP/1.0 200 OK
Date: Wed, 31 Mar 2004 17:35:57 GMT
Server: Apache/2.0.49 (Unix) mod_ssl/2.0.49 OpenSSL/0.9.7b PHP/4.3.5
Last-Modified: Wed, 31 Mar 2004 17:35:43 GMT
ETag: "522e8-1e-c69ff9c0"
Accept-Ranges: bytes
Content-Length: 30
Connection: close
Content-Type: text/html

<html>
<body>
</body>
</html>
Connection closed by foreign host.
---------------------------------------
GET /a.php HTTP/1.1
Host: stef.uli.it
Connection: close
User-Agent: a

HTTP/1.1 200 OK
Date: Wed, 31 Mar 2004 17:34:57 GMT
Server: Apache/2.0.49 (Unix) mod_ssl/2.0.49 OpenSSL/0.9.7b PHP/4.3.5
X-Powered-By: PHP/4.3.5
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html

4
ciao
0

Connection closed by foreign host.
----------------------

As you see, the PHP response discards force-response-1.0 and still responds with HTTP/1.1.

My Cisco 7960 IP phones has a broken HTTP/1.1 client and isn't able to cope with chunked transfer encoding and I'm not able to make it work.
 [2008-08-30 16:53 UTC] rasmus@php.net
Fixed in 5.2, 5.3 and 6 CVS
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 08:01:28 2024 UTC