Req #42593 [Opn->Csd]: PHP's url_rewriter url encoding and html escaping behavior seems wrong
| From: | cmb@php.net | Date: | Fri, 10 Sep 2021 10:56:53 +0000 |
| Subject: | Req #42593 [Opn->Csd]: PHP's url_rewriter url encoding and html escaping behavior seems wrong | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-236519@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=42593&edit=1
ID: 42593
Updated by: cmb@php.net
Reported by: mickoz at parodius dot com
Summary: PHP's url_rewriter url encoding and html escaping
behavior seems wrong
-Status: Open
+Status: Closed
Type: Feature/Change Request
Package: URL related
Operating System: All (PHP Behavior)
PHP Version: 5.2.4
-Assigned To:
+Assigned To: cmb
Block user comment: N
Private report: N
New Comment:
These issues appear to have been resolved in the meantime.
Previous Comments:
------------------------------------------------------------------------
[2007-09-07 18:14:00] mickoz at parodius dot com
Description:
------------
When using PHP's url_rewriter (with output_add_rewrite_var) I have noticed it does this:
- It will urlencode() the value when rewriting an URL
- It will not urlencode() the name when rewriting an URL
- If we set it to write to form:
- It will create input hidden field after the form tag.
- It will urlencode() the value when writing the value in a form input tag
- It will not urlencode() the name when writing the name in a form input tag
- On top of that, while writing this, I found it won't htmlspecialchars() what it write (in no
case) // which is probably why we need to change the arg_separator.output like this
"ini_set('arg_separator.output', '&');"
Someone using a name, value pair that don't contain any html or url special characters
won't notice anything. However, if we use special characters in any of these, that can cause
some problems.
For now it looks like we should avoid special character in name or value and maybe there is reason
for this behavior beyond what I am thinking right now. But I believe it should be fixed right.
Also unfortunately doing an htmlspecialchars "smart" encoding might get problematic, since
a lot of people probably use the "arg_separator.output = &" hack for XHTML
compliance... it won't be a smart idea to automaticelly make it looks like & (after
html escaping it). (if my ideas get implemented, then there will need to be a way to guide this
behavior while staying backward compatible...)
----------------------------------------
Exemple #1:
----------------------------------------
<?php
ini_set('url_rewriter.tags',
'a=href,area=href,frame=src,input=src,form=action,fieldset=');
output_add_rewrite_var("test/name", "test/value");
?>
<a href="/test2">linkname</a>
<form action="/test" method="get">
<input type="text" value="" />
<input type="submit" value="ok" />
</form>
----------------------------------------
will output this:
----------------------------------------
<a href="/test2?test/name=test%2Fvalue">linkname</a>
<form action="/test?test/name=test%2Fvalue" method="get"><input
type="hidden" name="test/name" value="test%2Fvalue" />
<input type="text" value="" />
<input type="submit" value="ok" />
</form>
----------------------------------------
while I would expect:
----------------------------------------
<a href="/test2?test%2Fname=test%2Fvalue">linkname</a>
<form action="/test?test%2Fname=test%2Fvalue" method="get"><input
type="hidden" name="test/name" value="test/value" />
<input type="text" value="" />
<input type="submit" value="ok" />
</form>
----------------------------------------
Exemple #2: (with html special characters)
----------------------------------------
<?php
ini_set('url_rewriter.tags',
'a=href,area=href,frame=src,input=src,form=action,fieldset=');
output_add_rewrite_var("test/name\"&", "test/value\"&");
?>
<a href="/test2">linkname</a>
<form action="/test" method="get">
<input type="text" value="" />
<input type="submit" value="ok" />
</form>
----------------------------------------
will output this:
----------------------------------------
<a href="/test2?test/name"&=test%2Fvalue%22%26">linkname</a>
<form action="/test?test/name"&=test%2Fvalue%22%26"
method="get"><input type="hidden" name="test/name"&"
value="test%2Fvalue%22%26" />
<input type="text" value="" />
<input type="submit" value="ok" />
</form>
----------------------------------------
while I would expect:
----------------------------------------
<a href="/test2?test/name%22%26=test%2Fvalue%22%26">linkname</a>
<form action="/test?test/name%22%26=test%2Fvalue%22%26"
method="get"><input type="hidden"
name="test/name"&" value="test/value"&" />
<input type="text" value="" />
<input type="submit" value="ok" />
</form>
========================================
Resume of the behavior I would expect (written in notes+pseudo/php code)
========================================
- When rewriting an URL, append to the original url (that one should have been espaced properly by
the user):
- "?" if not defined (already doing this)
-
htmlspecialchars(urlencode($name1).'='.urlencode($value1).'&'.urlencode($name2).'='.urlencode($value2)).'&'...)
where '&' is the argument separator (and if doing so, we won't need to put
html in an arg separator value!!! which at first did not make sense, even thought there is maybe
reason, especially now that people rely on it...).
- urlencode the name and the value
- html escape what we output (since they are always in html value zone)
- When adding input type=hidden fields
- <input type="hidden" name="<?php htmlspecialchars($name1); ?>"
value="<?php htmlspecialchars($value1); ?>" />
- no url escaping, should not be done here!
- html escape the name and value as it should be
// there is maybe details that I forgot, but that is a good start and I can always help think
further (and validate the logic) if someone handle this case
----------------------------------------
Notes:
----------------------------------------
- The problem I got when submitting this bug is that I was using urlrewriter to write a value like
"N/A". It did add input hidden field in my forms and one of my form has
method="get". When submitting a form in method=get, it does escape the form's input
value... and since it was already escaped... the value was escaped twice (which make it impossible
to use that kind of value in that context, unless we add hack around it...)
example:
output_add_rewrite_var("var", "N/A");
become:
<input type="hidden" name="var" value="N%2FA" />
then become in URL after submitting the form:
N%252FA
(because % get escaped to %25)
- A solution is to never use special characters for name and value when using php urlrewriter, but
still it doesn't feel logical (unless it can apply to other usage that I am not aware of)
- Another solution might be to write my own output handler
- I believe these kind of thing is at the origin of other related problem (or "hack" to
fix it in PHP) and that fixing it there will avoid need like needing to change the arg separator
with html in it (again there is probably stuff I don't know which render this impossible, but
maybe not)
Hope that help and that will improve thing (or that I will simply understand why all these
behaviors)
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=42593&edit=1