php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #18792 no form variables after multipart/form-data
Submitted: 2002-08-07 14:50 UTC Modified: 2002-08-16 15:35 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: t dot bubeck at reinform dot de Assigned:
Status: Closed Package: HTTP related
PHP Version: 4.2.2 OS: Red Hat 7.1
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: t dot bubeck at reinform dot de
New email:
PHP Version: OS:

 

 [2002-08-07 14:50 UTC] t dot bubeck at reinform dot de
If you use a HTML form together with multipart/form-data encryption, then the
browser will send the form data in a POST request surrounded with boundaries.

Microsoft Internet Explorer (MSIE 5.0 at least) is violating the HTTP
specification (rfc 2616, paragraph 3.7: "Media Types") by repeating the
content-type in a wrong syntax. This will break PHP in looking for boundaries
of the multiparts and therefore no global variables will be defined containing
the form data. This will make it impossible to use PHP together with MSIE to
process any form data encoded with "multipart/form-data". This results in many
different bugs reported in large PHP projects (e.g. SquirrelMail) which are
impossible to fix.

Here is the (broken) HTTP request of MSIE:

POST /squirrel/src/compose.php HTTP/1.0
Via: 1.0 NDCSTR16
Connection: Keep-Alive
Content-Length: 1889
User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)
Content-Type: multipart/form-data; boundary=---------------------------7d29f1d3bad02b2,multipart/form-data; boundary=---------------------------7d29f1d3bad02b2,multipart/form-data; boundary=---------------------------7d29f1d3bad02b2
Host: reinform.hn.org
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, */*
Accept-Language: de,de,de
Referer: http://reinform.hn.org/squirrel/src/compose.php,http://reinform.hn.org/squirrel/src/compose.php,http://reinform.hn.org/squirrel/src/compose.php
Pragma: no-cache
Cookie: squirrelmail_language=de_DE; key=AW0RUMJgLK4%3D; PHPSESSID=0afb8733761a1723a006ce1676d9aa7b
Accept-Encoding: gzip, deflate,gzip, deflate,gzip, deflate

-----------------------------7d29f1d3bad02b2
Content-Disposition: form-data; name="session"

7
-----------------------------7d29f1d3bad02b2
Content-Disposition: form-data; name="send_to"


-----------------------------7d29f1d3bad02b2

The wrong part is the Content-Type which contains more than a single boundary
statement (which is a rfc2616 violation, because the parameters are not
seperated by ",").

PHP takes everything after the first '=' as the boundary and will therefore
look for a boundary
"---------------------------7d29f1d3bad02b2,multipart/form-data;
boundary=---------------------------7d29f1d3bad02b2,multipart/form-data;
boundary=---------------------------7d29f1d3bad02b2" which is never found in
the data stream. Therefore no parts are found and no variables are declared.

The following (trivial) patch will fix the bug and is based upong the current
CVS version of PHP-4.2.2:

diff -r -u php-4.2.2-orig/main/rfc1867.c php-4.2.2/main/rfc1867.c
--- php-4.2.2-orig/main/rfc1867.c	Sat Jul 20 21:17:52 2002
+++ php-4.2.2/main/rfc1867.c	Wed Aug  7 20:26:28 2002
@@ -599,7 +599,7 @@
 
 SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler)
 {
-	char *boundary, *s=NULL, *start_arr=NULL, *array_index=NULL;
+	char *boundary, *boundary_end, *s=NULL, *start_arr=NULL, *array_index=NULL;
 	char *temp_filename=NULL, *lbuf=NULL, *abuf=NULL;
 	int boundary_len=0, total_bytes=0, cancel_upload=0, is_arr_upload=0, array_len=0, max_file_size=0;
 	zval *http_post_files=NULL;
@@ -620,6 +620,10 @@
 		sapi_module.sapi_error(E_WARNING, "Missing boundary in multipart/form-data POST data");
 		return;
 	}
+	/* search for the end of the boundary */
+	boundary_end = strchr(boundary, ',');
+	if ( boundary_end ) *boundary_end = 0;
+
 	boundary++;
 	boundary_len = strlen(boundary);
 

Would you please apply the patch?

Thanks,
  Till

+-------+-------------------------------------------------------------+
|       | dr. tilmann bubeck               reinform medien- und       |
| rein  |                                  informationstechnologie AG |
| form  | cell.: +49 (172) 8 84 29 72      koenigstrasse 80           |
|    AG | fax  : +49 (711) 7 22 77 34      70173 stuttgart / germany  |
|       | email: t.bubeck@reinform.de      http://www.reinform.de     |
+-------+-------------------------------------------------------------+

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-08-07 14:56 UTC] sander@php.net
Status -> critical
Can someone with more insight to the POST mechanism in PHP look into this?
 [2002-08-07 14:57 UTC] rasmus@php.net
Critical?  Is this not fixed in CVS?  I certainly can't reproduce it here.
 [2002-08-07 15:17 UTC] rasmus@php.net
Oops, didn't read the entire description.  The summary matches a bug that was fixed.  This is actually different.
 [2002-08-08 01:35 UTC] t dot bubeck at reinform dot de
One more thing for clarification: my last checks showed, that the broken boundary doesn't come from MSIE alone. There must be a proxy (in my case Netscape Proxy 3.52) between MSIE and PHP. Then you can see this broken Content-Type entry. I don't know if this only happens with MSIE and NS Proxy. Maybe with MSIE and other proxies, too?

Using Mozilla 1.0 via Netscape Proxy 3.52 does NOT have the broken Content-Type.

Both tests were done form the same machine using the identical proxies and PHP server.
 [2002-08-09 05:13 UTC] tal@php.net
This bug has been fixed in CVS. You can grab a snapshot of the
CVS version 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.
Thank you for the report, and for helping us make PHP better.

Already fixed...
 [2002-08-16 01:15 UTC] t dot bubeck at reinform dot de
No, this bug is NOT fixed. I downloaded PHP this evening from CVS and the behaviour is still the same (buggy). Also I can't see anything that looks like my patch (or similar) to fix the bug, so the bug ist still in...

Have you seen, that I attached a patch solving the problem?

I have also looked at perl's CGI.pm which does something similar than my patch... So it seems to be ok.
 [2002-08-16 09:23 UTC] kalowsky@php.net
did you download the STABLE or non-STABLE snapshot?
 [2002-08-16 09:43 UTC] t dot bubeck at reinform dot de
I did a "cvs -q up -d". I did not request a particular revision by using "-r". By using phpinfo() it calls itself "PHP Version 4.3.0-dev".

Therefore I think I got the unstable tree. Is this right?
 [2002-08-16 12:58 UTC] kalowsky@php.net
yeah you got the right one
 [2002-08-16 13:09 UTC] ilia at prohost dot org
Could you please provide a sample page or source code to the form that would allow us to replicate the problem?
 [2002-08-16 13:12 UTC] kalowsky@php.net
more importantly, does this happen with the newer versions of MSIE (5.5, or 6.0)?
 [2002-08-16 14:21 UTC] t dot bubeck at reinform dot de
Here is the HTML page containing the form to send. It is part of "message compose" of SquirrelMail 1.2.7 and 
is generated by PHP. Do you need the PHP source, too?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>
<HEAD>
<LINK REL="stylesheet" TYPE="text/css" HREF="/squirrel/themes/css/sans-10.css">
<title>Squirrelmail</title><script language="JavaScript" type="text/javascript">
<!--
function checkForm() {
var f = document.forms.length;
var i = 0;
var pos = -1;
while( pos == -1 && i < f ) {
var e = document.forms[i].elements.length;
var j = 0;
while( pos == -1 && j < e ) {
if ( document.forms[i].elements[j].type == 'text' ) {
pos = j;
}
j++;
}
i++;
}
if( pos >= 0 ) {
document.forms[i-1].elements[pos].focus();
}
}
// -->
</script>
</head>

<BODY TEXT="#841722" BGCOLOR="#FFFFFF" LINK="#c6204a" VLINK="#c6204a" ALINK="#c6204a" onLoad="checkForm();">

<A NAME=pagetop></A>
<TABLE BGCOLOR="#FFFFFF" BORDER=0 WIDTH="100%" CELLSPACING=0 CELLPADDING=2>
   <TR BGCOLOR="#fad6b6" >
      <TD ALIGN=left>
         Aktueller Ordner: <B>inbox&nbsp;</B>
      </TD>
      <TD ALIGN=right><b><a href="/squirrel/src/signout.php" target="_top">Abmelden</a></b></TD>
   </TR>
   <TR BGCOLOR="#FFFFFF">
      <TD ALIGN=left>
<a href="/squirrel/src/compose.php?mailbox=%23mh%2Finbox" target="right">Mail schreiben</a>&nbsp;&nbsp;
<a href="/squirrel/src/addressbook.php" target="right">Adressen</a>&nbsp;&nbsp;
<a href="/squirrel/src/folders.php" target="right">Ordner</a>&nbsp;&nbsp;
<a href="/squirrel/src/options.php" target="right">Optionen</a>&nbsp;&nbsp;
<a href="/squirrel/src/search.php?mailbox=%23mh%2Finbox" target="right">Suchen</a>&nbsp;&nbsp;
<a href="/squirrel/src/help.php" target="right">Hilfe</a>&nbsp;&nbsp;
      </TD>
      <TD ALIGN="right"><A HREF="http://www.squirrelmail.org/" TARGET="_blank">SquirrelMail</A></TD>
   </TR>
</TABLE>


<FORM name=compose action="compose.php" METHOD=POST ENCTYPE="multipart/form-data">
<input type="hidden" name="session" value="1">
<TABLE WIDTH="100%" ALIGN=center CELLSPACING=0 BORDER=0>
   <TR>
      <TD BGCOLOR="#FFFFFF" WIDTH="10%" ALIGN=RIGHT>
An:      </TD><TD BGCOLOR="#FFFFFF" WIDTH="90%">
         <INPUT TYPE=text NAME="send_to" VALUE="" SIZE=60><BR>
      </TD>
   </TR>
   <TR>
      <TD BGCOLOR="#FFFFFF" ALIGN=RIGHT>
CC:      </TD><TD BGCOLOR="#FFFFFF" ALIGN=LEFT>
         <INPUT TYPE=text NAME="send_to_cc" SIZE=60 VALUE=""><BR>
      </TD>
   </TR>
   <TR>
      <TD BGCOLOR="#FFFFFF" ALIGN=RIGHT>
BCC:      </TD><TD BGCOLOR="#FFFFFF" ALIGN=LEFT>
         <INPUT TYPE=text NAME="send_to_bcc" VALUE="" SIZE=60><BR>
</TD></TR>
   <TR>
      <TD BGCOLOR="#FFFFFF" ALIGN=RIGHT>
Betreff:      </TD><TD BGCOLOR="#FFFFFF" ALIGN=LEFT>
         <INPUT TYPE=text NAME=subject SIZE=60 VALUE=""></td></tr>

  <TR><TD>
</TD><TD>
Priorit&auml;t: <select name="mailprio"><option value="1">Hoch</option><option value="3" 
selected>Normal</option><option value="5">Niedrig</option></select>
	Receipt: <input type="checkbox" name="request_mdn" value=1>On read <input type="checkbox" 
name="request_dr" value=1>On Delivery   <TR><td>
   </td><td>

    <INPUT TYPE=SUBMIT NAME="sigappend" VALUE="Signatur">
      <input type=submit name="html_addr_search" value="Adressen">
    <INPUT TYPE=SUBMIT NAME=send VALUE="Senden">
<input type="submit" name ="draft" value="Entwurf speichern">
<script type="text/javascript">
<!--
document.write("<input type=\"button\" value=\"Rechtschreibpr?fung\" 
onclick=\"window.open('../plugins/squirrelspell/sqspell_interface.php', 'sqspell', 
'status=yes,width=550,height=370,resizable=yes')\">");
//-->
</script>
   </TD></TR>

   <TR>
      <TD BGCOLOR="#FFFFFF" COLSPAN=2>
         &nbsp;&nbsp;<TEXTAREA NAME=body ROWS=20 COLS="76" WRAP="VIRTUAL">

+-------+-------------------------------------------------------------+ 
|       | dr. tilmann bubeck               reinform medien- und       | 
|       |                                  informationstechnologie AG | 
| rein  | fon  : +49 (711) 7 82 76-52      koenigstrasse 80           | 
| form  | fax  : +49 (711) 7 82 76-46      70173 stuttgart / germany  | 
|    AG | cell.: +49 (172) 8 84 29 72      fon: +49 (711) 7 82 76-50  | 
|       | email: t.bubeck@reinform.de      http://www.reinform.de     | 
+-------+-------------------------------------------------------------+

</TEXTAREA><BR>
      </TD>
   </TR>
   <TR><TD COLSPAN=2 ALIGN=LEFT> &nbsp; <INPUT TYPE=SUBMIT NAME=send VALUE="Senden"></TD></TR>
   <TR>
     <TD VALIGN=MIDDLE ALIGN=RIGHT>
Anhang:      </TD>
      <TD VALIGN=MIDDLE ALIGN=LEFT>
      <INPUT NAME="attachfile" SIZE=48 TYPE="file">
      &nbsp;&nbsp;<input type="submit" name="attach" value="Hinzuf&uuml;gen">
     </TD>
   </TR>
</TABLE>
<INPUT TYPE=hidden NAME=mailbox VALUE="#mh/inbox">
</FORM></BODY></HTML>
 [2002-08-16 14:24 UTC] t dot bubeck at reinform dot de
I'm not able to check the bug with IE 5.5 or 6.0, because I'm not able to install this software. The bug 
occurs from within a corporate network, where software installation is not possible.

Apart from that, I'm not sure, if _you_ would have been able to reproduce the bug, because it seems to be a 
mix between IE and Netscape Proxy, which shows the bug.
 [2002-08-16 14:32 UTC] kalowsky@php.net
Okay, it must be a Netscape proxy thing, as I cannot reproduce it here (found an old MSIE 5.0).  My only issue with your patch is my understanding of the RFC says that the boundry end can be any character (correct me if I'm wrong) not just a ".". 

Think your patch can be adapted to support this?  Determined by the, oh say, the end of the Content-Type header maybe?
 [2002-08-16 14:53 UTC] t dot bubeck at reinform dot de
I think that rfc2616, Section 2.2 is important:



Many HTTP/1.1 header field values consist of words separated by LWS

   or special characters. These special characters MUST be in a quoted

   string to be used within a parameter value (as defined in section

   3.6).        token          = 1*<any CHAR except CTLs or separators>

       separators     = "(" | ")" | "<" | ">" | "@"

                      | "," | ";" | ":" | "\" | <">

                      | "/" | "[" | "]" | "?" | "="

                      | "{" | "}" | SP | HT



In any case you have to remember, that strings could be quoted by '"', so that it is not enought to terminate the boundary after the next "," (as my patch did). To be fully correct, you should be able to deal with something like that:



boundary="XXX\"", param=value.



However, it may be enough to check for "," and ";":



This is the regular expression used by perl's CGI.pm:



my($boundary) = $ENV{'CONTENT_TYPE'} =~ /boundary=\"?([^\";,]+)\"?/;



It ends a boundary after ";" or ",". My patch only terminates the boundary string after ",". It may be better to also use ";" together with ",".
 [2002-08-16 15:35 UTC] kalowsky@php.net
commited to CVS.  Thanks for your patch.  You may wish to follow PHP-DEV and/or PHP-CVS to see if any further comments for or against it pop up.  
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 18 06:01:28 2024 UTC