From 5a6acc490893c902c795a1a4d6f10230f7fc47dd Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 12 Mar 2020 03:29:56 +0100 Subject: [PATCH 1/9] BadFunctions/EasyRFI: add unit tests --- .../Tests/BadFunctions/EasyRFIUnitTest.0.inc | 17 ++++ .../Tests/BadFunctions/EasyRFIUnitTest.1.inc | 17 ++++ .../EasyRFIUnitTest.Drupal7.1.inc | 14 ++++ .../Tests/BadFunctions/EasyRFIUnitTest.php | 83 +++++++++++++++++++ 4 files changed, 131 insertions(+) create mode 100644 Security/Tests/BadFunctions/EasyRFIUnitTest.0.inc create mode 100644 Security/Tests/BadFunctions/EasyRFIUnitTest.1.inc create mode 100644 Security/Tests/BadFunctions/EasyRFIUnitTest.Drupal7.1.inc create mode 100644 Security/Tests/BadFunctions/EasyRFIUnitTest.php diff --git a/Security/Tests/BadFunctions/EasyRFIUnitTest.0.inc b/Security/Tests/BadFunctions/EasyRFIUnitTest.0.inc new file mode 100644 index 0000000..9f4b8de --- /dev/null +++ b/Security/Tests/BadFunctions/EasyRFIUnitTest.0.inc @@ -0,0 +1,17 @@ + + */ + public function getErrorList($testFile = '') + { + switch ($testFile) { + case 'EasyRFIUnitTest.0.inc': + return [ + 8 => 1, + 10 => 1, + ]; + + case 'EasyRFIUnitTest.1.inc': + return [ + 8 => 1, + 10 => 1, + 17 => 1, + ]; + + case 'EasyRFIUnitTest.Drupal7.1.inc': + return [ + 8 => 1, + 10 => 1, + 13 => 1, + 14 => 2, + ]; + + default: + return []; + } + } + + /** + * Returns the lines where warnings should occur. + * + * The key of the array should represent the line number and the value + * should represent the number of warnings that should occur on that line. + * + * @param string $testFile The name of the file being tested. + * + * @return array + */ + public function getWarningList($testFile = '') + { + switch ($testFile) { + case 'EasyRFIUnitTest.1.inc': + return [ + 9 => 2, + 13 => 1, + 14 => 2, + ]; + + case 'EasyRFIUnitTest.Drupal7.1.inc': + return [ + 9 => 2, + ]; + + default: + return []; + } + } +} From b5a7ffe4fd6981a04366b5f585128caa23bfb591 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 12 Mar 2020 01:30:01 +0100 Subject: [PATCH 2/9] BadFunctions/EasyRFI: efficiency fix As the tokens to search for don't change during a PHPCS run, it is inefficient to use the "expensive" `array_merge()` function 1) within a `while` loop and 2) every time the sniff is triggered by an include/require token. The set of tokens to search for can just as easily be set only once before the sniff is ever triggered and doing so will make the sniff faster. --- Security/Sniffs/BadFunctions/EasyRFISniff.php | 14 +++++++++++++- Security/Sniffs/Utils.php | 7 ++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Security/Sniffs/BadFunctions/EasyRFISniff.php b/Security/Sniffs/BadFunctions/EasyRFISniff.php index 143d380..506ea03 100644 --- a/Security/Sniffs/BadFunctions/EasyRFISniff.php +++ b/Security/Sniffs/BadFunctions/EasyRFISniff.php @@ -7,12 +7,24 @@ class EasyRFISniff implements Sniff { + /** + * Tokens to search for within an include/require statement. + * + * @var array + */ + private $search = []; + /** * Returns the token types that this sniff is interested in. * * @return array(int) */ public function register() { + // Set the $search property. + $this->search = \PHP_CodeSniffer\Util\Tokens::$emptyTokens; + $this->search += \PHP_CodeSniffer\Util\Tokens::$bracketTokens; + $this->search += \PHPCS_SecurityAudit\Security\Sniffs\Utils::$staticTokens; + return array(T_INCLUDE, T_INCLUDE_ONCE, T_REQUIRE, T_REQUIRE_ONCE); } @@ -37,7 +49,7 @@ public function process(File $phpcsFile, $stackPtr) { $s = $stackPtr; } while ($s) { - $s = $phpcsFile->findNext(array_merge(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHP_CodeSniffer\Util\Tokens::$bracketTokens, \PHPCS_SecurityAudit\Security\Sniffs\Utils::$staticTokens), $s + 1, $closer, true); + $s = $phpcsFile->findNext($this->search, $s + 1, $closer, true); if ($s && $utils::is_token_user_input($tokens[$s])) { if (\PHP_CodeSniffer\Config::getConfigData('ParanoiaMode') || !$utils::is_token_false_positive($tokens[$s], $tokens[$s+2])) { $phpcsFile->addError('Easy RFI detected because of direct user input with ' . $tokens[$s]['content'] . ' on ' . $tokens[$stackPtr]['content'], $s, 'ErrEasyRFI'); diff --git a/Security/Sniffs/Utils.php b/Security/Sniffs/Utils.php index a0134eb..a0dba1f 100644 --- a/Security/Sniffs/Utils.php +++ b/Security/Sniffs/Utils.php @@ -3,7 +3,12 @@ class Utils { // Tokens that can't containts or use any variables (so no user input) - public static $staticTokens = array(T_CONSTANT_ENCAPSED_STRING, T_COMMA, T_LNUMBER, T_DNUMBER); + public static $staticTokens = array( + T_CONSTANT_ENCAPSED_STRING => T_CONSTANT_ENCAPSED_STRING, + T_COMMA => T_COMMA, + T_LNUMBER => T_LNUMBER, + T_DNUMBER => T_DNUMBER, + ); /** * Heavy used function to verify if a string from a token contains user input From 437c7f6876a650f39c284deef8f0f153e1099d86 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 12 Mar 2020 01:47:22 +0100 Subject: [PATCH 3/9] BadFunctions/EasyRFI: use the build-in PHPCS functionality [1] The PHPCS [`addError()`](https://pear.php.net/package/PHP_CodeSniffer/docs/3.5.4/apidoc/PHP_CodeSniffer/File.html#methodaddError) and [`addWarning()`](https://pear.php.net/package/PHP_CodeSniffer/docs/3.5.4/apidoc/PHP_CodeSniffer/File.html#methodaddWarning) functions have a build-in string replacement `sprintf()`-like functionality, so let's use it. --- Security/Sniffs/BadFunctions/EasyRFISniff.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Security/Sniffs/BadFunctions/EasyRFISniff.php b/Security/Sniffs/BadFunctions/EasyRFISniff.php index 506ea03..f5a1086 100644 --- a/Security/Sniffs/BadFunctions/EasyRFISniff.php +++ b/Security/Sniffs/BadFunctions/EasyRFISniff.php @@ -50,12 +50,18 @@ public function process(File $phpcsFile, $stackPtr) { } while ($s) { $s = $phpcsFile->findNext($this->search, $s + 1, $closer, true); + + $data = array( + $tokens[$s]['content'], + $tokens[$stackPtr]['content'], + ); + if ($s && $utils::is_token_user_input($tokens[$s])) { if (\PHP_CodeSniffer\Config::getConfigData('ParanoiaMode') || !$utils::is_token_false_positive($tokens[$s], $tokens[$s+2])) { - $phpcsFile->addError('Easy RFI detected because of direct user input with ' . $tokens[$s]['content'] . ' on ' . $tokens[$stackPtr]['content'], $s, 'ErrEasyRFI'); + $phpcsFile->addError('Easy RFI detected because of direct user input with %s on %s', $s, 'ErrEasyRFI', $data); } } elseif ($s && \PHP_CodeSniffer\Config::getConfigData('ParanoiaMode') && $tokens[$s]['content'] != '.') { - $phpcsFile->addWarning('Possible RFI detected with ' . $tokens[$s]['content'] . ' on ' . $tokens[$stackPtr]['content'], $s, 'WarnEasyRFI'); + $phpcsFile->addWarning('Possible RFI detected with %s on %s', $s, 'WarnEasyRFI', $data); } } } From 0471ea439e3442037b1f8e8795e3d9823f559b70 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 17 Mar 2020 07:25:22 +0100 Subject: [PATCH 4/9] BadFunctions/EasyRFI: use the build-in PHPCS functionality [2] The PHPCS native `PHP_CodeSniffer\Util\Tokens` class contains a number of useful token groups. For this particular sniff, the `Tokens::$includeTokens` applies and contains all the relevant tokens. It is generally a good idea to use the build-in token groups, as when something would change in how PHP and/or PHPCS tokenizes certain constructs, those groups will be updated too. --- Security/Sniffs/BadFunctions/EasyRFISniff.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Security/Sniffs/BadFunctions/EasyRFISniff.php b/Security/Sniffs/BadFunctions/EasyRFISniff.php index f5a1086..78e97aa 100644 --- a/Security/Sniffs/BadFunctions/EasyRFISniff.php +++ b/Security/Sniffs/BadFunctions/EasyRFISniff.php @@ -25,7 +25,7 @@ public function register() { $this->search += \PHP_CodeSniffer\Util\Tokens::$bracketTokens; $this->search += \PHPCS_SecurityAudit\Security\Sniffs\Utils::$staticTokens; - return array(T_INCLUDE, T_INCLUDE_ONCE, T_REQUIRE, T_REQUIRE_ONCE); + return \PHP_CodeSniffer\Util\Tokens::$includeTokens; } /** From b52dc50e73eff42b2d0c410d120ae33e1c87db28 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 12 Mar 2020 03:57:07 +0100 Subject: [PATCH 5/9] BadFunctions/EasyRFI: bug fix - fix detecting of start/end of the statement [1] Prevent false negatives when an `include`/`require` statement combines parentheses with concatentation outside parentheses. Checking whether the next non-empty token is an open parenthesis could cause false negatives as there may be additional paths of the path _after_ the parenthesized part of the statement. The only reason why this wasn't a problem up to now is because of a bug in the sniff determining `$s`. The `findNext()` function searches in the token stack and treats the `$start` parameter as _inclusive_. That means that when searching for the next non-empty token, passing the `$stackPtr` to an include/require statement would _always_ return the `$stackPtr` and not the next non-empty token _after_ the `$stackPtr` which could have been an open parenthesis (or not). Taking the logic related to the parentheses out of the sniff prevents this issue. --- Security/Sniffs/BadFunctions/EasyRFISniff.php | 12 ++++-------- Security/Tests/BadFunctions/EasyRFIUnitTest.0.inc | 2 +- Security/Tests/BadFunctions/EasyRFIUnitTest.1.inc | 2 +- .../Tests/BadFunctions/EasyRFIUnitTest.Drupal7.1.inc | 2 +- 4 files changed, 7 insertions(+), 11 deletions(-) diff --git a/Security/Sniffs/BadFunctions/EasyRFISniff.php b/Security/Sniffs/BadFunctions/EasyRFISniff.php index 78e97aa..89e7a7d 100644 --- a/Security/Sniffs/BadFunctions/EasyRFISniff.php +++ b/Security/Sniffs/BadFunctions/EasyRFISniff.php @@ -38,16 +38,12 @@ public function register() { * @return void */ public function process(File $phpcsFile, $stackPtr) { - $utils = \PHPCS_SecurityAudit\Security\Sniffs\UtilsFactory::getInstance(); + $closer = $phpcsFile->findNext(T_SEMICOLON, ($stackPtr + 1)); + + $utils = \PHPCS_SecurityAudit\Security\Sniffs\UtilsFactory::getInstance(); $tokens = $phpcsFile->getTokens(); - $s = $phpcsFile->findNext(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, $stackPtr, null, true, null, true); + $s = $stackPtr; - if ($tokens[$s]['code'] == T_OPEN_PARENTHESIS) { - $closer = $tokens[$s]['parenthesis_closer']; - } else { - $closer = $phpcsFile->findNext(T_SEMICOLON, $stackPtr); - $s = $stackPtr; - } while ($s) { $s = $phpcsFile->findNext($this->search, $s + 1, $closer, true); diff --git a/Security/Tests/BadFunctions/EasyRFIUnitTest.0.inc b/Security/Tests/BadFunctions/EasyRFIUnitTest.0.inc index 9f4b8de..3450534 100644 --- a/Security/Tests/BadFunctions/EasyRFIUnitTest.0.inc +++ b/Security/Tests/BadFunctions/EasyRFIUnitTest.0.inc @@ -6,7 +6,7 @@ // Base. include ( 'path/to/' . $_GET['filename'] ); // Error. -include_once 'path/to/' . "$filename" . '.' . $extension; +include_once ('path/to/' . "$filename") . '.' . $extension; require getenv('PATHTOFILE'); // Error. // Drupal 7. diff --git a/Security/Tests/BadFunctions/EasyRFIUnitTest.1.inc b/Security/Tests/BadFunctions/EasyRFIUnitTest.1.inc index 0fa86a2..714128d 100644 --- a/Security/Tests/BadFunctions/EasyRFIUnitTest.1.inc +++ b/Security/Tests/BadFunctions/EasyRFIUnitTest.1.inc @@ -6,7 +6,7 @@ // Base. include ( 'path/to/' . $_GET['filename'] ); // Error. -include 'path/to/' . "$filename" . '.' . $extension; // Warning x 2. +include ('path/to/' . "$filename") . '.' . $extension; // Warning x 2. include getenv('PATHTOFILE'); // Error. // Drupal 7. diff --git a/Security/Tests/BadFunctions/EasyRFIUnitTest.Drupal7.1.inc b/Security/Tests/BadFunctions/EasyRFIUnitTest.Drupal7.1.inc index a931390..41b8f97 100644 --- a/Security/Tests/BadFunctions/EasyRFIUnitTest.Drupal7.1.inc +++ b/Security/Tests/BadFunctions/EasyRFIUnitTest.Drupal7.1.inc @@ -6,7 +6,7 @@ // Base. include ( 'path/to/' . $_GET['filename'] ); // Error. -include 'path/to/' . "$filename" . '.' . $extension; // Warning x 2. +include ('path/to/' . "$filename") . '.' . $extension; // Warning x 2. include getenv('PATHTOFILE'); // Error. // Drupal 7. From 39182fc5b566bd0505d3e6f9a2db9aeb731ef351 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 12 Mar 2020 04:06:38 +0100 Subject: [PATCH 6/9] BadFunctions/EasyRFI: bug fix - fix detecting of start/end of the statement [2] PHPCS can be run from within an IDE during live coding. Similarly PHPCS can be run over files containing parse errors. With that in mind, it is best practice to bow out in those cases. Parse error detection should catch those errors. That is not the responsibility of this sniff. --- Security/Sniffs/BadFunctions/EasyRFISniff.php | 4 ++++ Security/Tests/BadFunctions/EasyRFIUnitTest.0.inc | 3 +++ Security/Tests/BadFunctions/EasyRFIUnitTest.1.inc | 3 +++ Security/Tests/BadFunctions/EasyRFIUnitTest.Drupal7.1.inc | 3 +++ 4 files changed, 13 insertions(+) diff --git a/Security/Sniffs/BadFunctions/EasyRFISniff.php b/Security/Sniffs/BadFunctions/EasyRFISniff.php index 89e7a7d..5186d23 100644 --- a/Security/Sniffs/BadFunctions/EasyRFISniff.php +++ b/Security/Sniffs/BadFunctions/EasyRFISniff.php @@ -39,6 +39,10 @@ public function register() { */ public function process(File $phpcsFile, $stackPtr) { $closer = $phpcsFile->findNext(T_SEMICOLON, ($stackPtr + 1)); + if ($closer === false) { + // Live coding or parse error. + return; + } $utils = \PHPCS_SecurityAudit\Security\Sniffs\UtilsFactory::getInstance(); $tokens = $phpcsFile->getTokens(); diff --git a/Security/Tests/BadFunctions/EasyRFIUnitTest.0.inc b/Security/Tests/BadFunctions/EasyRFIUnitTest.0.inc index 3450534..6332df0 100644 --- a/Security/Tests/BadFunctions/EasyRFIUnitTest.0.inc +++ b/Security/Tests/BadFunctions/EasyRFIUnitTest.0.inc @@ -15,3 +15,6 @@ include arg(2) . drupal_get_query_parameters()['param']; // Prevent false positives on safe $_SERVER variables. include $_SERVER['DOCUMENT_ROOT'] . '/filename.php'; + +// Intentional parse error. This should be the last test in the file. +require_once diff --git a/Security/Tests/BadFunctions/EasyRFIUnitTest.1.inc b/Security/Tests/BadFunctions/EasyRFIUnitTest.1.inc index 714128d..b986c2b 100644 --- a/Security/Tests/BadFunctions/EasyRFIUnitTest.1.inc +++ b/Security/Tests/BadFunctions/EasyRFIUnitTest.1.inc @@ -15,3 +15,6 @@ include arg(2) . drupal_get_query_parameters()['param']; // Warning x 2. // Prevent false positives on safe $_SERVER variables. include $_SERVER['DOCUMENT_ROOT'] . '/filename.php'; // Error. + +// Intentional parse error. This should be the last test in the file. +require $_GET['path'] diff --git a/Security/Tests/BadFunctions/EasyRFIUnitTest.Drupal7.1.inc b/Security/Tests/BadFunctions/EasyRFIUnitTest.Drupal7.1.inc index 41b8f97..0c337d6 100644 --- a/Security/Tests/BadFunctions/EasyRFIUnitTest.Drupal7.1.inc +++ b/Security/Tests/BadFunctions/EasyRFIUnitTest.Drupal7.1.inc @@ -12,3 +12,6 @@ include getenv('PATHTOFILE'); // Error. // Drupal 7. include ( 'path/to/' . $form['filename'] ); // Error. include arg(2) . drupal_get_query_parameters()['param']; // Error x 2. + +// Intentional parse error. This should be the last test in the file. +include_once ( $_GET['path'] From 48e7e4409b281257fb55812aedc4445c6d7fa0de Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 12 Mar 2020 04:01:15 +0100 Subject: [PATCH 7/9] BadFunctions/EasyRFI: bug fix - fix detecting of start/end of the statement [3] An `include`/`require` statement can be used within template files to include another template and doesn't need a closing semi-colon in that case. That situation was so far not being considered by the sniff and the sniff could in that case search way to far and report on completely unrelated statements after the include. --- Security/Sniffs/BadFunctions/EasyRFISniff.php | 2 +- Security/Tests/BadFunctions/EasyRFIUnitTest.0.inc | 5 +++++ Security/Tests/BadFunctions/EasyRFIUnitTest.1.inc | 5 +++++ Security/Tests/BadFunctions/EasyRFIUnitTest.php | 2 ++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Security/Sniffs/BadFunctions/EasyRFISniff.php b/Security/Sniffs/BadFunctions/EasyRFISniff.php index 5186d23..f270345 100644 --- a/Security/Sniffs/BadFunctions/EasyRFISniff.php +++ b/Security/Sniffs/BadFunctions/EasyRFISniff.php @@ -38,7 +38,7 @@ public function register() { * @return void */ public function process(File $phpcsFile, $stackPtr) { - $closer = $phpcsFile->findNext(T_SEMICOLON, ($stackPtr + 1)); + $closer = $phpcsFile->findNext(array(T_SEMICOLON, T_CLOSE_TAG), ($stackPtr + 1)); if ($closer === false) { // Live coding or parse error. return; diff --git a/Security/Tests/BadFunctions/EasyRFIUnitTest.0.inc b/Security/Tests/BadFunctions/EasyRFIUnitTest.0.inc index 6332df0..6eee64a 100644 --- a/Security/Tests/BadFunctions/EasyRFIUnitTest.0.inc +++ b/Security/Tests/BadFunctions/EasyRFIUnitTest.0.inc @@ -16,5 +16,10 @@ include arg(2) . drupal_get_query_parameters()['param']; // Prevent false positives on safe $_SERVER variables. include $_SERVER['DOCUMENT_ROOT'] . '/filename.php'; +?> + + + + 1, 10 => 1, + 20 => 1, ]; case 'EasyRFIUnitTest.1.inc': @@ -36,6 +37,7 @@ public function getErrorList($testFile = '') 8 => 1, 10 => 1, 17 => 1, + 20 => 1, ]; case 'EasyRFIUnitTest.Drupal7.1.inc': From 1e8f46246aff8878c21c4a95928c196c79ed88c6 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 12 Mar 2020 04:18:06 +0100 Subject: [PATCH 8/9] BadFunctions/EasyRFI: minor code simplification [1] Putting the `findNext()` in the `while` condition allows to simplify the `if` conditions within the loop. --- Security/Sniffs/BadFunctions/EasyRFISniff.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Security/Sniffs/BadFunctions/EasyRFISniff.php b/Security/Sniffs/BadFunctions/EasyRFISniff.php index f270345..c4fb395 100644 --- a/Security/Sniffs/BadFunctions/EasyRFISniff.php +++ b/Security/Sniffs/BadFunctions/EasyRFISniff.php @@ -48,19 +48,18 @@ public function process(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $s = $stackPtr; - while ($s) { - $s = $phpcsFile->findNext($this->search, $s + 1, $closer, true); + while (($s = $phpcsFile->findNext($this->search, $s + 1, $closer, true)) !== false) { $data = array( $tokens[$s]['content'], $tokens[$stackPtr]['content'], ); - if ($s && $utils::is_token_user_input($tokens[$s])) { + if ($utils::is_token_user_input($tokens[$s])) { if (\PHP_CodeSniffer\Config::getConfigData('ParanoiaMode') || !$utils::is_token_false_positive($tokens[$s], $tokens[$s+2])) { $phpcsFile->addError('Easy RFI detected because of direct user input with %s on %s', $s, 'ErrEasyRFI', $data); } - } elseif ($s && \PHP_CodeSniffer\Config::getConfigData('ParanoiaMode') && $tokens[$s]['content'] != '.') { + } elseif (\PHP_CodeSniffer\Config::getConfigData('ParanoiaMode') && $tokens[$s]['content'] != '.') { $phpcsFile->addWarning('Possible RFI detected with %s on %s', $s, 'WarnEasyRFI', $data); } } From d4c92924015899d2867b9c1dcafc8fce8b4498c0 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 12 Mar 2020 02:16:40 +0100 Subject: [PATCH 9/9] BadFunctions/EasyRFI: minor code simplification [2] The only token which can have a `content` of `.` is the `T_STRING_CONCAT` token, so we may as well exclude it from being found. --- Security/Sniffs/BadFunctions/EasyRFISniff.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Security/Sniffs/BadFunctions/EasyRFISniff.php b/Security/Sniffs/BadFunctions/EasyRFISniff.php index c4fb395..0496cda 100644 --- a/Security/Sniffs/BadFunctions/EasyRFISniff.php +++ b/Security/Sniffs/BadFunctions/EasyRFISniff.php @@ -24,6 +24,7 @@ public function register() { $this->search = \PHP_CodeSniffer\Util\Tokens::$emptyTokens; $this->search += \PHP_CodeSniffer\Util\Tokens::$bracketTokens; $this->search += \PHPCS_SecurityAudit\Security\Sniffs\Utils::$staticTokens; + $this->search[T_STRING_CONCAT] = T_STRING_CONCAT; return \PHP_CodeSniffer\Util\Tokens::$includeTokens; } @@ -59,7 +60,7 @@ public function process(File $phpcsFile, $stackPtr) { if (\PHP_CodeSniffer\Config::getConfigData('ParanoiaMode') || !$utils::is_token_false_positive($tokens[$s], $tokens[$s+2])) { $phpcsFile->addError('Easy RFI detected because of direct user input with %s on %s', $s, 'ErrEasyRFI', $data); } - } elseif (\PHP_CodeSniffer\Config::getConfigData('ParanoiaMode') && $tokens[$s]['content'] != '.') { + } elseif (\PHP_CodeSniffer\Config::getConfigData('ParanoiaMode')) { $phpcsFile->addWarning('Possible RFI detected with %s on %s', $s, 'WarnEasyRFI', $data); } }