-
Notifications
You must be signed in to change notification settings - Fork 43
Security/PHPFilterFunctions: various sniff improvements #846
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
GaryJones
merged 7 commits into
develop
from
feature/security-phpfilterfunctions-sniff-review
Jul 18, 2025
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
8581c40
Security/PHPFilterFunctions: improve the tests
jrfnl dafc562
Security/PHPFilterFunctions: remove redundant `strtoupper()` calls
jrfnl e953ac7
Security/PHPFilterFunctions: prevent some false positives
jrfnl e10dd27
Security/PHPFilterFunctions: add support for PHP 8.0+ named parameters
jrfnl c65e55c
Security/PHPFilterFunctions: report restricted filter on the correct …
jrfnl 4febbf3
Security/PHPFilterFunctions: ignore function calls using PHP 5.6+ arg…
jrfnl 824bb1b
Security/PHPFilterFunctions: document unsupported PHP feature
jrfnl File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
113 changes: 92 additions & 21 deletions
113
WordPressVIPMinimum/Tests/Security/PHPFilterFunctionsUnitTest.inc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,29 +1,100 @@ | ||
| <?php | ||
|
|
||
| $url = 'http://www.google.ca'; | ||
| $_GET['foo'] = 'bar'; | ||
| $array = [ 'something_something', 'https://www.google.com', '6' ]; | ||
| /* | ||
| * Not the sniff target. | ||
| */ | ||
| use filter_var; | ||
|
|
||
| // Ok. | ||
| my\ns\filter_input($a, $b); | ||
| $this->filter_var_array($a, $b); | ||
| $this?->filter_input_array($a, $b); | ||
| MyClass::filter_var($a, $b); | ||
| echo FILTER_INPUT; | ||
| namespace\filter_var_array($a, $b); | ||
|
|
||
| // Looks like a function call, but is a PHP 8.0+ class instantiation via an attribute. | ||
| #[Filter_Input('text')] | ||
| function foo() {} | ||
|
|
||
| // PHP 8.1 first class callable. | ||
| // As we have no knowledge about what parameters will be passed, we shouldn't flag this. | ||
| add_filter('my_filter', filter_var(...)); | ||
|
|
||
|
|
||
| /* | ||
| * These should all be okay. | ||
| */ | ||
| filter_var( $url, FILTER_SANITIZE_URL ); | ||
| filter_var( 'test', FILTER_SANITIZE_STRING ); | ||
| filter_var( "test", FILTER_SANITIZE_STRING ); | ||
| filter_input( INPUT_GET, 'foo', FILTER_SANITIZE_STRING ); | ||
| \filter_var( 'test', FILTER_SANITIZE_STRING ); | ||
| FILTER_INPUT( INPUT_GET, 'foo', FILTER_SANITIZE_STRING, ); | ||
| filter_input( INPUT_GET, "foo" , FILTER_SANITIZE_STRING ); | ||
| filter_var_array( $array, FILTER_SANITIZE_STRING ); | ||
| filter_input_array( $array, FILTER_SANITIZE_STRING ); | ||
| filter_input_array( $array,FILTER_SANITIZE_STRING ); | ||
|
|
||
| // Bad. | ||
| filter_input( INPUT_GET, 'foo' ); // Missing third parameter. | ||
| filter_input( INPUT_GET, 'foo', FILTER_DEFAULT ); // This filter ID does nothing. | ||
| filter_input( INPUT_GET, "foo", FILTER_UNSAFE_RAW ); // This filter ID does nothing. | ||
| filter_var( $url ); // Missing second parameter. | ||
| filter_var( $url, FILTER_DEFAULT ); // This filter ID does nothing. | ||
| filter_input_array( $array, filter_default ); // Constants are case-sensitive, so this is not the FILTER_DEFAULT constant. | ||
|
|
||
| // Ignore as undetermined. | ||
| filter_var( "test", get_filter() ); | ||
| \Filter_Var_Array( $array, $filterName ); | ||
| filter_input_array( $array,$obj->get_filter() , ); | ||
|
|
||
| // Incomplete function call, should be ignored by the sniff. | ||
| $incorrect_but_ok = filter_input(); | ||
|
|
||
| /* | ||
| * These should all be flagged with a warning. | ||
| */ | ||
| filter_input( INPUT_GET, 'foo' ); // Missing $filter parameter. | ||
| \filter_input( INPUT_GET, 'foo', FILTER_DEFAULT ); // This filter ID does nothing. | ||
| filter_input( INPUT_GET, "foo", FILTER_UNSAFE_RAW /* comment */ ,); // This filter ID does nothing. | ||
|
|
||
| filter_var( $url ); // Missing $filter parameter. | ||
| Filter_Var( $url, FILTER_DEFAULT ); // This filter ID does nothing. | ||
| filter_var( 'https://google.com', FILTER_UNSAFE_RAW ); // This filter ID does nothing. | ||
| filter_var_array( $array ); // Missing second parameter. | ||
|
|
||
| filter_var_array( $array, ); // Missing $options parameter. | ||
| filter_var_array( $array, FILTER_DEFAULT ); // This filter ID does nothing. | ||
| filter_var_array( $array, FILTER_UNSAFE_RAW ); // This filter ID does nothing. | ||
| filter_input_array( $array ); // Missing second parameter. | ||
| filter_input_array( $array, FILTER_DEFAULT ); // This filter ID does nothing. | ||
| filter_input_array( $array, FILTER_UNSAFE_RAW ); // This filter ID does nothing. | ||
|
|
||
| filter_input_array( $array ); // Missing $options parameter. | ||
| \FILTER_INPUT_ARRAY( $array, FILTER_DEFAULT ); // This filter ID does nothing. | ||
| filter_input_array( $array, FILTER_UNSAFE_RAW, ); // This filter ID does nothing. | ||
|
|
||
| // Safeguard handling of function calls using PHP 8.0+ named parameters. | ||
| filter_input(var_name: $var_name, filter: FILTER_SANITIZE_STRING, type: FILTER_DEFAULT); // OK, invalid input value for $type, but that's not our concern. | ||
| filter_input(var_name: $var_name, filter: $filter, type: $type); // Ignore, undetermined. | ||
| filter_input( | ||
| var_name: $var_name, | ||
| filter: FILTER_DEFAULT, // This filter ID does nothing. | ||
| type: $type, | ||
| ); | ||
|
|
||
| filter_var(filter: FILTER_SANITIZE_URL); // OK, well not really, missing required parameter, but that's not our concern. | ||
| filter_var($value, options: FILTER_NULL_ON_FAILURE); // Missing $filter parameter. | ||
| filter_var(value: $value, filters: FILTER_SANITIZE_URL); // Typo in parameter name, report as missing $filter parameter. | ||
|
|
||
| filter_var_array(options: FILTER_UNSAFE_RAW, array: $array); // This filter ID does nothing. | ||
|
|
||
| filter_input_array($type, add_empty: false, options: FILTER_DEFAULT,); // This filter ID does nothing. | ||
|
|
||
| // Ignore function calls using PHP 5.6 argument unpacking as we don't know what parameters were passed. | ||
| filter_input(INPUT_GET, ...$params); | ||
| trim(filter_input(INPUT_GET, ...$params)); | ||
| // ... but only ignore unpacking if done at the correct nesting level. | ||
| filter_input(INPUT_GET, $obj->getVarname(...$params)); // Missing $filter parameter. | ||
|
|
||
| // False negatives: $options arrays are currently not (yet) supported by this sniff. | ||
| // See: https://www.php.net/manual/en/function.filter-var-array.php and https://www.php.net/manual/en/function.filter-input-array.php | ||
| filter_var_array( | ||
| $array, | ||
| array('keyA' => FILTER_DEFAULT), // This filter ID does nothing. | ||
| ); | ||
| filter_input_array( | ||
| $array, | ||
| [ | ||
| 'keyA' => [ | ||
| 'filter' => FILTER_UNSAFE_RAW, // This filter ID does nothing. | ||
| 'flags' => FILTER_FORCE_ARRAY, | ||
| ], | ||
| 'keyB' => [ | ||
| 'filter' => FILTER_SANITIZE_ENCODED, | ||
| ], | ||
| ] | ||
| ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than check against
filter_input, could this check against$param_positioninstead? In case any future entries are added from the third param position?Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As the extension hasn't effectively been maintained since 2011, I'm a bit sceptical of the idea of additional functions being added to the
Filterextension.I'd say, let's leave it as-is. If in the future additional functions would need to be checked, this can always be changed then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a side-note: I don't think the error codes should refer to the parameter position at all, but changing that is a BC-break, so would need to wait for a future major release.
See this remark from one of the commit messages:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh sod it. As the error code - at this time - is tied to the parameter position, you have a point, so I've changed it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Darn... merged while I posted this, I'll check how the PR has gone in (with or without the condition change) and if without, will pull the condition change separately.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without. Opened PR #848 to update this.