- For the security plugin used as part of Wikimedia's Phan configuration, see Phan-taint-check-plugin.
We perform static analysis, including security vulnerability analysis of MediaWiki's PHP code base using Phan. MediaWiki core configuration for Phan is in the
.phan directory. All MediaWiki core and Wikimedia-deployed extension and skin patches are analyzed by Phan as part of the CI infrastructure. Non-Wikimedia production code is encouraged to use Phan as well.
Phan requires PHP >= 7.2 to run. This is because Phan analyzes the AST that was added to PHP in version 7. The php-ast extension is also strongly recommended. You can use Phan without it (as long as you pass the
--allow-polyfill-parser option), but it could be slower.
We pull Phan via composer. If your repo already requires
mediawiki/mediawiki-phan-config, all you have to do is run
composer update to install Phan. Otherwise, you should run
composer require --dev mediawiki/mediawiki-phan-config first.
vendor/bin/phan -d . -p
-d .tells it to analyze the current directory
-ptells it to output a progress bar. Alternatively, you may use
--long-progress-barto get a progress bar more suitable for e.g. CI logs.
For MediaWiki extensions and skins, you might need to hint the path to mediawiki/core by setting the
MW_INSTALL_PATH=/home/user/git/mediawiki/core phan ..
A Web demo is available. Note, however, that it's usually useful only if you want to analyze a small piece of code.
- Annotating Your Source Code
- About Union Types
- Issue Types Caught by Phan
- Typing Parameters
- Phan Config Settings
Results are in the following structure, one per line.
includes/AuthPlugin.php:165 PhanUndeclaredMethod Call to undeclared method \AuthPlugin::allowEmailChange includes/DerivativeRequest.php:56 PhanParamSignatureMismatch Declaration of function getHeader($name, int $flags = null) should be compatible with function getHeader(string $name, int $flags = null) : array|bool|string defined in includes/WebRequest.php:1028
Sometimes phan gets it wrong. Or the code is just so hopeless that a large refactor is needed to make the analysis line up. In these cases errors from individual lines can be suppressed with the following format:
// @phan-suppress-next-line PhanUndeclaredMethod some text saying why it was suppressed
Multiple issues can be suppressed from the same line by comma separating them:
/* @phan-suppress-next-line PhanUndeclaredVariable, PhanUndeclaredFunction */
See the upstream documentation.
Or you can suppress particular error types from an entire repo by modifying the
suppress_issue_types array in your phan config.php file:
$cfg['suppress_issue_types'] = array_merge( $cfg['suppress_issue_types'], [ 'PhanDeprecatedProperty', ] );
- Phan cannot read
/** @var Foo $bar */annotations in the middle of functions. This is a limitation of the PHP AST, and it likely won't change in the near future. Current workarounds include:
- You can specify @var annotations in the method doc block.
- You can also use the ugly-but-it-works string literal version:
'@phan-var Foo $bar';see line 302 in this commit for an example.
phan-taint-checkcannot accommodate certain data flows for subclasses that should obviously be considered tainted. The workaround for this is to mark any relevant subclass functions as
@return-taint html. See also: https://phabricator.wikimedia.org/T289314 and the relevant upstream issue: https://github.com/phan/phan/issues/4502.