From c36e8c6fae2be53b37e361e7e314302de0fbeb5c Mon Sep 17 00:00:00 2001 From: jrfnl Date: Mon, 13 Jan 2020 23:39:54 +0100 Subject: [PATCH] Fix compliance with PHPCS PHPCS has specific naming and directory layout requirements for external standards which the `Security` standard did not comply with. While things sort of worked with the symlink hack, the net effect was: - The PHPCS autoloader did not work. - None of the PHPCS ruleset configuration options worked as PHPCS could not match sniffs to files. - Some sniffs would never load. This PR fixes this by: 1. Setting the base namespace to `PHPCS_SecurityAudit\Security` and annotating this in the `ruleset.xml` file in the correct manner. 2. Fixing all namespaces and uses thereof throughout the codebase. 3. Fixing the `Drupal8/Utils.php` file which was missing the namespace and was still referring to an out-of-date class name to extend. 4. Fixing the namespace names and file names of the CVE sniffs. - The namespace of a sniff has to reflect its path in the standard. - The file name has to reflect the name of the sniff. 5. Fixing the names of the CVE sniffs in the example rulesets 6. Removing the symlink file and all references to it. Instead `require` the [DealerDirect Composer PHPCS plugin](https://github.com/Dealerdirect/phpcodesniffer-composer-installer) which will sort out the `installed_paths` for PHPCS . 7. Setting the minimum PHPCS version to `3.0.2` as prior to that external standards weren't fully supported in the 3.x branch. 8. Removing the `autoload` section in `composer.json`. This is no longer needed and in certain situations can cause conflicts/fatal errors. References: * https://github.com/squizlabs/PHP_CodeSniffer/wiki/Coding-Standard-Tutorial * https://github.com/squizlabs/PHP_CodeSniffer/wiki/Version-3.0-Upgrade-Guide * https://github.com/squizlabs/PHP_CodeSniffer/issues/2481#issuecomment-485145277 * https://github.com/squizlabs/PHP_CodeSniffer/issues/2606 * https://github.com/squizlabs/PHP_CodeSniffer/issues/1469 * https://github.com/Dealerdirect/phpcodesniffer-composer-installer Fixes 47 --- Dockerfile | 1 - README.md | 23 ++++++++----------- Security/Sniffs/BadFunctions/AssertsSniff.php | 6 ++--- .../Sniffs/BadFunctions/BackticksSniff.php | 4 ++-- .../BadFunctions/CallbackFunctionsSniff.php | 6 ++--- .../BadFunctions/CryptoFunctionsSniff.php | 4 ++-- Security/Sniffs/BadFunctions/EasyRFISniff.php | 6 ++--- Security/Sniffs/BadFunctions/EasyXSSSniff.php | 6 ++--- .../BadFunctions/ErrorHandlingSniff.php | 4 ++-- .../BadFunctions/FilesystemFunctionsSniff.php | 6 ++--- .../BadFunctions/FringeFunctionsSniff.php | 6 ++--- .../FunctionHandlingFunctionsSniff.php | 6 ++--- Security/Sniffs/BadFunctions/MysqliSniff.php | 6 ++--- Security/Sniffs/BadFunctions/NoEvalsSniff.php | 2 +- .../Sniffs/BadFunctions/PhpinfosSniff.php | 4 ++-- .../Sniffs/BadFunctions/PregReplaceSniff.php | 4 ++-- .../Sniffs/BadFunctions/SQLFunctionsSniff.php | 6 ++--- .../BadFunctions/SystemExecFunctionsSniff.php | 6 ++--- ...20132110Sniff.php => CVE20132110Sniff.php} | 4 ++-- ...20134113Sniff.php => CVE20134113Sniff.php} | 4 ++-- Security/Sniffs/Drupal7/AESModuleSniff.php | 2 +- .../Sniffs/Drupal7/AdvisoriesContribSniff.php | 4 ++-- .../Sniffs/Drupal7/AdvisoriesCoreSniff.php | 4 ++-- Security/Sniffs/Drupal7/CacheiSniff.php | 2 +- Security/Sniffs/Drupal7/DbQueryACSniff.php | 2 +- Security/Sniffs/Drupal7/DynQueriesSniff.php | 2 +- Security/Sniffs/Drupal7/HttpRequestSniff.php | 2 +- Security/Sniffs/Drupal7/SQLiSniff.php | 2 +- .../Sniffs/Drupal7/UserInputWatchSniff.php | 2 +- Security/Sniffs/Drupal7/Utils.php | 4 ++-- Security/Sniffs/Drupal7/XSSFormValueSniff.php | 4 ++-- .../Sniffs/Drupal7/XSSHTMLConstructSniff.php | 4 ++-- Security/Sniffs/Drupal7/XSSPThemeSniff.php | 4 ++-- Security/Sniffs/Drupal8/Utils.php | 3 ++- Security/Sniffs/Misc/BadCorsHeaderSniff.php | 4 ++-- Security/Sniffs/Misc/IncludeMismatchSniff.php | 2 +- Security/Sniffs/Symfony2/Utils.php | 4 ++-- Security/Sniffs/Utils.php | 20 ++++++++-------- Security/Sniffs/UtilsFactory.php | 4 ++-- Security/ruleset.xml | 3 +-- composer.json | 12 ++-------- example_base_ruleset.xml | 4 ++-- example_drupal7_ruleset.xml | 4 ++-- symlink.sh | 12 ---------- 44 files changed, 99 insertions(+), 125 deletions(-) rename Security/Sniffs/CVE/{20132110Sniff.php => CVE20132110Sniff.php} (89%) rename Security/Sniffs/CVE/{20134113Sniff.php => CVE20134113Sniff.php} (89%) delete mode 100644 symlink.sh diff --git a/Dockerfile b/Dockerfile index 0364eff..458d888 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,6 @@ RUN addgroup -S tool && adduser -S -G tool tool && \ # Install phpcs-security-audit RUN composer global require pheromone/phpcs-security-audit WORKDIR /tmp -RUN sh ./vendor/pheromone/phpcs-security-audit/symlink.sh # change user USER tool diff --git a/README.md b/README.md index 6d08f50..ebd5b0a 100644 --- a/README.md +++ b/README.md @@ -21,21 +21,16 @@ Install Requires [PHP CodeSniffer](http://pear.php.net/package/PHP_CodeSniffer/) version 3.x with PHP 5.4 or higher. -Because of the way PHP CodeSniffer works, you need to put the `Security/` folder from phpcs-security-audit in `/usr/share/php/PHP/CodeSniffer/Standards` or do a symlink to it. - -The easiest way to install is to git clone and use composer that will create the symlink for you: -``` -composer install -./vendor/bin/phpcs --standard=example_base_ruleset.xml tests.php -``` - -The package is also on [Packagist](https://packagist.org/packages/pheromone/phpcs-security-audit): +The easiest way to install is using [Composer](https://getcomposer.org/): ``` -composer require pheromone/phpcs-security-audit -sh vendor/pheromone/phpcs-security-audit/symlink.sh +composer require --dev pheromone/phpcs-security-audit ./vendor/bin/phpcs --standard=./vendor/pheromone/phpcs-security-audit/example_base_ruleset.xml ./vendor/pheromone/phpcs-security-audit/tests.php ``` +This will also install the [DealerDirect Composer PHPCS plugin](https://github.com/Dealerdirect/phpcodesniffer-composer-installer/) which will register the `Security` standard with PHP_CodeSniffer. + +It is also possible to install this based on a git clone. In that case, you will need to [register the package with PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Configuration-Options#setting-the-installed-standard-paths) yourself. + If you want to integrate it all with Jenkins, go see http://jenkins-php.org/ for extensive help. @@ -44,14 +39,14 @@ Usage Simply point to any XML ruleset file and a folder: ``` -phpcs --extensions=php,inc,lib,module,info --standard=example_base_ruleset.xml /your/php/files/ +phpcs --extensions=php,inc,lib,module,info --standard=./vendor/pheromone/phpcs-security-audit/example_base_ruleset.xml /your/php/files/ ``` Specifying extensions is important since for example PHP code is within .module files in Drupal. To have a quick example of output you can use the provided tests.php file: ``` -$ phpcs --extensions=php,inc,lib,module,info --standard=example_base_ruleset.xml tests.php +$ phpcs --extensions=php,inc,lib,module,info --standard=./vendor/pheromone/phpcs-security-audit/example_base_ruleset.xml ./vendor/pheromone/phpcs-security-audit/tests.php FILE: tests.php -------------------------------------------------------------------------------- @@ -85,7 +80,7 @@ These global parameters are used in many rules: * ParanoiaMode: set to 1 to add more checks. 0 for less. * CmsFramework: set to the name of a folder containings rules and Utils.php (such as Drupal7, Symfony2). -They can be setted in the XML files or in command line for permanent config with `--config-set` or at runtime with `--runtime-set`. Note that the XML override all CLI options so remove it if you want to use it. The CLI usage is as follow `phpcs --runtime-set ParanoiaMode 0 --extensions=php --standard=example_base_ruleset.xml tests.php`; +They can be set in a custom ruleset `phpcs.xml[.dist]` XML file or from the command line for permanent config with `--config-set` or at runtime with `--runtime-set`. Note that the XML override all CLI options so remove it if you want to use it. The CLI usage is as follow `phpcs --runtime-set ParanoiaMode 0 --extensions=php --standard=./vendor/pheromone/phpcs-security-audit/example_base_ruleset.xml tests.php`; In some case you can force the paranoia mode on or off with the parameter `forceParanoia` inside the XML rule. diff --git a/Security/Sniffs/BadFunctions/AssertsSniff.php b/Security/Sniffs/BadFunctions/AssertsSniff.php index f36949d..14d1836 100644 --- a/Security/Sniffs/BadFunctions/AssertsSniff.php +++ b/Security/Sniffs/BadFunctions/AssertsSniff.php @@ -1,5 +1,5 @@ getTokens(); - $utils = \PHPCS_SecurityAudit\Sniffs\UtilsFactory::getInstance(); + $utils = \PHPCS_SecurityAudit\Security\Sniffs\UtilsFactory::getInstance(); if ($tokens[$stackPtr]['content'] == 'assert') { $opener = $phpcsFile->findNext(T_OPEN_PARENTHESIS, $stackPtr, null, false, null, true); $closer = $tokens[$opener]['parenthesis_closer']; $s = $stackPtr + 1; - $s = $phpcsFile->findNext(array_merge(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHP_CodeSniffer\Util\Tokens::$bracketTokens, \PHPCS_SecurityAudit\Sniffs\Utils::$staticTokens, array(T_STRING_CONCAT)), $s, $closer, true); + $s = $phpcsFile->findNext(array_merge(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHP_CodeSniffer\Util\Tokens::$bracketTokens, \PHPCS_SecurityAudit\Security\Sniffs\Utils::$staticTokens, array(T_STRING_CONCAT)), $s, $closer, true); if ($s) { $msg = 'Assert eval function ' . $tokens[$stackPtr]['content'] . '() detected with dynamic parameter'; if ($utils::is_token_user_input($tokens[$s])) { diff --git a/Security/Sniffs/BadFunctions/BackticksSniff.php b/Security/Sniffs/BadFunctions/BackticksSniff.php index 60e9b14..a2bda9d 100644 --- a/Security/Sniffs/BadFunctions/BackticksSniff.php +++ b/Security/Sniffs/BadFunctions/BackticksSniff.php @@ -1,5 +1,5 @@ getTokens(); $closer = $phpcsFile->findNext(T_BACKTICK, $stackPtr + 1, null, false, null, true); if (!$closer) { diff --git a/Security/Sniffs/BadFunctions/CallbackFunctionsSniff.php b/Security/Sniffs/BadFunctions/CallbackFunctionsSniff.php index 70fdaf1..fcf30ba 100644 --- a/Security/Sniffs/BadFunctions/CallbackFunctionsSniff.php +++ b/Security/Sniffs/BadFunctions/CallbackFunctionsSniff.php @@ -1,5 +1,5 @@ getTokens(); - $utils = \PHPCS_SecurityAudit\Sniffs\UtilsFactory::getInstance(); + $utils = \PHPCS_SecurityAudit\Security\Sniffs\UtilsFactory::getInstance(); if (in_array($tokens[$stackPtr]['content'], $utils::getCallbackFunctions())) { $opener = $phpcsFile->findNext(T_OPEN_PARENTHESIS, $stackPtr, null, false, null, true); @@ -41,7 +41,7 @@ public function process(File $phpcsFile, $stackPtr) { } } $s = $phpcsFile->findNext(array_merge(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHP_CodeSniffer\Util\Tokens::$bracketTokens, - \PHPCS_SecurityAudit\Sniffs\Utils::$staticTokens, array(T_STRING_CONCAT)), $s, $closer, true); + \PHPCS_SecurityAudit\Security\Sniffs\Utils::$staticTokens, array(T_STRING_CONCAT)), $s, $closer, true); $msg = 'Function ' . $tokens[$stackPtr]['content'] . '() that supports callback detected'; if ($s) { if ($utils::is_token_user_input($tokens[$s])) { diff --git a/Security/Sniffs/BadFunctions/CryptoFunctionsSniff.php b/Security/Sniffs/BadFunctions/CryptoFunctionsSniff.php index 283318f..680bda4 100644 --- a/Security/Sniffs/BadFunctions/CryptoFunctionsSniff.php +++ b/Security/Sniffs/BadFunctions/CryptoFunctionsSniff.php @@ -1,5 +1,5 @@ getTokens(); if (preg_match("/^mcrypt_/", $tokens[$stackPtr]['content']) || in_array($tokens[$stackPtr]['content'], $utils::getCryptoFunctions())) { $tokstr = $tokens[$stackPtr]['content']; diff --git a/Security/Sniffs/BadFunctions/EasyRFISniff.php b/Security/Sniffs/BadFunctions/EasyRFISniff.php index d7cbf9b..143d380 100644 --- a/Security/Sniffs/BadFunctions/EasyRFISniff.php +++ b/Security/Sniffs/BadFunctions/EasyRFISniff.php @@ -1,5 +1,5 @@ getTokens(); $s = $phpcsFile->findNext(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, $stackPtr, null, true, null, true); @@ -37,7 +37,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\Sniffs\Utils::$staticTokens), $s + 1, $closer, true); + $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); 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/BadFunctions/EasyXSSSniff.php b/Security/Sniffs/BadFunctions/EasyXSSSniff.php index dd6bb00..c5b8646 100644 --- a/Security/Sniffs/BadFunctions/EasyXSSSniff.php +++ b/Security/Sniffs/BadFunctions/EasyXSSSniff.php @@ -1,5 +1,5 @@ forceParanoia >= 0) { $parano = $this->forceParanoia ? 1 : 0; } else { @@ -53,7 +53,7 @@ public function process(File $phpcsFile, $stackPtr) { $warn = false; while ($s) { - $s = $phpcsFile->findNext(array_merge(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHP_CodeSniffer\Util\Tokens::$bracketTokens, \PHPCS_SecurityAudit\Sniffs\Utils::$staticTokens), $s + 1, $closer, true); + $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); if ($s && $utils::is_token_user_input($tokens[$s])) { $phpcsFile->addError('Easy XSS detected because of direct user input with ' . $tokens[$s]['content'] . ' on ' . $tokens[$stackPtr]['content'], $s, 'EasyXSSerr'); } elseif ($s && $utils::is_XSS_mitigation($tokens[$s]['content'])) { diff --git a/Security/Sniffs/BadFunctions/ErrorHandlingSniff.php b/Security/Sniffs/BadFunctions/ErrorHandlingSniff.php index fe8a131..b8845ec 100644 --- a/Security/Sniffs/BadFunctions/ErrorHandlingSniff.php +++ b/Security/Sniffs/BadFunctions/ErrorHandlingSniff.php @@ -1,5 +1,5 @@ getTokens(); - $utils = new \PHPCS_SecurityAudit\Sniffs\Utils(); + $utils = new \PHPCS_SecurityAudit\Security\Sniffs\Utils(); if ($tokens[$stackPtr]['content'] == 'error_reporting') { $p = $utils::get_param_tokens($phpcsFile, $stackPtr, 1); diff --git a/Security/Sniffs/BadFunctions/FilesystemFunctionsSniff.php b/Security/Sniffs/BadFunctions/FilesystemFunctionsSniff.php index 67a28f4..0fa198f 100644 --- a/Security/Sniffs/BadFunctions/FilesystemFunctionsSniff.php +++ b/Security/Sniffs/BadFunctions/FilesystemFunctionsSniff.php @@ -1,5 +1,5 @@ getTokens(); if (in_array($tokens[$stackPtr]['content'], $utils::getFilesystemFunctions())) { @@ -48,7 +48,7 @@ public function process(File $phpcsFile, $stackPtr) { } $closer = $tokens[$opener]['parenthesis_closer']; - $s = $phpcsFile->findNext(array_merge(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHP_CodeSniffer\Util\Tokens::$bracketTokens, \PHPCS_SecurityAudit\Sniffs\Utils::$staticTokens), $s, $closer, true); + $s = $phpcsFile->findNext(array_merge(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHP_CodeSniffer\Util\Tokens::$bracketTokens, \PHPCS_SecurityAudit\Security\Sniffs\Utils::$staticTokens), $s, $closer, true); if ($s) { $msg = 'Filesystem function ' . $tokens[$stackPtr]['content'] . '() detected with dynamic parameter'; if ($utils::is_token_user_input($tokens[$s])) { diff --git a/Security/Sniffs/BadFunctions/FringeFunctionsSniff.php b/Security/Sniffs/BadFunctions/FringeFunctionsSniff.php index 28dcd58..d7764e9 100644 --- a/Security/Sniffs/BadFunctions/FringeFunctionsSniff.php +++ b/Security/Sniffs/BadFunctions/FringeFunctionsSniff.php @@ -1,5 +1,5 @@ getTokens(); - $utils = \PHPCS_SecurityAudit\Sniffs\UtilsFactory::getInstance(); + $utils = \PHPCS_SecurityAudit\Security\Sniffs\UtilsFactory::getInstance(); if (preg_match("/^ftp_/", $tokens[$stackPtr]['content'])) { $opener = $phpcsFile->findNext(T_OPEN_PARENTHESIS, $stackPtr, null, false, null, true); $closer = $tokens[$opener]['parenthesis_closer']; $s = $stackPtr + 1; - $s = $phpcsFile->findNext(array_merge(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHP_CodeSniffer\Util\Tokens::$bracketTokens, \PHPCS_SecurityAudit\Sniffs\Utils::$staticTokens, array(T_STRING_CONCAT)), $s, $closer, true); + $s = $phpcsFile->findNext(array_merge(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHP_CodeSniffer\Util\Tokens::$bracketTokens, \PHPCS_SecurityAudit\Security\Sniffs\Utils::$staticTokens, array(T_STRING_CONCAT)), $s, $closer, true); $msg = 'Unusual function ' . $tokens[$stackPtr]['content'] . '() detected'; if ($s) { if ($utils::is_token_user_input($tokens[$s])) { diff --git a/Security/Sniffs/BadFunctions/FunctionHandlingFunctionsSniff.php b/Security/Sniffs/BadFunctions/FunctionHandlingFunctionsSniff.php index efc412f..fda8635 100644 --- a/Security/Sniffs/BadFunctions/FunctionHandlingFunctionsSniff.php +++ b/Security/Sniffs/BadFunctions/FunctionHandlingFunctionsSniff.php @@ -1,5 +1,5 @@ getTokens(); if (in_array($tokens[$stackPtr]['content'], $utils::getFunctionhandlingFunctions())) { $opener = $phpcsFile->findNext(T_OPEN_PARENTHESIS, $stackPtr, null, false, null, true); $closer = $tokens[$opener]['parenthesis_closer']; $s = $stackPtr + 1; - $s = $phpcsFile->findNext(array_merge(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHP_CodeSniffer\Util\Tokens::$bracketTokens, \PHPCS_SecurityAudit\Sniffs\Utils::$staticTokens, array(T_STRING_CONCAT)), $s, $closer, true); + $s = $phpcsFile->findNext(array_merge(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHP_CodeSniffer\Util\Tokens::$bracketTokens, \PHPCS_SecurityAudit\Security\Sniffs\Utils::$staticTokens, array(T_STRING_CONCAT)), $s, $closer, true); if ($s) { $msg = 'Function handling function ' . $tokens[$stackPtr]['content'] . '() detected with dynamic parameter'; if ($utils::is_token_user_input($tokens[$s])) { diff --git a/Security/Sniffs/BadFunctions/MysqliSniff.php b/Security/Sniffs/BadFunctions/MysqliSniff.php index 8cd31d6..8394d99 100644 --- a/Security/Sniffs/BadFunctions/MysqliSniff.php +++ b/Security/Sniffs/BadFunctions/MysqliSniff.php @@ -1,5 +1,5 @@ getTokens(); // http://www.php.net/manual/en/book.mysqli.php @@ -66,7 +66,7 @@ public function process(File $phpcsFile, $stackPtr) { } elseif ($tokens[$stackPtr]['code'] == T_STRING && in_array($tokens[$stackPtr]['content'],array_map(function($v) { return 'mysqli_' . $v; }, $mysqlifunctions))) { // The first parameter is always the link $p2 = $utils::get_param_tokens($phpcsFile, $stackPtr, 2); - $s = $phpcsFile->findNext(array_merge(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHP_CodeSniffer\Util\Tokens::$bracketTokens, \PHPCS_SecurityAudit\Sniffs\Utils::$staticTokens, array(T_STRING_CONCAT)), $p2[0]['stackPtr'], end($p2)['stackPtr']+1, true); + $s = $phpcsFile->findNext(array_merge(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHP_CodeSniffer\Util\Tokens::$bracketTokens, \PHPCS_SecurityAudit\Security\Sniffs\Utils::$staticTokens, array(T_STRING_CONCAT)), $p2[0]['stackPtr'], end($p2)['stackPtr']+1, true); if ($s) { $msg = 'MYSQLi function ' . $tokens[$stackPtr]['content'] . '() detected with dynamic parameter '; if ($utils::is_token_user_input($tokens[$s])) { diff --git a/Security/Sniffs/BadFunctions/NoEvalsSniff.php b/Security/Sniffs/BadFunctions/NoEvalsSniff.php index e3bb56c..80e0b62 100644 --- a/Security/Sniffs/BadFunctions/NoEvalsSniff.php +++ b/Security/Sniffs/BadFunctions/NoEvalsSniff.php @@ -1,5 +1,5 @@ getTokens(); - $utils = \PHPCS_SecurityAudit\Sniffs\UtilsFactory::getInstance(); + $utils = \PHPCS_SecurityAudit\Security\Sniffs\UtilsFactory::getInstance(); if ($tokens[$stackPtr]['content'] == 'phpinfo') { $phpcsFile->addWarning('phpinfo() function detected', $stackPtr, 'WarnPhpinfo'); diff --git a/Security/Sniffs/BadFunctions/PregReplaceSniff.php b/Security/Sniffs/BadFunctions/PregReplaceSniff.php index 74665db..5cdb6ef 100644 --- a/Security/Sniffs/BadFunctions/PregReplaceSniff.php +++ b/Security/Sniffs/BadFunctions/PregReplaceSniff.php @@ -1,5 +1,5 @@ getTokens(); if ($tokens[$stackPtr]['content'] == 'preg_replace') { diff --git a/Security/Sniffs/BadFunctions/SQLFunctionsSniff.php b/Security/Sniffs/BadFunctions/SQLFunctionsSniff.php index 01a49d9..37f0361 100644 --- a/Security/Sniffs/BadFunctions/SQLFunctionsSniff.php +++ b/Security/Sniffs/BadFunctions/SQLFunctionsSniff.php @@ -1,5 +1,5 @@ getTokens(); // http://www.php.net/manual/en/book.mysql.php @@ -34,7 +34,7 @@ public function process(File $phpcsFile, $stackPtr) { $opener = $phpcsFile->findNext(T_OPEN_PARENTHESIS, $stackPtr, null, false, null, true); $closer = $tokens[$opener]['parenthesis_closer']; $s = $stackPtr + 1; - $s = $phpcsFile->findNext(array_merge(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHP_CodeSniffer\Util\Tokens::$bracketTokens, \PHPCS_SecurityAudit\Sniffs\Utils::$staticTokens, array(T_STRING_CONCAT)), $s, $closer, true); + $s = $phpcsFile->findNext(array_merge(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHP_CodeSniffer\Util\Tokens::$bracketTokens, \PHPCS_SecurityAudit\Security\Sniffs\Utils::$staticTokens, array(T_STRING_CONCAT)), $s, $closer, true); if ($s) { $msg = 'SQL function ' . $tokens[$stackPtr]['content'] . '() detected with dynamic parameter '; if ($utils::is_token_user_input($tokens[$s])) { diff --git a/Security/Sniffs/BadFunctions/SystemExecFunctionsSniff.php b/Security/Sniffs/BadFunctions/SystemExecFunctionsSniff.php index 842779b..3345ea6 100644 --- a/Security/Sniffs/BadFunctions/SystemExecFunctionsSniff.php +++ b/Security/Sniffs/BadFunctions/SystemExecFunctionsSniff.php @@ -1,5 +1,5 @@ getTokens(); if (in_array($tokens[$stackPtr]['content'], $utils::getSystemexecFunctions())) { @@ -39,7 +39,7 @@ public function process(File $phpcsFile, $stackPtr) { } $closer = $tokens[$opener]['parenthesis_closer']; $s = $stackPtr + 1; - $s = $phpcsFile->findNext(array_merge(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHP_CodeSniffer\Util\Tokens::$bracketTokens, \PHPCS_SecurityAudit\Sniffs\Utils::$staticTokens, array(T_STRING_CONCAT)), $s, $closer, true); + $s = $phpcsFile->findNext(array_merge(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHP_CodeSniffer\Util\Tokens::$bracketTokens, \PHPCS_SecurityAudit\Security\Sniffs\Utils::$staticTokens, array(T_STRING_CONCAT)), $s, $closer, true); if ($s) { $msg = 'System program execution function ' . $tokens[$stackPtr]['content'] . '() detected with dynamic parameter'; if ($utils::is_token_user_input($tokens[$s])) { diff --git a/Security/Sniffs/CVE/20132110Sniff.php b/Security/Sniffs/CVE/CVE20132110Sniff.php similarity index 89% rename from Security/Sniffs/CVE/20132110Sniff.php rename to Security/Sniffs/CVE/CVE20132110Sniff.php index 7b422bc..5966daf 100644 --- a/Security/Sniffs/CVE/20132110Sniff.php +++ b/Security/Sniffs/CVE/CVE20132110Sniff.php @@ -1,5 +1,5 @@ findNext(array_merge(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHPCS_SecurityAudit\Sniffs\Utils::$staticTokens), $s + 1, $closer, true); + $s = $phpcsFile->findNext(array_merge(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHPCS_SecurityAudit\Security\Sniffs\Utils::$staticTokens), $s + 1, $closer, true); if ($s) { $phpcsFile->addWarning('CVE-2013-2110 Heap-based buffer overflow in the php_quot_print_encode function in ext/standard/quot_print.c in PHP before 5.3.26 and 5.4.x before 5.4.16 allows remote attackers to cause a denial of service (application crash) or possibly have unspecified other impact via a crafted argument to the quoted_printable_encode function.', $stackPtr, 'CVE-2013-2110'); } diff --git a/Security/Sniffs/CVE/20134113Sniff.php b/Security/Sniffs/CVE/CVE20134113Sniff.php similarity index 89% rename from Security/Sniffs/CVE/20134113Sniff.php rename to Security/Sniffs/CVE/CVE20134113Sniff.php index f7beecf..9c7fc87 100644 --- a/Security/Sniffs/CVE/20134113Sniff.php +++ b/Security/Sniffs/CVE/CVE20134113Sniff.php @@ -1,5 +1,5 @@ findNext(array_merge(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHPCS_SecurityAudit\Sniffs\Utils::$staticTokens), $s + 1, $closer, true); + $s = $phpcsFile->findNext(array_merge(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHPCS_SecurityAudit\Security\Sniffs\Utils::$staticTokens), $s + 1, $closer, true); if ($s) { $phpcsFile->addWarning('CVE-2013-4113 ext/xml/xml.c in PHP before 5.3.27 does not properly consider parsing depth, which allows remote attackers to cause a denial of service (heap memory corruption) or possibly have unspecified other impact via a crafted document that is processed by the xml_parse_into_struct function.', $stackPtr, 'CVE-2013-4113'); if ($tokens[$s]['code'] == T_DOUBLE_QUOTED_STRING) { diff --git a/Security/Sniffs/Drupal7/AESModuleSniff.php b/Security/Sniffs/Drupal7/AESModuleSniff.php index 9b388b7..3d459cd 100644 --- a/Security/Sniffs/Drupal7/AESModuleSniff.php +++ b/Security/Sniffs/Drupal7/AESModuleSniff.php @@ -1,5 +1,5 @@ getFileName(); if (!preg_match('/\.info$/', $fileName)) return; - $utils = \PHPCS_SecurityAudit\Sniffs\UtilsFactory::getInstance('Drupal7'); + $utils = \PHPCS_SecurityAudit\Security\Sniffs\UtilsFactory::getInstance('Drupal7'); $tokens = $phpcsFile->getTokens(); $info = $utils->drupal_parse_info_format(file_get_contents($fileName)); diff --git a/Security/Sniffs/Drupal7/AdvisoriesCoreSniff.php b/Security/Sniffs/Drupal7/AdvisoriesCoreSniff.php index ca48821..a310205 100644 --- a/Security/Sniffs/Drupal7/AdvisoriesCoreSniff.php +++ b/Security/Sniffs/Drupal7/AdvisoriesCoreSniff.php @@ -1,5 +1,5 @@ getFileName(); if (!preg_match('/includes\/bootstrap\.inc$/', $fileName)) return; - $utils = \PHPCS_SecurityAudit\Sniffs\UtilsFactory::getInstance('Drupal7'); + $utils = \PHPCS_SecurityAudit\Security\Sniffs\UtilsFactory::getInstance('Drupal7'); $tokens = $phpcsFile->getTokens(); if ($tokens[$stackPtr]['content'] == "'VERSION'") { diff --git a/Security/Sniffs/Drupal7/CacheiSniff.php b/Security/Sniffs/Drupal7/CacheiSniff.php index 15075c4..e1cb94c 100644 --- a/Security/Sniffs/Drupal7/CacheiSniff.php +++ b/Security/Sniffs/Drupal7/CacheiSniff.php @@ -1,5 +1,5 @@ getTokens(); if ($tokens[$stackPtr]['content'] == "'#value'" || $tokens[$stackPtr]['content'] == '"#value"') { $closer = $phpcsFile->findNext(T_SEMICOLON, $stackPtr); diff --git a/Security/Sniffs/Drupal7/XSSHTMLConstructSniff.php b/Security/Sniffs/Drupal7/XSSHTMLConstructSniff.php index ef6107f..23359c1 100644 --- a/Security/Sniffs/Drupal7/XSSHTMLConstructSniff.php +++ b/Security/Sniffs/Drupal7/XSSHTMLConstructSniff.php @@ -1,5 +1,5 @@ getTokens(); if (preg_match('/<|>/', $tokens[$stackPtr]['content'])) { $end = $phpcsFile->findNext(T_SEMICOLON, $stackPtr + 1); diff --git a/Security/Sniffs/Drupal7/XSSPThemeSniff.php b/Security/Sniffs/Drupal7/XSSPThemeSniff.php index b21162c..35bd34a 100644 --- a/Security/Sniffs/Drupal7/XSSPThemeSniff.php +++ b/Security/Sniffs/Drupal7/XSSPThemeSniff.php @@ -1,5 +1,5 @@ getTokens(); if ($tokens[$stackPtr]['content'] == "'#theme'" || $tokens[$stackPtr]['content'] == '"#theme"') { diff --git a/Security/Sniffs/Drupal8/Utils.php b/Security/Sniffs/Drupal8/Utils.php index 44a6581..58fe4ba 100644 --- a/Security/Sniffs/Drupal8/Utils.php +++ b/Security/Sniffs/Drupal8/Utils.php @@ -1,6 +1,7 @@ getTokens(); if (stristr($tokens[$stackPtr]['content'], 'Access-Control-Allow-Origin')) { $closer = $phpcsFile->findNext(T_CLOSE_PARENTHESIS, $stackPtr); diff --git a/Security/Sniffs/Misc/IncludeMismatchSniff.php b/Security/Sniffs/Misc/IncludeMismatchSniff.php index 8b871b8..6d49c90 100644 --- a/Security/Sniffs/Misc/IncludeMismatchSniff.php +++ b/Security/Sniffs/Misc/IncludeMismatchSniff.php @@ -1,5 +1,5 @@ findNext(T_OPEN_PARENTHESIS, $stackPtr, null, false, null, true); $closer = $tokens[$opener]['parenthesis_closer']; $s = $opener + 1; - $s = $phpcsFile->findNext(array_merge(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHP_CodeSniffer\Util\Tokens::$bracketTokens, \PHPCS_SecurityAudit\Sniffs\Utils::$staticTokens, array(T_STRING_CONCAT)), $s, $closer, true); + $s = $phpcsFile->findNext(array_merge(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHP_CodeSniffer\Util\Tokens::$bracketTokens, \PHPCS_SecurityAudit\Security\Sniffs\Utils::$staticTokens, array(T_STRING_CONCAT)), $s, $closer, true); return $s; } diff --git a/Security/Sniffs/UtilsFactory.php b/Security/Sniffs/UtilsFactory.php index 8feda0c..828f03e 100644 --- a/Security/Sniffs/UtilsFactory.php +++ b/Security/Sniffs/UtilsFactory.php @@ -1,5 +1,5 @@ - + Security related coding standard. - PHPCS_SecurityAudit diff --git a/composer.json b/composer.json index 5bc96d2..ea69e5d 100644 --- a/composer.json +++ b/composer.json @@ -11,15 +11,7 @@ ], "require": { "php": ">=5.4", - "squizlabs/php_codesniffer": ">3.0" - }, - "autoload": { - "psr-4": { - "PHPCS_SecurityAudit\\": "Security/" - } - }, - "scripts": { - "post-install-cmd": "sh symlink.sh", - "post-update-cmd": "sh symlink.sh" + "squizlabs/php_codesniffer": "^3.0.2", + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.1 || ^0.5 || ^0.6" } } diff --git a/example_base_ruleset.xml b/example_base_ruleset.xml index 048dacc..4de57c5 100644 --- a/example_base_ruleset.xml +++ b/example_base_ruleset.xml @@ -41,8 +41,8 @@ - - + + diff --git a/example_drupal7_ruleset.xml b/example_drupal7_ruleset.xml index 414769a..dfd0921 100644 --- a/example_drupal7_ruleset.xml +++ b/example_drupal7_ruleset.xml @@ -37,8 +37,8 @@ - - + + diff --git a/symlink.sh b/symlink.sh deleted file mode 100644 index 6115d7f..0000000 --- a/symlink.sh +++ /dev/null @@ -1,12 +0,0 @@ -if [ ! -d "vendor/squizlabs/php_codesniffer/src/Standards/Security" ]; then - if [ -d "vendor/pheromone" ]; then - ln -s ../../../../pheromone/phpcs-security-audit/Security vendor/squizlabs/php_codesniffer/src/Standards/Security - else - ln -s ../../../../../Security vendor/squizlabs/php_codesniffer/src/Standards/Security - fi - if [ -n "$WINDIR" ]; then - echo "Looks like you're on Windows... folder copied." - else - echo "Symlink created." - fi -fi