|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #42718 FILTER_UNSAFE_RAW not applied when configured as default filter, even with flags
Submitted: 2007-09-20 16:54 UTC Modified: 2017-10-24 07:30 UTC
Avg. Score:3.1 ± 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
Have you experienced this issue?
Rate the importance of this bug to you:

 [2007-09-20 16:54 UTC] arnaud dot lb at gmail dot com
The "unsafe_raw" filter is not applied when configured as default 

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 

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.

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


Add a Patch

Pull Requests

Add a Pull Request


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:

And a testcase:

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
 [2007-09-29 20:04 UTC]
"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 

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, 
=> "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]
Pierre, he is right, fix it. :)
 [2008-11-02 13:06 UTC]
Arnaud, fix it yourself.
 [2008-11-02 22:07 UTC]
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
Thank you for the report, and for helping us make PHP better.

 [2008-12-06 17:18 UTC]
Reopening, this patch broke magic_quotes_gpc and has been backed out.
 [2008-12-06 17:32 UTC]
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.
 [2008-12-06 17:52 UTC]
All my apologizes for this broken fix.

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

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

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 

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]
> 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]
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]
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]
-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...
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Tue Jul 27 03:01:23 2021 UTC