php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #42718 filter.default_flags are ignored if filter.default = unsafe_raw
Submitted: 2007-09-20 16:54 UTC Modified: 2021-08-11 11:00 UTC
Votes:135
Avg. Score:3.0 ± 0.8
Reproduced:40 of 44 (90.9%)
Same Version:27 (67.5%)
Same OS:24 (60.0%)
From: arnaud dot lb at gmail dot com Assigned:
Status: Open Package: Filter related
PHP Version: 5.*, 6CVS (2009-04-30) OS: *
Private report: No CVE-ID: None
 [2007-09-20 16:54 UTC] arnaud dot lb at gmail dot com
Description:
------------
The "unsafe_raw" filter is not applied when configured as default 
filter.

I found that the php_sapi_filter() internal function in 
ext/filter/filter.c intentionally bypass this filter:

if (!(IF_G(default_filter) == FILTER_UNSAFE_RAW)){
 (apply default filter)
} else [...]

The unsafe_raw filter does nothing by default, but it 
can "optionally strip or encode special characters", and it is the 
only filter which is able to do that without doing any other 
filtering.

Reproduce code:
---------------
- Prints filter.default and filter.default_flags values,
- Check if $_GET['a'] contains a null byte (null bytes may be filtered by FILTER_UNSAFE_RAW with the FILTER_FLAG_STRIP_LOW flag
- Check if $_GET['a'] though filter_input() with the same filter/flags contains a null byte.

<?php
echo "filter.default = " . ini_get('filter.default') . " <br />\n";
echo "filter.default_flags = " . ini_get('filter.default_flags') . " <br />\n";
echo "<br />";
echo "\$_GET['a'] contains \\0: " . (strpos($_GET['a'], "\0") !== false ? 'Yes' : 'No') . " <br />\n";
echo "<br />";
echo "\$_GET['a'] throught filter_var() contains \\0: " . (strpos(filter_var($_GET['a'], FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW), "\0") !== false ? 'Yes' : 'No') . "<br />";
echo "<br />";
?>

Expected result:
----------------
filter.default: unsafe_raw
filter.default_flags: 4

$_GET['a'] contains \0: No

$_GET['a'] through filter_var() contains \0: No

Actual result:
--------------
filter.default: unsafe_raw
filter.default_flags: 4

$_GET['a'] contains \0: Yes

$_GET['a'] through filter_var() contains \0: No

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-09-24 17:37 UTC] arnaud dot lb at gmail dot com
I made a little (one-line) patch for this bug:
https://s3.amazonaws.com/arnaud.lb/filter-bug-42718.patch.txt

And a testcase:
https://s3.amazonaws.com/arnaud.lb/bug42718.phpt.txt

And an other test case to check if the patch does not modify the 
behavior of the php_sapi_filter() function:

- Apply filter, only if filter will do something (unsafe_raw with no 
flags do nothing)
- Else, fallback to magic_quotes_gpc if enabled

https://s3.amazonaws.com/arnaud.lb/052.phpt.txt
 [2007-09-29 20:04 UTC] pajoye@php.net
"The unsafe_raw filter does nothing by default, but it 
can "optionally strip or encode special characters", and it is the 
only filter which is able to do that without doing any other 
filtering."

The string filter with the correct flags should work as you expected. It is normal that the unsafe_raw filter does nothing.

What are you trying to achieve exactly? (ie using other filters but it did not work as you expect)
 [2007-09-29 21:40 UTC] arnaud dot lb at gmail dot com
Thanks for your reply.

I'm trying to strip low ascii characters from GET/POST/COOKIE using 
the filter extension, and the only way to do that is to use the 
unsafe_raw filter with the FILTER_FLAG_STRIP_LOW flag.

The string filter can do that with the FILTER_FLAG_STRIP_LOW flag, 
but it strips HTML tags too, and I don't want to strip HTML tags.

From the documentation, about the unsafe_raw filter: 
 "Do nothing, optionally strip or encode special characters."

It works as expected using filter_var() for example:

filter_var("a <b> \000 c", FILTER_SANITIZE_STRING, 
FILTER_FLAG_STRIP_LOW)
=> "a   c" (the null char was striped, but the <b> tag too)

filter_var("a <b> \000 c", FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW)
=> "a <b>  c" (only the null char was striped)

But it does not work as a default filter. The bug42718.phpt testcase 
demonstrates that.

According to the documentation, I think that the unsafe_raw filter 
may not be bypassed when default_flags are != 0. This is the only 
change my patch do:

-		if (!(IF_G(default_filter) == FILTER_UNSAFE_RAW)) {
+		if (!(IF_G(default_filter) == FILTER_UNSAFE_RAW) || 
IF_G(default_filter_flags) != 0) {
 [2007-09-30 06:29 UTC] jani@php.net
Pierre, he is right, fix it. :)
 [2008-11-02 13:06 UTC] jani@php.net
Arnaud, fix it yourself.
 [2008-11-02 22:07 UTC] lbarnaud@php.net
This bug has been fixed in CVS.

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/.
 
Thank you for the report, and for helping us make PHP better.


 [2008-12-06 17:18 UTC] scottmac@php.net
Reopening, this patch broke magic_quotes_gpc and has been backed out.
 [2008-12-06 17:32 UTC] magicaltux@php.net
This is a proposed fix for this bug that will keep old behavior.

Another fix could be simply to test IF_G(default_filter_flags) against FILTER_FLAG_NO_ENCODE_QUOTES instead of 0.

http://ookoo.org/svn/snip/php_5_2-broken_filter_and_magic_quotes.patch
 [2008-12-06 17:52 UTC] lbarnaud@php.net
All my apologizes for this broken fix.

A quick workaround for 5.2.7 users is to add the following in the php.ini:
filter.default_flags=0

Scott has reverted this and this bug is not present in CVS.
 [2008-12-06 18:25 UTC] pajoye@php.net
ooch.

I did not catch in this bug before, but there is a major misunderstanding in the first comment.

"The unsafe_raw filter does nothing by default, but it 
can "optionally strip or encode special characters", and it is the 
only filter which is able to do that without doing any other 
filtering."

That's wrong. UNSAFE_RAW, the key word here is RAW. It means that the data is returned unfiltered, without flag, nothing, nada. If this behavior has been changed then please revert it.

I did not check if it is present in 5.2.7 (it seems to be, as said in this report or another), that may require a quick fix release (Ilia?).
 [2008-12-06 19:17 UTC] lbarnaud@php.net
> That's wrong

This is exactly what you said one year ago, just before it was demonstrated that FILTER_UNSAFE_RAW actually does something (according to documentation, code, and examples), and the bug has been assigned to you.

That said, I'm not rejecting the fault on anyone, and the important is to revert, which is done.

 [2008-12-06 19:20 UTC] pajoye@php.net
Yes, revert was the best option for now.

I will dig into it on Monday and re read the discussions about that (there was some discussions about this whole thing when we added filter to core).

 [2010-04-05 18:21 UTC] rasmus@php.net
We should figure out what we want here.  Do we want to allow default flags to be 
applied with the unsafe_raw filter or not?
 [2017-10-24 07:30 UTC] kalle@php.net
-Status: Assigned +Status: Open -Assigned To: pajoye +Assigned To:
 [2020-12-21 05:07 UTC] sji at sj-i dot dev
I've confirmed that this still occurs on 8.0.1 .
filter.default_flags are ignored if filter.default = unsafe_raw.

Because the behavior is being kept this way for 13 years, I'm not confident whether just enabling the filtering makes sense.
Maybe fixing the manual is a simple solution?

If there are needs for this specific feature, adding another filter that can be used in filter.default with filter.default_flags would be good...
 [2021-08-11 11:00 UTC] cmb@php.net
-Summary: FILTER_UNSAFE_RAW not applied when configured as default filter, even with flags +Summary: filter.default_flags are ignored if filter.default = unsafe_raw -Type: Bug +Type: Documentation Problem
 [2021-08-11 11:00 UTC] cmb@php.net
> Maybe fixing the manual is a simple solution?

At this point in time, I have to agree, although that makes
filter.default practically useless.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Nov 12 16:01:32 2024 UTC