Brian Wolff has submitted this change and it was merged. ( 
https://gerrit.wikimedia.org/r/395765 )

Change subject: Support installing via composer.
......................................................................


Support installing via composer.

Add scripts for easy running of test.

Change-Id: I315a0019f07130e0a09f14a856d1a7d5afb4d116
---
M README
M composer.json
A scripts/generic-config.php
A scripts/mw-config.php
A scripts/mwext-config.php
A scripts/mwext-fast-config.php
A scripts/mwext-slow-config.php
A scripts/seccheck-fast-mwext
A scripts/seccheck-generic
A scripts/seccheck-mw
A scripts/seccheck-mwext
A scripts/seccheck-slow-mwext
M src/TaintednessBaseVisitor.php
A tests/integration/unserialize/expectedResults.txt
A tests/integration/unserialize/test.php
15 files changed, 953 insertions(+), 5 deletions(-)



diff --git a/README b/README
index 7b7ca3a..6b6a965 100644
--- a/README
+++ b/README
@@ -20,9 +20,47 @@
 
 == How to use ==
 === via composer (recommended) ===
-[This doesn't actually work yet, once this plugin is in packagist]
+[This doesn't actually work yet, as package not in packagist]
 
-[TODO: fill this out]
+* Run (from the root directory of your project)
+
+$ composer require --dev wikimedia/security-check-plugin
+
+* For mediawiki extension, add the following to composer.json
+
+"scripts": {
+   "seccheck": "seccheck-mwext"
+   "seccheck-fast": "seccheck-fast-mwext"
+},
+
+* For a generic php project add
+
+"scripts": {
+   "seccheck": "seccheck-generic"
+},
+
+* For mediawiki core add
+
+"scripts": {
+   "seccheck": "seccheck-mw"
+},
+
+You can then run:
+$ composer seccheck
+
+to run the security check. Note that false positives are disabled by default.
+For mediawiki extensions, this assumes the extension is installed in the normal
+extension directory, and thus MediaWiki is in ../../. If this is not the case,
+then you need to specify the MW_INSTALL_PATH environment variable.
+
+This plugin also provides variants seccheck-fast-mwext (Doesn't analyse 
mediawiki
+core. May miss some stuff related to hooks) and seccheck-slow-mwext (Also 
analyzes vendor). seccheck-mwext will generally take about 3 minutes, where 
seccheck-fast-mwext
+takes only about half a minute.
+
+Additionally, if you want to do a really quick check, you can run the 
seccheck-generic script from a mediawiki extension which will ignore all 
MediaWiki stuff,
+making the check much faster (but misses many issues).
+
+If you want to do custom configuration (to say exclude some directories), 
follow the instructions below unser Manually.
 === Manually ===
 
 For MediaWiki mode, add MediaWikiSecurityCheckPlugin.php to the
@@ -53,7 +91,7 @@
 get Issue::SEVERITY_LOW (0). Issues that may result in server compromise
 (as opposed to just end user compromise) such as shell or sql injection are
 marked as Issue::SEVERITY_CRITICAL (10). SerializationInjection would normally
-be "critical" but its currently denoted as a severity of 4 because the check
+be "critical" but its currently denoted as a severity of NORMAL because the 
check
 seems to have a high false positive rate at the moment.
 
 You can use the -y command line option of phan to filter by severity.
diff --git a/composer.json b/composer.json
index 9431ad0..4e64eb7 100644
--- a/composer.json
+++ b/composer.json
@@ -1,9 +1,12 @@
 {
     "name": "wikimedia/security-check-plugin",
     "description": "A Phan plugin to do security checking",
+    "keywords": [ "php", "static", "analyzer", "phan", "security" ],
     "type": "library",
     "require": {
-        "etsy/phan": "0.8.0"
+        "etsy/phan": "0.8.0",
+        "php": "~7.0.0",
+        "ext-ast": "*"
     },
     "require-dev": {
         "mediawiki/mediawiki-codesniffer": "14.1.0",
@@ -20,6 +23,16 @@
        "phan-for-plugin": "./tests/run-phan-on-plugin.sh",
         "fix": "phpcbf"
     },
+    "bin": [
+        "scripts/seccheck-mwext",
+        "scripts/seccheck-slow-mwext",
+        "scripts/seccheck-fast-mwext",
+        "scripts/seccheck-mw",
+        "scripts/seccheck-generic"
+    ],
+    "support": {
+        "issues": "https://phabricator.wikimedia.org";
+    },
     "license": "GPLv2",
     "authors": [
         {
diff --git a/scripts/generic-config.php b/scripts/generic-config.php
new file mode 100644
index 0000000..91b14ec
--- /dev/null
+++ b/scripts/generic-config.php
@@ -0,0 +1,125 @@
+<?php
+
+// If xdebug is enabled, we need to increase the nesting level for phan
+ini_set( 'xdebug.max_nesting_level', 1000 );
+
+return [
+       /**
+        * A list of individual files to include in analysis
+        * with a path relative to the root directory of the
+        * project. directory_list won't find .inc files so
+        * we augment it here.
+        */
+       'file_list' => [],
+       'directory_list' => [
+               '.'
+       ],
+
+       /**
+        * A file list that defines files that will be excluded
+        * from parsing and analysis and will not be read at all.
+        *
+        * This is useful for excluding hopelessly unanalyzable
+        * files that can't be removed for whatever reason.
+        */
+       'exclude_file_list' => [],
+
+       /**
+        * A list of directories holding code that we want
+        * to parse, but not analyze. Also works for individual
+        * files.
+        */
+       "exclude_analysis_directory_list" => [
+               'vendor'
+       ],
+
+       /**
+        * Backwards Compatibility Checking. This is slow
+        * and expensive, but you should consider running
+        * it before upgrading your version of PHP to a
+        * new version that has backward compatibility
+        * breaks.
+        */
+       'backward_compatibility_checks' => false,
+
+       /**
+        * A set of fully qualified class-names for which
+        * a call to parent::__construct() is required
+        */
+       'parent_constructor_required' => [
+       ],
+
+       'quick_mode' => false,
+
+       'should_visit_all_nodes' => true,
+
+       'analyze_signature_compatibility' => false,
+
+       /**
+        * Do not emit false positives
+        */
+       "minimum_severity" => 1,
+       'allow_missing_properties' => false,
+       'null_casts_as_any_type' => true,
+       'scalar_implicit_cast' => true,
+       'ignore_undeclared_variables_in_global_scope' => true,
+       'dead_code_detection' => false,
+       'dead_code_detection_prefer_false_negative' => true,
+       'read_type_annotations' => true,
+       'disable_suppression' => false,
+       'dump_ast' => false,
+       'dump_signatures_file' => null,
+       'expand_file_list' => false,
+       // Include a progress bar in the output
+       'progress_bar' => true,
+       'progress_bar_sample_rate' => 0.005,
+
+       /**
+        * The number of processes to fork off during the analysis
+        * phase.
+        */
+       'processes' => 1,
+
+       /** We use the whitelist instead */
+       'suppress_issue_types' => [],
+
+       /**
+        * If empty, no filter against issues types will be applied.
+        * If this white-list is non-empty, only issues within the list
+        * will be emitted by Phan.
+        */
+       'whitelist_issue_types' => [
+               'SecurityCheckMulti',
+               'SecurityCheck-XSS',
+               'SecurityCheck-SQLInjection',
+               'SecurityCheck-ShellInjection',
+               'SecurityCheck-CUSTOM1',
+               'SecurityCheck-CUSTOM2',
+               'SecurityCheck-OTHER',
+               // Rely on severity setting to blacklist false positive.
+               'SecurityCheck-LikelyFalsePositive',
+       ],
+
+       /**
+        * Override to hardcode existence and types of (non-builtin) globals in 
the global scope.
+        * Class names must be prefixed with '\\'.
+        * (E.g. ['_FOO' => '\\FooClass', 'page' => '\\PageClass', 'userId' => 
'int'])
+        */
+       'globals_type_map' => [
+               // 'IP' => 'string',
+       ],
+
+       // Emit issue messages with markdown formatting
+       'markdown_issue_messages' => false,
+
+       /**
+        * Enable or disable support for generic templated
+        * class types.
+        */
+       'generic_types_enabled' => true,
+
+       // A list of plugin files to execute
+       'plugins' => [
+               __DIR__ . '/../GenericSecurityCheckPlugin.php',
+       ],
+];
diff --git a/scripts/mw-config.php b/scripts/mw-config.php
new file mode 100644
index 0000000..89f79d1
--- /dev/null
+++ b/scripts/mw-config.php
@@ -0,0 +1,162 @@
+<?php
+
+// If xdebug is enabled, we need to increase the nesting level for phan
+ini_set( 'xdebug.max_nesting_level', 1000 );
+
+/**
+ * This is based on MW's phan config.php.
+ */
+return [
+       /**
+        * A list of individual files to include in analysis
+        * with a path relative to the root directory of the
+        * project. directory_list won't find .inc files so
+        * we augment it here.
+        */
+       'file_list' => array_merge(
+               function_exists( 'register_postsend_function' ) ? [] : [ 
'tests/phan/stubs/hhvm.php' ],
+               function_exists( 'wikidiff2_do_diff' ) ? [] : [ 
'tests/phan/stubs/wikidiff.php' ],
+               function_exists( 'tideways_enable' ) ? [] : [ 
'tests/phan/stubs/tideways.php' ],
+               class_exists( PEAR::class ) ? [] : [ 
'tests/phan/stubs/mail.php' ],
+               class_exists( Memcached::class ) ? [] : [ 
'tests/phan/stubs/memcached.php' ],
+               [
+                       'maintenance/7zip.inc',
+                       'maintenance/backup.inc',
+                       'maintenance/backupPrefetch.inc',
+                       'maintenance/cleanupTable.inc',
+                       'maintenance/CodeCleanerGlobalsPass.inc',
+                       'maintenance/commandLine.inc',
+                       'maintenance/importImages.inc',
+                       'maintenance/sqlite.inc',
+                       'maintenance/userDupes.inc',
+                       'maintenance/userOptions.inc',
+                       'maintenance/language/checkLanguage.inc',
+                       'maintenance/language/languages.inc',
+               ]
+       ),
+
+       'directory_list' => [
+               'includes/',
+               'languages/',
+               'maintenance/',
+               'mw-config/',
+               'resources/',
+               'skins/',
+               'vendor/',
+       ],
+
+       /**
+        * A file list that defines files that will be excluded
+        * from parsing and analysis and will not be read at all.
+        *
+        * This is useful for excluding hopelessly unanalyzable
+        * files that can't be removed for whatever reason.
+        */
+       'exclude_file_list' => [],
+
+       /**
+        * A list of directories holding code that we want
+        * to parse, but not analyze. Also works for individual
+        * files.
+        */
+       "exclude_analysis_directory_list" => [
+               'vendor/',
+               'tests/phan/stubs/',
+               // The referenced classes are not available in vendor, only when
+               // included from composer.
+               'includes/composer/',
+               'maintenance/language/',
+               'includes/libs/jsminplus.php',
+               'skins/',
+       ],
+
+       /**
+        * Backwards Compatibility Checking. This is slow
+        * and expensive, but you should consider running
+        * it before upgrading your version of PHP to a
+        * new version that has backward compatibility
+        * breaks.
+        */
+       'backward_compatibility_checks' => false,
+
+       /**
+        * A set of fully qualified class-names for which
+        * a call to parent::__construct() is required
+        */
+       'parent_constructor_required' => [
+       ],
+
+       'quick_mode' => false,
+
+       'should_visit_all_nodes' => true,
+
+       'analyze_signature_compatibility' => false,
+
+       /**
+        * Do not emit false positives
+        */
+       "minimum_severity" => 1,
+       'allow_missing_properties' => false,
+       'null_casts_as_any_type' => true,
+       'scalar_implicit_cast' => true,
+       'ignore_undeclared_variables_in_global_scope' => true,
+       'dead_code_detection' => false,
+       'dead_code_detection_prefer_false_negative' => true,
+       'read_type_annotations' => true,
+       'disable_suppression' => false,
+       'dump_ast' => false,
+       'dump_signatures_file' => null,
+       'expand_file_list' => false,
+       // Include a progress bar in the output
+       'progress_bar' => true,
+       'progress_bar_sample_rate' => 0.005,
+
+       /**
+        * The number of processes to fork off during the analysis
+        * phase.
+        */
+       'processes' => 1,
+
+       /** We use the whitelist instead */
+       'suppress_issue_types' => [],
+
+       /**
+        * If empty, no filter against issues types will be applied.
+        * If this white-list is non-empty, only issues within the list
+        * will be emitted by Phan.
+        */
+       'whitelist_issue_types' => [
+               'SecurityCheckMulti',
+               'SecurityCheck-XSS',
+               'SecurityCheck-SQLInjection',
+               'SecurityCheck-ShellInjection',
+               'SecurityCheck-CUSTOM1',
+               'SecurityCheck-CUSTOM2',
+               'SecurityCheck-OTHER',
+               // Rely on severity setting to blacklist false positive.
+               'SecurityCheck-LikelyFalsePositive',
+       ],
+
+       /**
+        * Override to hardcode existence and types of (non-builtin) globals in 
the global scope.
+        * Class names must be prefixed with '\\'.
+        * (E.g. ['_FOO' => '\\FooClass', 'page' => '\\PageClass', 'userId' => 
'int'])
+        */
+       'globals_type_map' => [
+               // 'IP' => 'string',
+       ],
+
+       // Emit issue messages with markdown formatting
+       'markdown_issue_messages' => false,
+
+       /**
+        * Enable or disable support for generic templated
+        * class types.
+        */
+       'generic_types_enabled' => true,
+
+       // A list of plugin files to execute
+       'plugins' => [
+               __DIR__ . '/../MediaWikiSecurityCheckPlugin.php',
+       ],
+];
diff --git a/scripts/mwext-config.php b/scripts/mwext-config.php
new file mode 100644
index 0000000..1df6fe0
--- /dev/null
+++ b/scripts/mwext-config.php
@@ -0,0 +1,169 @@
+<?php
+
+// If xdebug is enabled, we need to increase the nesting level for phan
+ini_set( 'xdebug.max_nesting_level', 1000 );
+
+$IP = getenv( 'MW_INSTALL_PATH' ) ?: '../../';
+
+/**
+ * This is based on MW's phan config.php.
+ */
+$MWExtConfig = [
+       /**
+        * A list of individual files to include in analysis
+        * with a path relative to the root directory of the
+        * project. directory_list won't find .inc files so
+        * we augment it here.
+        */
+       'file_list' => array_merge(
+               function_exists( 'register_postsend_function' ) ? [] : [ $IP . 
'tests/phan/stubs/hhvm.php' ],
+               function_exists( 'wikidiff2_do_diff' ) ? [] : [ $IP . 
'tests/phan/stubs/wikidiff.php' ],
+               function_exists( 'tideways_enable' ) ? [] : [ $IP . 
'tests/phan/stubs/tideways.php' ],
+               class_exists( PEAR::class ) ? [] : [ $IP . 
'tests/phan/stubs/mail.php' ],
+               class_exists( Memcached::class ) ? [] : [ $IP . 
'tests/phan/stubs/memcached.php' ],
+               [
+                       $IP . 'maintenance/7zip.inc',
+                       $IP . 'maintenance/backup.inc',
+                       $IP . 'maintenance/backupPrefetch.inc',
+                       $IP . 'maintenance/cleanupTable.inc',
+                       $IP . 'maintenance/CodeCleanerGlobalsPass.inc',
+                       $IP . 'maintenance/commandLine.inc',
+                       $IP . 'maintenance/importImages.inc',
+                       $IP . 'maintenance/sqlite.inc',
+                       $IP . 'maintenance/userDupes.inc',
+                       $IP . 'maintenance/userOptions.inc',
+                       $IP . 'maintenance/language/checkLanguage.inc',
+                       $IP . 'maintenance/language/languages.inc',
+               ]
+       ),
+
+       'directory_list' => [
+               $IP . 'includes/',
+               $IP . 'languages/',
+               $IP . 'maintenance/',
+               $IP . 'mw-config/',
+               $IP . 'resources/',
+               $IP . 'skins/',
+               $IP . 'vendor/',
+               '.'
+       ],
+
+       /**
+        * A file list that defines files that will be excluded
+        * from parsing and analysis and will not be read at all.
+        *
+        * This is useful for excluding hopelessly unanalyzable
+        * files that can't be removed for whatever reason.
+        */
+       'exclude_file_list' => [],
+
+       /**
+        * A list of directories holding code that we want
+        * to parse, but not analyze. Also works for individual
+        * files.
+        */
+       "exclude_analysis_directory_list" => [
+               $IP . 'vendor/',
+               $IP . 'tests/phan/stubs/',
+               // The referenced classes are not available in vendor, only when
+               // included from composer.
+               $IP . 'includes/composer/',
+               $IP . 'maintenance/language/',
+               $IP . 'includes/libs/jsminplus.php',
+               $IP . 'skins/',
+               'vendor'
+       ],
+
+       /**
+        * Backwards Compatibility Checking. This is slow
+        * and expensive, but you should consider running
+        * it before upgrading your version of PHP to a
+        * new version that has backward compatibility
+        * breaks.
+        */
+       'backward_compatibility_checks' => false,
+
+       /**
+        * A set of fully qualified class-names for which
+        * a call to parent::__construct() is required
+        */
+       'parent_constructor_required' => [
+       ],
+
+       'quick_mode' => false,
+
+       'should_visit_all_nodes' => true,
+
+       'analyze_signature_compatibility' => false,
+
+       /**
+        * Do not emit false positives
+        */
+       "minimum_severity" => 1,
+       'allow_missing_properties' => false,
+       'null_casts_as_any_type' => true,
+       'scalar_implicit_cast' => true,
+       'ignore_undeclared_variables_in_global_scope' => true,
+       'dead_code_detection' => false,
+       'dead_code_detection_prefer_false_negative' => true,
+       'read_type_annotations' => true,
+       'disable_suppression' => false,
+       'dump_ast' => false,
+       'dump_signatures_file' => null,
+       'expand_file_list' => false,
+       // Include a progress bar in the output
+       'progress_bar' => true,
+       'progress_bar_sample_rate' => 0.005,
+
+       /**
+        * The number of processes to fork off during the analysis
+        * phase.
+        */
+       'processes' => 1,
+
+       /** We use the whitelist instead */
+       'suppress_issue_types' => [],
+
+       /**
+        * If empty, no filter against issues types will be applied.
+        * If this white-list is non-empty, only issues within the list
+        * will be emitted by Phan.
+        */
+       'whitelist_issue_types' => [
+               'SecurityCheckMulti',
+               'SecurityCheck-XSS',
+               'SecurityCheck-SQLInjection',
+               'SecurityCheck-ShellInjection',
+               'SecurityCheck-CUSTOM1',
+               'SecurityCheck-CUSTOM2',
+               'SecurityCheck-OTHER',
+               // Rely on severity setting to blacklist false positive.
+               'SecurityCheck-LikelyFalsePositive',
+       ],
+
+       /**
+        * Override to hardcode existence and types of (non-builtin) globals in 
the global scope.
+        * Class names must be prefixed with '\\'.
+        * (E.g. ['_FOO' => '\\FooClass', 'page' => '\\PageClass', 'userId' => 
'int'])
+        */
+       'globals_type_map' => [
+               // 'IP' => 'string',
+       ],
+
+       // Emit issue messages with markdown formatting
+       'markdown_issue_messages' => false,
+
+       /**
+        * Enable or disable support for generic templated
+        * class types.
+        */
+       'generic_types_enabled' => true,
+
+       // A list of plugin files to execute
+       'plugins' => [
+               __DIR__ . '/../MediaWikiSecurityCheckPlugin.php',
+       ],
+];
+
+unset( $IP );
+return $MWExtConfig;
diff --git a/scripts/mwext-fast-config.php b/scripts/mwext-fast-config.php
new file mode 100644
index 0000000..79590a4
--- /dev/null
+++ b/scripts/mwext-fast-config.php
@@ -0,0 +1,164 @@
+<?php
+
+// If xdebug is enabled, we need to increase the nesting level for phan
+ini_set( 'xdebug.max_nesting_level', 1000 );
+
+$IP = getenv( 'MW_INSTALL_PATH' ) ?: '../../';
+
+/**
+ * Fast mode excludes MW from analysis. May miss some stuff with hooks.
+ *
+ * This is based on MW's phan config.php.
+ */
+$MWExtConfig = [
+       /**
+        * A list of individual files to include in analysis
+        * with a path relative to the root directory of the
+        * project. directory_list won't find .inc files so
+        * we augment it here.
+        */
+       'file_list' => array_merge(
+               function_exists( 'register_postsend_function' ) ? [] : [ $IP . 
'tests/phan/stubs/hhvm.php' ],
+               function_exists( 'wikidiff2_do_diff' ) ? [] : [ $IP . 
'tests/phan/stubs/wikidiff.php' ],
+               function_exists( 'tideways_enable' ) ? [] : [ $IP . 
'tests/phan/stubs/tideways.php' ],
+               class_exists( PEAR::class ) ? [] : [ $IP . 
'tests/phan/stubs/mail.php' ],
+               class_exists( Memcached::class ) ? [] : [ $IP . 
'tests/phan/stubs/memcached.php' ],
+               [
+                       $IP . 'maintenance/7zip.inc',
+                       $IP . 'maintenance/backup.inc',
+                       $IP . 'maintenance/backupPrefetch.inc',
+                       $IP . 'maintenance/cleanupTable.inc',
+                       $IP . 'maintenance/CodeCleanerGlobalsPass.inc',
+                       $IP . 'maintenance/commandLine.inc',
+                       $IP . 'maintenance/importImages.inc',
+                       $IP . 'maintenance/sqlite.inc',
+                       $IP . 'maintenance/userDupes.inc',
+                       $IP . 'maintenance/userOptions.inc',
+                       $IP . 'maintenance/language/checkLanguage.inc',
+                       $IP . 'maintenance/language/languages.inc',
+               ]
+       ),
+
+       'directory_list' => [
+               $IP . 'includes/',
+               $IP . 'languages/',
+               $IP . 'maintenance/',
+               $IP . 'mw-config/',
+               $IP . 'resources/',
+               $IP . 'skins/',
+               $IP . 'vendor/',
+               '.'
+       ],
+
+       /**
+        * A file list that defines files that will be excluded
+        * from parsing and analysis and will not be read at all.
+        *
+        * This is useful for excluding hopelessly unanalyzable
+        * files that can't be removed for whatever reason.
+        */
+       'exclude_file_list' => [],
+
+       /**
+        * A list of directories holding code that we want
+        * to parse, but not analyze. Also works for individual
+        * files.
+        */
+       "exclude_analysis_directory_list" => [
+               'vendor/',
+               $IP,
+       ],
+
+       /**
+        * Backwards Compatibility Checking. This is slow
+        * and expensive, but you should consider running
+        * it before upgrading your version of PHP to a
+        * new version that has backward compatibility
+        * breaks.
+        */
+       'backward_compatibility_checks' => false,
+
+       /**
+        * A set of fully qualified class-names for which
+        * a call to parent::__construct() is required
+        */
+       'parent_constructor_required' => [
+       ],
+
+       'quick_mode' => false,
+
+       'should_visit_all_nodes' => true,
+
+       'analyze_signature_compatibility' => false,
+
+       /**
+        * Do not emit false positives
+        */
+       "minimum_severity" => 1,
+       'allow_missing_properties' => false,
+       'null_casts_as_any_type' => true,
+       'scalar_implicit_cast' => true,
+       'ignore_undeclared_variables_in_global_scope' => true,
+       'dead_code_detection' => false,
+       'dead_code_detection_prefer_false_negative' => true,
+       'read_type_annotations' => true,
+       'disable_suppression' => false,
+       'dump_ast' => false,
+       'dump_signatures_file' => null,
+       'expand_file_list' => false,
+       // Include a progress bar in the output
+       'progress_bar' => true,
+       'progress_bar_sample_rate' => 0.005,
+
+       /**
+        * The number of processes to fork off during the analysis
+        * phase.
+        */
+       'processes' => 1,
+
+       /** We use the whitelist instead */
+       'suppress_issue_types' => [],
+
+       /**
+        * If empty, no filter against issues types will be applied.
+        * If this white-list is non-empty, only issues within the list
+        * will be emitted by Phan.
+        */
+       'whitelist_issue_types' => [
+               'SecurityCheckMulti',
+               'SecurityCheck-XSS',
+               'SecurityCheck-SQLInjection',
+               'SecurityCheck-ShellInjection',
+               'SecurityCheck-CUSTOM1',
+               'SecurityCheck-CUSTOM2',
+               'SecurityCheck-OTHER',
+               // Rely on severity setting to blacklist false positive.
+               'SecurityCheck-LikelyFalsePositive',
+       ],
+
+       /**
+        * Override to hardcode existence and types of (non-builtin) globals in 
the global scope.
+        * Class names must be prefixed with '\\'.
+        * (E.g. ['_FOO' => '\\FooClass', 'page' => '\\PageClass', 'userId' => 
'int'])
+        */
+       'globals_type_map' => [
+               // 'IP' => 'string',
+       ],
+
+       // Emit issue messages with markdown formatting
+       'markdown_issue_messages' => false,
+
+       /**
+        * Enable or disable support for generic templated
+        * class types.
+        */
+       'generic_types_enabled' => true,
+
+       // A list of plugin files to execute
+       'plugins' => [
+               __DIR__ . '/../MediaWikiSecurityCheckPlugin.php',
+       ],
+];
+
+unset( $IP );
+return $MWExtConfig;
diff --git a/scripts/mwext-slow-config.php b/scripts/mwext-slow-config.php
new file mode 100644
index 0000000..af59410
--- /dev/null
+++ b/scripts/mwext-slow-config.php
@@ -0,0 +1,163 @@
+<?php
+
+// If xdebug is enabled, we need to increase the nesting level for phan
+ini_set( 'xdebug.max_nesting_level', 1000 );
+
+$IP = getenv( 'MW_INSTALL_PATH' ) ?: '../../';
+
+/**
+ * Slow config. Include vendor in the analysis.
+ *
+ * This is based on MW's phan config.php.
+ */
+$MWExtConfig = [
+       /**
+        * A list of individual files to include in analysis
+        * with a path relative to the root directory of the
+        * project. directory_list won't find .inc files so
+        * we augment it here.
+        */
+       'file_list' => array_merge(
+               function_exists( 'register_postsend_function' ) ? [] : [ $IP . 
'tests/phan/stubs/hhvm.php' ],
+               function_exists( 'wikidiff2_do_diff' ) ? [] : [ $IP . 
'tests/phan/stubs/wikidiff.php' ],
+               function_exists( 'tideways_enable' ) ? [] : [ $IP . 
'tests/phan/stubs/tideways.php' ],
+               class_exists( PEAR::class ) ? [] : [ $IP . 
'tests/phan/stubs/mail.php' ],
+               class_exists( Memcached::class ) ? [] : [ $IP . 
'tests/phan/stubs/memcached.php' ],
+               [
+                       $IP . 'maintenance/7zip.inc',
+                       $IP . 'maintenance/backup.inc',
+                       $IP . 'maintenance/backupPrefetch.inc',
+                       $IP . 'maintenance/cleanupTable.inc',
+                       $IP . 'maintenance/CodeCleanerGlobalsPass.inc',
+                       $IP . 'maintenance/commandLine.inc',
+                       $IP . 'maintenance/importImages.inc',
+                       $IP . 'maintenance/sqlite.inc',
+                       $IP . 'maintenance/userDupes.inc',
+                       $IP . 'maintenance/userOptions.inc',
+                       $IP . 'maintenance/language/checkLanguage.inc',
+                       $IP . 'maintenance/language/languages.inc',
+               ]
+       ),
+
+       'directory_list' => [
+               $IP . 'includes/',
+               $IP . 'languages/',
+               $IP . 'maintenance/',
+               $IP . 'mw-config/',
+               $IP . 'resources/',
+               $IP . 'skins/',
+               $IP . 'vendor/',
+               '.'
+       ],
+
+       /**
+        * A file list that defines files that will be excluded
+        * from parsing and analysis and will not be read at all.
+        *
+        * This is useful for excluding hopelessly unanalyzable
+        * files that can't be removed for whatever reason.
+        */
+       'exclude_file_list' => [],
+
+       /**
+        * A list of directories holding code that we want
+        * to parse, but not analyze. Also works for individual
+        * files.
+        */
+       "exclude_analysis_directory_list" => [
+               'vendor/wikimedia/security-check-plugin'
+       ],
+
+       /**
+        * Backwards Compatibility Checking. This is slow
+        * and expensive, but you should consider running
+        * it before upgrading your version of PHP to a
+        * new version that has backward compatibility
+        * breaks.
+        */
+       'backward_compatibility_checks' => false,
+
+       /**
+        * A set of fully qualified class-names for which
+        * a call to parent::__construct() is required
+        */
+       'parent_constructor_required' => [
+       ],
+
+       'quick_mode' => false,
+
+       'should_visit_all_nodes' => true,
+
+       'analyze_signature_compatibility' => false,
+
+       /**
+        * Do not emit false positives
+        */
+       "minimum_severity" => 1,
+       'allow_missing_properties' => false,
+       'null_casts_as_any_type' => true,
+       'scalar_implicit_cast' => true,
+       'ignore_undeclared_variables_in_global_scope' => true,
+       'dead_code_detection' => false,
+       'dead_code_detection_prefer_false_negative' => true,
+       'read_type_annotations' => true,
+       'disable_suppression' => false,
+       'dump_ast' => false,
+       'dump_signatures_file' => null,
+       'expand_file_list' => false,
+       // Include a progress bar in the output
+       'progress_bar' => true,
+       'progress_bar_sample_rate' => 0.005,
+
+       /**
+        * The number of processes to fork off during the analysis
+        * phase.
+        */
+       'processes' => 1,
+
+       /** We use the whitelist instead */
+       'suppress_issue_types' => [],
+
+       /**
+        * If empty, no filter against issues types will be applied.
+        * If this white-list is non-empty, only issues within the list
+        * will be emitted by Phan.
+        */
+       'whitelist_issue_types' => [
+               'SecurityCheckMulti',
+               'SecurityCheck-XSS',
+               'SecurityCheck-SQLInjection',
+               'SecurityCheck-ShellInjection',
+               'SecurityCheck-CUSTOM1',
+               'SecurityCheck-CUSTOM2',
+               'SecurityCheck-OTHER',
+               // Rely on severity setting to blacklist false positive.
+               'SecurityCheck-LikelyFalsePositive',
+       ],
+
+       /**
+        * Override to hardcode existence and types of (non-builtin) globals in 
the global scope.
+        * Class names must be prefixed with '\\'.
+        * (E.g. ['_FOO' => '\\FooClass', 'page' => '\\PageClass', 'userId' => 
'int'])
+        */
+       'globals_type_map' => [
+               // 'IP' => 'string',
+       ],
+
+       // Emit issue messages with markdown formatting
+       'markdown_issue_messages' => false,
+
+       /**
+        * Enable or disable support for generic templated
+        * class types.
+        */
+       'generic_types_enabled' => true,
+
+       // A list of plugin files to execute
+       'plugins' => [
+               __DIR__ . '/../MediaWikiSecurityCheckPlugin.php',
+       ],
+];
+
+unset( $IP );
+return $MWExtConfig;
diff --git a/scripts/seccheck-fast-mwext b/scripts/seccheck-fast-mwext
new file mode 100755
index 0000000..7083cec
--- /dev/null
+++ b/scripts/seccheck-fast-mwext
@@ -0,0 +1,22 @@
+#!/bin/sh
+#
+# Run the security check test on the extension
+# in the current directory.
+#
+# This script is meant to be run via composer
+#
+# Assumes that either MediaWiki is installed in ../../
+# or the user has set MW_INSTALL_PATH environment variable.
+
+php=`which php7.0`
+if [ "$?" != 0 ]
+then
+       php=`which php`
+fi
+
+$php vendor/etsy/phan/phan \
+       -d . \
+       -k vendor/wikimedia/security-check-plugin/scripts/mwext-fast-config.php 
\
+       --output "php://stdout" "$@"
+
+exit $?
diff --git a/scripts/seccheck-generic b/scripts/seccheck-generic
new file mode 100755
index 0000000..9a73dbf
--- /dev/null
+++ b/scripts/seccheck-generic
@@ -0,0 +1,22 @@
+#!/bin/sh
+#
+# Run the security check test on the extension
+# in the current directory.
+#
+# This script is meant to be run via composer
+#
+# Assumes that either MediaWiki is installed in ../../
+# or the user has set MW_INSTALL_PATH environment variable.
+
+php=`which php7.0`
+if [ "$?" != 0 ]
+then
+       php=`which php`
+fi
+
+$php vendor/etsy/phan/phan \
+       -d . \
+       -k vendor/wikimedia/security-check-plugin/scripts/generic-config.php \
+       --output "php://stdout" "$@"
+
+exit $?
diff --git a/scripts/seccheck-mw b/scripts/seccheck-mw
new file mode 100755
index 0000000..ddc8c4f
--- /dev/null
+++ b/scripts/seccheck-mw
@@ -0,0 +1,22 @@
+#!/bin/sh
+#
+# Run the security check test on the extension
+# in the current directory.
+#
+# This script is meant to be run via composer
+#
+# Assumes that either MediaWiki is installed in ../../
+# or the user has set MW_INSTALL_PATH environment variable.
+
+php=`which php7.0`
+if [ "$?" != 0 ]
+then
+       php=`which php`
+fi
+
+$php vendor/etsy/phan/phan \
+       -d . \
+       -k vendor/wikimedia/security-check-plugin/scripts/mw-config.php \
+       --output "php://stdout" "$@"
+
+exit $?
diff --git a/scripts/seccheck-mwext b/scripts/seccheck-mwext
new file mode 100755
index 0000000..0aca7b4
--- /dev/null
+++ b/scripts/seccheck-mwext
@@ -0,0 +1,22 @@
+#!/bin/sh
+#
+# Run the security check test on the extension
+# in the current directory.
+#
+# This script is meant to be run via composer
+#
+# Assumes that either MediaWiki is installed in ../../
+# or the user has set MW_INSTALL_PATH environment variable.
+
+php=`which php7.0`
+if [ "$?" != 0 ]
+then
+       php=`which php`
+fi
+
+$php vendor/etsy/phan/phan \
+       -d . \
+       -k vendor/wikimedia/security-check-plugin/scripts/mwext-config.php \
+       --output "php://stdout" "$@" | grep '\(^\./\| \./\)'
+
+exit $?
diff --git a/scripts/seccheck-slow-mwext b/scripts/seccheck-slow-mwext
new file mode 100755
index 0000000..4714787
--- /dev/null
+++ b/scripts/seccheck-slow-mwext
@@ -0,0 +1,22 @@
+#!/bin/sh
+#
+# Run the security check test on the extension
+# in the current directory.
+#
+# This script is meant to be run via composer
+#
+# Assumes that either MediaWiki is installed in ../../
+# or the user has set MW_INSTALL_PATH environment variable.
+
+php=`which php7.0`
+if [ "$?" != 0 ]
+then
+       php=`which php`
+fi
+
+$php vendor/etsy/phan/phan \
+       -d . \
+       -k vendor/wikimedia/security-check-plugin/scripts/mwext-slow-config.php 
\
+       --output "php://stdout" "$@" | grep '\(^\./\| \./\)'
+
+exit $?
diff --git a/src/TaintednessBaseVisitor.php b/src/TaintednessBaseVisitor.php
index 340cad2..fa8df1d 100644
--- a/src/TaintednessBaseVisitor.php
+++ b/src/TaintednessBaseVisitor.php
@@ -1443,7 +1443,7 @@
                        $issueType = 'SecurityCheck-PHPSerializeInjection';
                        // For now this is low because it seems to have a lot
                        // of false positives.
-                       $severity = 4;
+                       // $severity = 4;
                } elseif (
                        $combinedTaint === SecurityCheckPlugin::CUSTOM1_TAINT
                ) {
diff --git a/tests/integration/unserialize/expectedResults.txt 
b/tests/integration/unserialize/expectedResults.txt
new file mode 100644
index 0000000..3e1c758
--- /dev/null
+++ b/tests/integration/unserialize/expectedResults.txt
@@ -0,0 +1 @@
+integration/unserialize/test.php:3 SecurityCheck-PHPSerializeInjection Calling 
method \unserialize() in [no method] that outputs using tainted argument $[arg 
#1].
diff --git a/tests/integration/unserialize/test.php 
b/tests/integration/unserialize/test.php
new file mode 100644
index 0000000..afddbdb
--- /dev/null
+++ b/tests/integration/unserialize/test.php
@@ -0,0 +1,3 @@
+<?php
+
+unserialize( $_GET['foo'] );

-- 
To view, visit https://gerrit.wikimedia.org/r/395765
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I315a0019f07130e0a09f14a856d1a7d5afb4d116
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/tools/phan/SecurityCheckPlugin
Gerrit-Branch: master
Gerrit-Owner: Brian Wolff <bawolff...@gmail.com>
Gerrit-Reviewer: Brian Wolff <bawolff...@gmail.com>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to