Added SensioLabs Security Checker Plugin. Issue #27

This commit is contained in:
Dmitry Khomutov 2017-04-04 20:59:28 +07:00
parent e4803f657a
commit e3e3cf5124
No known key found for this signature in database
GPG key ID: 7EB36C9576F9ECB9
10 changed files with 1812 additions and 828 deletions

View file

@ -54,6 +54,16 @@
"sensiolabs/ansi-to-html": "1.1.*",
"pda/pheanstalk": "3.1.*",
"phpunit/phpunit": "5.7.*",
"codeception/codeception": "2.2.*",
"phpmd/phpmd": "2.5.*",
"sebastian/phpcpd": "2.0.*",
"squizlabs/php_codesniffer": "2.7.*",
"block8/php-docblock-checker": "1.0.*",
"phploc/phploc": "3.0.*",
"jakub-onderka/php-parallel-lint": "0.9.*",
"sensiolabs/security-checker": "4.0.*",
"mnsami/composer-custom-directory-installer": "1.1.*",
"npm-asset/sprintf-js": "1.0.*",
@ -63,15 +73,6 @@
"bower-asset/ionicons": "2.0.*",
"bower-asset/raphael": "2.2.*"
},
"require-dev": {
"phpunit/phpunit": "5.7.*",
"phpmd/phpmd": "2.5.*",
"sebastian/phpcpd": "2.0.*",
"squizlabs/php_codesniffer": "2.7.*",
"block8/php-docblock-checker": "1.0.*",
"phploc/phploc": "3.0.*",
"jakub-onderka/php-parallel-lint": "0.9.*"
},
"extra": {
"installer-paths": {
"public/assets/vendor/sprintf-js": ["npm-asset/sprintf-js"],

2449
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -64,6 +64,7 @@ Plugins
* [Shell](plugins/shell.md) - `shell`
* [Slack](plugins/slack_notify.md) - `slack_notify`
* [Technical Debt](plugins/technical_dept.md) - `technical_debt`
* [Security Checker](plugins/security_checker.md) - SensioLabs Security Checker Plugin (`security_checker`).
* [XMPP](plugins/xmpp.md) - `xmpp`
### Third-party plugins

View file

@ -0,0 +1,21 @@
SensioLabs Security Checker Plugin
==================================
Runs [SensioLabs Security Checker](https://github.com/sensiolabs/security-checker) against your project.
Configuration
-------------
### Options
- **allowed_warnings** [int, optional] - The warning limit for a successful build (default: 0). -1 disables warnings.
### Example
Run PHPLoc against the app directory only. This will prevent inclusion of code from 3rd party libraries that are included outside of the app directory.
```yml
test:
security_checker:
allowed_warnings: -1
```

View file

@ -49,27 +49,27 @@ var phpspecPlugin = ActiveBuild.UiPlugin.extend({
tbody.empty();
for (var i in tests.suites) {
var test_suite = tests.suites[i];
var test_suite = tests.suites[i];
for(var k in test_suite.cases){
var test_case = test_suite.cases[k];
for (var k in test_suite.cases) {
var test_case = test_suite.cases[k];
var row = $(
'<tr>'+
'<td>'+test_suite.name+'</td>'+
'<td title="'+Lang.get('took_n_seconds', test_case['time'])+'">'+test_case.name+'</td>'+
'<td>'+(test_case.message ? test_case.message : Lang.get('ok'))+'</td>'+
'</tr>'
);
var row = $(
'<tr>' +
'<td>' + test_suite.name + '</td>' +
'<td title="' + Lang.get('took_n_seconds', test_case['time']) + '">' + test_case.name + '</td>' +
'<td>' + (test_case.message ? test_case.message : Lang.get('ok')) + '</td>' +
'</tr>'
);
if (test_case.status!='passed') {
row.addClass('danger');
} else {
row.addClass('success');
}
if (test_case.status != 'passed') {
row.addClass('danger');
} else {
row.addClass('success');
}
tbody.append(row);
}
tbody.append(row);
}
}
// show plugin once preparation of grid is done

View file

@ -394,6 +394,7 @@ PHP Censor',
'slack_notify' => 'Slack',
'technical_debt' => 'Technical Debt',
'xmpp' => 'XMPP',
'security_checker' => 'SensioLabs Security Checker',
'confirm_message' => 'Item will be permanently deleted. Are you sure?',
'confirm_title' => 'Item delete confirmation',

View file

@ -377,6 +377,7 @@ PHP Censor',
'slack_notify' => 'Slack',
'technical_debt' => 'Technical Debt',
'xmpp' => 'XMPP',
'security_checker' => 'SensioLabs Security Checker',
'confirm_message' => 'Элемент будет удален навсегда. Вы уверены?',
'confirm_title' => 'Подтвержение удаления',

View file

@ -8,13 +8,14 @@ namespace PHPCensor\Plugin;
use PHPCensor\Builder;
use PHPCensor\Model\Build;
use Psr\Log\LogLevel;
use \PHPCensor\Plugin;
/**
* Integrates PHPCensor with Mage: https://github.com/andres-montanez/Magallanes
* @package PHPCensor
* @subpackage Plugins
*/
class Mage extends \PHPCensor\Plugin
class Mage extends Plugin
{
protected $mage_bin = 'mage';
protected $mage_env;

View file

@ -5,6 +5,7 @@ namespace PHPCensor\Plugin;
use PHPCensor;
use PHPCensor\Builder;
use PHPCensor\Model\Build;
use PHPCensor\Model\BuildError;
use PHPCensor\Plugin;
use PHPCensor\ZeroConfigPluginInterface;
@ -28,6 +29,10 @@ class PhpDocblockChecker extends Plugin implements ZeroConfigPluginInterface
protected $skipClasses = false;
protected $skipMethods = false;
/**
* @var integer
*/
protected $allowed_warnings;
/**
@ -128,8 +133,8 @@ class PhpDocblockChecker extends Plugin implements ZeroConfigPluginInterface
// Re-enable exec output logging:
$this->builder->logExecOutput(true);
$output = json_decode($this->builder->getLastOutput(), true);
$errors = count($output);
$output = json_decode($this->builder->getLastOutput(), true);
$errors = count($output);
$success = true;
$this->build->storeMeta('phpdoccheck-warnings', $errors);
@ -150,11 +155,11 @@ class PhpDocblockChecker extends Plugin implements ZeroConfigPluginInterface
{
foreach ($output as $error) {
$message = 'Class ' . $error['class'] . ' is missing a docblock.';
$severity = PHPCensor\Model\BuildError::SEVERITY_LOW;
$severity = BuildError::SEVERITY_LOW;
if ($error['type'] == 'method') {
$message = $error['class'] . '::' . $error['method'] . ' is missing a docblock.';
$severity = PHPCensor\Model\BuildError::SEVERITY_NORMAL;
$severity = BuildError::SEVERITY_NORMAL;
}
$this->build->reportError(

View file

@ -0,0 +1,98 @@
<?php
namespace PHPCensor\Plugin;
use PHPCensor;
use PHPCensor\Builder;
use PHPCensor\Model\Build;
use PHPCensor\Plugin;
use PHPCensor\Model\BuildError;
use PHPCensor\ZeroConfigPluginInterface;
use SensioLabs\Security\SecurityChecker as BaseSecurityChecker;
/**
* SensioLabs Security Checker Plugin
*
* @author Dmitry Khomutov <poisoncorpsee@gmail.com>
*/
class SecurityChecker extends Plugin implements ZeroConfigPluginInterface
{
/**
* @var integer
*/
protected $allowed_warnings;
/**
* @return string
*/
public static function pluginName()
{
return 'security_checker';
}
/**
* {@inheritdoc}
*/
public function __construct(Builder $builder, Build $build, array $options = [])
{
parent::__construct($builder, $build, $options);
$this->allowed_warnings = 0;
if (isset($options['zero_config']) && $options['zero_config']) {
$this->allowed_warnings = -1;
}
if (array_key_exists('allowed_warnings', $options)) {
$this->allowed_warnings = (int)$options['allowed_warnings'];
}
}
/**
* Check if this plugin can be executed.
*
* @param $stage
* @param Builder $builder
* @param Build $build
*
* @return bool
*/
public static function canExecute($stage, Builder $builder, Build $build)
{
$path = $builder->buildPath . DIRECTORY_SEPARATOR . 'composer.lock';
if (file_exists($path) && $stage == Build::STAGE_TEST) {
return true;
}
return false;
}
public function execute()
{
$success = true;
$checker = new BaseSecurityChecker();
$warnings = $checker->check($this->builder->buildPath . DIRECTORY_SEPARATOR . 'composer.lock');
if ($warnings) {
foreach ($warnings as $library => $warning) {
foreach ($warning['advisories'] as $advisory => $data) {
$this->build->reportError(
$this->builder,
'security_checker',
$library . ' (' . $warning['version'] . ")\n" . $data['cve'] . ': ' . $data['title'] . "\n" . $data['link'],
BuildError::SEVERITY_CRITICAL,
'-',
'-'
);
}
}
if ($this->allowed_warnings != -1 && ((int)$checker->getLastVulnerabilityCount() > $this->allowed_warnings)) {
$success = false;
}
}
return $success;
}
}