diff --git a/.codecov.yml b/.codecov.yml index bd531bc2..849e46e8 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -3,6 +3,6 @@ coverage: project: default: informational: true - path: + patch: default: informational: true diff --git a/.env b/.env index c762cc88..9a8bb987 100644 --- a/.env +++ b/.env @@ -75,4 +75,5 @@ GA_TRACKING= ###> storage ### PROXY_DIST_DIR=%kernel.project_dir%/var/proxy PACKAGES_DIST_DIR=%kernel.project_dir%/var/repo +SECURITY_ADVISORIES_DB_DIR=%kernel.project_dir%/var/security-advisories ###< storage ### diff --git a/.env.docker b/.env.docker index 8b5c1d2c..f7592966 100644 --- a/.env.docker +++ b/.env.docker @@ -79,5 +79,6 @@ GA_TRACKING= ###> storage ### PROXY_DIST_DIR=%kernel.project_dir%/var/proxy PACKAGES_DIST_DIR=%kernel.project_dir%/var/repo +SECURITY_ADVISORIES_DB_DIR=%kernel.project_dir%/var/security-advisories ###< storage ### diff --git a/composer.json b/composer.json index f16b3972..fb9e04d6 100644 --- a/composer.json +++ b/composer.json @@ -6,11 +6,11 @@ "require": { "php": "^7.4.1", "ext-ctype": "*", + "ext-curl": "*", "ext-iconv": "*", "ext-intl": "*", - "ext-zip": "*", - "ext-curl": "*", "ext-pdo_pgsql": "*", + "ext-zip": "*", "bitbucket/client": "^2.1", "buddy-works/buddy-works-php-api": "^1.3", "buddy-works/oauth2-client": "^0.1", @@ -40,6 +40,7 @@ "symfony/messenger": "5.0.*", "symfony/monolog-bundle": "^3.5", "symfony/orm-pack": "^1.0", + "symfony/process": "5.0.*", "symfony/security-bundle": "5.0.*", "symfony/twig-pack": "^1.0", "symfony/validator": "5.0.*", diff --git a/composer.lock b/composer.lock index 6805943f..eb36d208 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ae82c074e0ff87ea0b4c265cb9967b0c", + "content-hash": "53049602044a03a05bd1e57074c063e8", "packages": [ { "name": "bitbucket/client", @@ -7561,16 +7561,16 @@ }, { "name": "symfony/process", - "version": "v5.0.7", + "version": "v5.0.8", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "c5ca4a0fc16a0c888067d43fbcfe1f8a53d8e70e" + "reference": "3179f68dff5bad14d38c4114a1dab98030801fd7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/c5ca4a0fc16a0c888067d43fbcfe1f8a53d8e70e", - "reference": "c5ca4a0fc16a0c888067d43fbcfe1f8a53d8e70e", + "url": "https://api.github.com/repos/symfony/process/zipball/3179f68dff5bad14d38c4114a1dab98030801fd7", + "reference": "3179f68dff5bad14d38c4114a1dab98030801fd7", "shasum": "", "mirrors": [ { @@ -7596,7 +7596,7 @@ "/Tests/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.repman.io/downloads", "license": [ "MIT" ], @@ -7612,7 +7612,21 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2020-03-27T16:56:45+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-04-15T15:59:10+00:00" }, { "name": "symfony/property-access", @@ -8786,16 +8800,16 @@ }, { "name": "symfony/yaml", - "version": "v5.0.7", + "version": "v5.0.8", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "ad5e9c83ade5bbb3a96a3f30588a0622708caefd" + "reference": "482fb4e710e5af3e0e78015f19aa716ad953392f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/ad5e9c83ade5bbb3a96a3f30588a0622708caefd", - "reference": "ad5e9c83ade5bbb3a96a3f30588a0622708caefd", + "url": "https://api.github.com/repos/symfony/yaml/zipball/482fb4e710e5af3e0e78015f19aa716ad953392f", + "reference": "482fb4e710e5af3e0e78015f19aa716ad953392f", "shasum": "", "mirrors": [ { @@ -8831,7 +8845,7 @@ "/Tests/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.repman.io/downloads", "license": [ "MIT" ], @@ -8847,7 +8861,21 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2020-03-30T11:42:42+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-04-28T17:58:55+00:00" }, { "name": "twig/extra-bundle", @@ -12179,11 +12207,11 @@ "platform": { "php": "^7.4.1", "ext-ctype": "*", + "ext-curl": "*", "ext-iconv": "*", "ext-intl": "*", - "ext-zip": "*", - "ext-curl": "*", - "ext-pdo_pgsql": "*" + "ext-pdo_pgsql": "*", + "ext-zip": "*" }, "platform-dev": [], "plugin-api-version": "1.1.0" diff --git a/config/services.yaml b/config/services.yaml index c323351b..f5b18dc9 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -13,6 +13,8 @@ parameters: url_scheme: '%env(resolve:APP_URL_SCHEME)%' router.request_context.scheme: '%env(resolve:APP_URL_SCHEME)%' router.request_context.host: '%env(default:domain:APP_PUBLIC_HOST)%' + security_advisories_db_dir: '%env(resolve:SECURITY_ADVISORIES_DB_DIR)%' + security_advisories_db_repo: 'https://github.com/FriendsOfPHP/security-advisories.git' services: # default configuration for services in *this* file @@ -78,6 +80,11 @@ services: bitbucket: '%env(OAUTH_BITBUCKET_CLIENT_ID)%' buddy: '%env(OAUTH_BUDDY_CLIENT_ID)%' + Buddy\Repman\Service\Security\SecurityChecker\SensioLabsSecurityChecker: + arguments: + $databaseDir: '%security_advisories_db_dir%' + $databaseRepo: '%security_advisories_db_repo%' + ### Vendor Github\Client: arguments: diff --git a/config/services_test.yaml b/config/services_test.yaml index 1d2af0c1..49208858 100644 --- a/config/services_test.yaml +++ b/config/services_test.yaml @@ -1,6 +1,8 @@ parameters: dists_dir: '%kernel.project_dir%/tests/Resources' repo_dir: '%kernel.project_dir%/tests/Resources' + security_advisories_db_dir: '%kernel.project_dir%/tests/Resources/fixtures/security/security-advisories' + security_advisories_db_repo: 'bogus' services: Buddy\Repman\Service\Downloader: @@ -31,3 +33,6 @@ services: Buddy\Repman\Service\Security\PackageScanner: class: Buddy\Repman\Tests\Doubles\FakePackageScanner + + Buddy\Repman\Service\Security\SecurityChecker: + class: Buddy\Repman\Tests\Doubles\FakeSecurityChecker diff --git a/src/Command/UpdateAdvisoriesDbCommand.php b/src/Command/UpdateAdvisoriesDbCommand.php new file mode 100644 index 00000000..f6c5947c --- /dev/null +++ b/src/Command/UpdateAdvisoriesDbCommand.php @@ -0,0 +1,41 @@ +checker = $checker; + } + + /** + * @return void + */ + protected function configure() + { + $this + ->setName('repman:security:update-db') + ->setDescription('Update security advisories database') + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->checker->update(); + $output->writeln(sprintf('Database successfully updated')); + + return 0; + } +} diff --git a/src/Service/Security/SecurityChecker/Advisory.php b/src/Service/Security/SecurityChecker/Advisory.php new file mode 100644 index 00000000..2bf65255 --- /dev/null +++ b/src/Service/Security/SecurityChecker/Advisory.php @@ -0,0 +1,47 @@ +title = $title; + $this->cve = $cve; + $this->link = $link; + $this->branches = $branches; + } + + /** + * @return Versions[] + */ + public function branches(): array + { + return $this->branches; + } + + /** + * @return array + */ + public function toArray(): array + { + return [ + 'title' => $this->title, + 'cve' => $this->cve, + 'link' => $this->link, + ]; + } +} diff --git a/src/Service/Security/SecurityChecker/Package.php b/src/Service/Security/SecurityChecker/Package.php new file mode 100644 index 00000000..dcf48ef8 --- /dev/null +++ b/src/Service/Security/SecurityChecker/Package.php @@ -0,0 +1,27 @@ +name = $name; + $this->version = $version; + } + + public function name(): string + { + return $this->name; + } + + public function version(): string + { + return $this->version; + } +} diff --git a/src/Service/Security/SecurityChecker/Result.php b/src/Service/Security/SecurityChecker/Result.php new file mode 100644 index 00000000..c0590fe0 --- /dev/null +++ b/src/Service/Security/SecurityChecker/Result.php @@ -0,0 +1,34 @@ +version = $version; + $this->advisories = $advisories; + } + + /** + * @return array> + */ + public function toArray(): array + { + return [ + 'version' => $this->version, + 'advisories' => array_map(fn ($advisory) => $advisory->toArray(), $this->advisories), + ]; + } +} diff --git a/src/Service/Security/SecurityChecker/SensioLabsSecurityChecker.php b/src/Service/Security/SecurityChecker/SensioLabsSecurityChecker.php index a370977a..513971fd 100644 --- a/src/Service/Security/SecurityChecker/SensioLabsSecurityChecker.php +++ b/src/Service/Security/SecurityChecker/SensioLabsSecurityChecker.php @@ -5,20 +5,212 @@ namespace Buddy\Repman\Service\Security\SecurityChecker; use Buddy\Repman\Service\Security\SecurityChecker; +use Symfony\Component\Process\Exception\ProcessFailedException; +use Symfony\Component\Process\Process; +use Symfony\Component\Yaml\Parser; final class SensioLabsSecurityChecker implements SecurityChecker { + private Parser $yamlParser; + private string $databaseDir; + private string $databaseRepo; + + /** + * @var array + */ + private array $advisories = []; + + public function __construct(string $databaseDir, string $databaseRepo) + { + $this->yamlParser = new Parser(); + $this->databaseDir = $databaseDir; + $this->databaseRepo = $databaseRepo; + } + + public function update(): void + { + if (!is_dir($this->databaseDir.'/.git')) { + @mkdir($this->databaseDir, 0777, true); + $this->cloneRepo(); + + return; + } + + $this->updateRepo(); + } + /** * @return mixed[] */ public function check(string $lockFile): array { - // TODO: implement - return []; + $packages = $this->getPackages($lockFile); + $this->loadAdvisoriesDatabase(); + + $alerts = []; + foreach ($packages as $package) { + $packageAdvisories = $this->checkPackage($package); + if ($packageAdvisories === []) { + continue; + } + + $alerts[$package->name()] = (new Result( + $package->version(), + $packageAdvisories + ))->toArray(); + } + + return $alerts; } - public function update(): void + /** + * @return Advisory[] + */ + private function checkPackage(Package $package): array + { + $packageAdvisories = $this->advisories[$package->name()] ?? []; + + $alerts = []; + foreach ($packageAdvisories as $advisory) { + foreach ($advisory->branches() as $versions) { + if ($versions->include($package->version())) { + $alerts[] = $advisory; + } + } + } + + return $alerts; + } + + /** + * @return Package[] + */ + private function getPackages(string $lockFile): array { - // TODO: implement + $contents = json_decode($lockFile, true); + if (json_last_error() !== JSON_ERROR_NONE) { + throw new \UnexpectedValueException('Invalid composer.lock'); + } + + $packages = []; + foreach (['packages', 'packages-dev'] as $key) { + if (!isset($contents[$key]) || !is_array($contents[$key])) { + continue; + } + + foreach ($contents[$key] as $package) { + $packages[] = new Package($package['name'], $package['version']); + } + } + + return $packages; + } + + /** + * @return array + */ + private function getAdvisories(): array + { + $advisories = []; + foreach ($this->getDatabase() as $file) { + if (!$file->isFile() || $file->getExtension() !== 'yaml') { + continue; + } + + $packageName = $this->parsePackageName( + str_replace($this->databaseDir, '', $file->getPathname()) + ); + + if ($packageName === null) { + continue; + } + + $data = $this->yamlParser->parse( + (string) file_get_contents($file->getRealPath()) + ); + + if (!isset($advisories[$packageName])) { + $advisories[$packageName] = []; + } + + $advisories[$packageName][] = new Advisory( + $data['title'], + $data['cve'] ?? '', + $data['link'], + array_map( + fn ($branch) => new Versions(...$branch['versions']), + array_values($data['branches']) + ) + ); + } + + return $advisories; + } + + private function getDatabase(): \RecursiveIteratorIterator + { + if (!is_dir($this->databaseDir)) { + throw new \RuntimeException('Advisories database does not exist'); + } + + $advisoryFilter = function (\SplFileInfo $file): bool { + if ($file->isDir()) { + $dirName = $file->getFilename(); + if ($dirName[0] == '.') { + return false; + } + } + + return true; + }; + + return new \RecursiveIteratorIterator( + new \RecursiveCallbackFilterIterator( + new \RecursiveDirectoryIterator($this->databaseDir), + $advisoryFilter + ) + ); + } + + private function parsePackageName(string $path): ?string + { + $matches = []; + preg_match('~^/(?.+/.+)/.+yaml$~', $path, $matches); + + return $matches['name'] ?? null; + } + + private function loadAdvisoriesDatabase(): void + { + if ($this->advisories === []) { + $this->advisories = $this->getAdvisories(); + } + } + + private function cloneRepo(): void + { + $this->runProcess([ + 'git', 'clone', '--depth', '1', '--branch', 'master', $this->databaseRepo, '.', + ]); + } + + private function updateRepo(): void + { + $this->runProcess(['git', '--git-dir=.git', 'clean', '-f']); + $this->runProcess(['git', '--git-dir=.git', 'reset', '--hard', 'origin/master']); + $this->runProcess(['git', '--git-dir=.git', 'pull', '--depth', '1']); + } + + /** + * @param string[] $command + */ + protected function runProcess(array $command): void + { + $process = new Process($command, $this->databaseDir); + $process->run(); + + if (!$process->isSuccessful()) { + throw new ProcessFailedException($process); + } } } diff --git a/src/Service/Security/SecurityChecker/Versions.php b/src/Service/Security/SecurityChecker/Versions.php new file mode 100644 index 00000000..3710bf19 --- /dev/null +++ b/src/Service/Security/SecurityChecker/Versions.php @@ -0,0 +1,27 @@ +from = $from; + $this->to = $to; + } + + public function include(string $version): bool + { + $isLarger = Semver::satisfies($version, $this->from); + $isSmaller = $this->to === null ? true : Semver::satisfies($version, $this->to); + + return $isLarger && $isSmaller; + } +} diff --git a/tests/Functional/Command/UpdateAdvisoriesDbCommandTest.php b/tests/Functional/Command/UpdateAdvisoriesDbCommandTest.php new file mode 100644 index 00000000..1d0b2797 --- /dev/null +++ b/tests/Functional/Command/UpdateAdvisoriesDbCommandTest.php @@ -0,0 +1,24 @@ +container()->get(UpdateAdvisoriesDbCommand::class) + ); + $result = $commandTester->execute([]); + $output = $commandTester->getDisplay(); + + self::assertEquals($result, 0); + self::assertStringContainsString('Database successfully updated', $output); + } +} diff --git a/tests/Resources/fixtures/security/locks/insecure-composer.lock b/tests/Resources/fixtures/security/locks/insecure-composer.lock new file mode 100644 index 00000000..e8c3a992 --- /dev/null +++ b/tests/Resources/fixtures/security/locks/insecure-composer.lock @@ -0,0 +1,1288 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "37b1ac4441474d018104686755839ca4", + "packages": [ + { + "name": "aws/aws-sdk-php", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/aws/aws-sdk-php.git", + "reference": "07bcef20cd97a5aea92ac565d76b49964be7abe9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/07bcef20cd97a5aea92ac565d76b49964be7abe9", + "reference": "07bcef20cd97a5aea92ac565d76b49964be7abe9", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": ">=5.3|~6.0.1|~6.1", + "guzzlehttp/promises": "~1.0", + "guzzlehttp/psr7": "~1.0", + "mtdowling/jmespath.php": "~2.2", + "php": ">=5.5" + }, + "require-dev": { + "behat/behat": "~3.0", + "ext-dom": "*", + "ext-json": "*", + "ext-openssl": "*", + "ext-pcre": "*", + "ext-simplexml": "*", + "ext-spl": "*", + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "ext-curl": "To send requests using cURL", + "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Aws\\": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Amazon Web Services", + "homepage": "http://aws.amazon.com" + } + ], + "description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project", + "homepage": "http://aws.amazon.com/sdkforphp", + "keywords": [ + "amazon", + "aws", + "cloud", + "dynamodb", + "ec2", + "glacier", + "s3", + "sdk" + ], + "time": "2015-07-14T20:49:33+00:00" + }, + { + "name": "composer/installers", + "version": "v1.9.0", + "source": { + "type": "git", + "url": "https://github.com/composer/installers.git", + "reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/installers/zipball/b93bcf0fa1fccb0b7d176b0967d969691cd74cca", + "reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0" + }, + "replace": { + "roundcube/plugin-installer": "*", + "shama/baton": "*" + }, + "require-dev": { + "composer/composer": "1.6.* || 2.0.*@dev", + "composer/semver": "1.0.* || 2.0.*@dev", + "phpunit/phpunit": "^4.8.36", + "sebastian/comparator": "^1.2.4", + "symfony/process": "^2.3" + }, + "type": "composer-plugin", + "extra": { + "class": "Composer\\Installers\\Plugin", + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Installers\\": "src/Composer/Installers" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kyle Robinson Young", + "email": "kyle@dontkry.com", + "homepage": "https://github.com/shama" + } + ], + "description": "A multi-framework Composer library installer", + "homepage": "https://composer.github.io/installers/", + "keywords": [ + "Craft", + "Dolibarr", + "Eliasis", + "Hurad", + "ImageCMS", + "Kanboard", + "Lan Management System", + "MODX Evo", + "MantisBT", + "Mautic", + "Maya", + "OXID", + "Plentymarkets", + "Porto", + "RadPHP", + "SMF", + "Thelia", + "Whmcs", + "WolfCMS", + "agl", + "aimeos", + "annotatecms", + "attogram", + "bitrix", + "cakephp", + "chef", + "cockpit", + "codeigniter", + "concrete5", + "croogo", + "dokuwiki", + "drupal", + "eZ Platform", + "elgg", + "expressionengine", + "fuelphp", + "grav", + "installer", + "itop", + "joomla", + "known", + "kohana", + "laravel", + "lavalite", + "lithium", + "magento", + "majima", + "mako", + "mediawiki", + "modulework", + "modx", + "moodle", + "osclass", + "phpbb", + "piwik", + "ppi", + "puppet", + "pxcms", + "reindex", + "roundcube", + "shopware", + "silverstripe", + "sydes", + "sylius", + "symfony", + "typo3", + "wordpress", + "yawik", + "zend", + "zikula" + ], + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2020-04-07T06:57:05+00:00" + }, + { + "name": "fuel/core", + "version": "1.8.0", + "source": { + "type": "git", + "url": "https://github.com/fuel/core.git", + "reference": "26f6432a9f41659280c70ba47c16170adf1e7611" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fuel/core/zipball/26f6432a9f41659280c70ba47c16170adf1e7611", + "reference": "26f6432a9f41659280c70ba47c16170adf1e7611", + "shasum": "" + }, + "require": { + "composer/installers": "~1.0" + }, + "type": "fuel-package", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "FuelPHP Development Team", + "email": "team@fuelphp.com" + } + ], + "description": "FuelPHP 1.x Core", + "homepage": "https://github.com/fuel/core", + "time": "2016-04-09T16:28:31+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "6.5.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "aab4ebd862aa7d04f01a4b51849d657db56d882e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/aab4ebd862aa7d04f01a4b51849d657db56d882e", + "reference": "aab4ebd862aa7d04f01a4b51849d657db56d882e", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.6.1", + "php": ">=5.5", + "symfony/polyfill-intl-idn": "^1.11" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", + "psr/log": "^1.1" + }, + "suggest": { + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.5-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2020-04-18T10:38:46+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "shasum": "" + }, + "require": { + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "time": "2016-12-20T10:07:11+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "239400de7a173fe9901b9ac7c06497751f00727a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a", + "reference": "239400de7a173fe9901b9ac7c06497751f00727a", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-zlib": "*", + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" + }, + "suggest": { + "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "time": "2019-07-01T23:21:34+00:00" + }, + { + "name": "ircmaxell/password-compat", + "version": "v1.0.4", + "source": { + "type": "git", + "url": "https://github.com/ircmaxell/password_compat.git", + "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c", + "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c", + "shasum": "" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "type": "library", + "autoload": { + "files": [ + "lib/password.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anthony Ferrara", + "email": "ircmaxell@php.net", + "homepage": "http://blog.ircmaxell.com" + } + ], + "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash", + "homepage": "https://github.com/ircmaxell/password_compat", + "keywords": [ + "hashing", + "password" + ], + "time": "2014-11-20T16:49:30+00:00" + }, + { + "name": "mtdowling/jmespath.php", + "version": "2.5.0", + "source": { + "type": "git", + "url": "https://github.com/jmespath/jmespath.php.git", + "reference": "52168cb9472de06979613d365c7f1ab8798be895" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/52168cb9472de06979613d365c7f1ab8798be895", + "reference": "52168cb9472de06979613d365c7f1ab8798be895", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "symfony/polyfill-mbstring": "^1.4" + }, + "require-dev": { + "composer/xdebug-handler": "^1.2", + "phpunit/phpunit": "^4.8.36|^7.5.15" + }, + "bin": [ + "bin/jp.php" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev" + } + }, + "autoload": { + "psr-4": { + "JmesPath\\": "src/" + }, + "files": [ + "src/JmesPath.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Declaratively specify how to extract elements from a JSON document", + "keywords": [ + "json", + "jsonpath" + ], + "time": "2019-12-30T18:03:34+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "psr/log", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2020-03-23T09:12:05+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "symfony/debug", + "version": "v2.6.3", + "target-dir": "Symfony/Component/Debug", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug.git", + "reference": "7213c8200d60728c9d4c56d5830aa2d80ae3d25d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug/zipball/7213c8200d60728c9d4c56d5830aa2d80ae3d25d", + "reference": "7213c8200d60728c9d4c56d5830aa2d80ae3d25d", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "psr/log": "~1.0" + }, + "require-dev": { + "symfony/class-loader": "~2.2", + "symfony/http-foundation": "~2.1", + "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2" + }, + "suggest": { + "symfony/http-foundation": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Debug\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony Debug Component", + "homepage": "http://symfony.com", + "time": "2015-01-05T17:41:06+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v2.8.52", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "a77e974a5fecb4398833b0709210e3d5e334ffb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a77e974a5fecb4398833b0709210e3d5e334ffb0", + "reference": "a77e974a5fecb4398833b0709210e3d5e334ffb0", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "^2.0.5|~3.0.0", + "symfony/dependency-injection": "~2.6|~3.0.0", + "symfony/expression-language": "~2.6|~3.0.0", + "symfony/stopwatch": "~2.3|~3.0.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "time": "2018-11-21T14:20:20+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v2.8.52", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "3929d9fe8148d17819ad0178c748b8d339420709" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/3929d9fe8148d17819ad0178c748b8d339420709", + "reference": "3929d9fe8148d17819ad0178c748b8d339420709", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php54": "~1.0", + "symfony/polyfill-php55": "~1.0" + }, + "require-dev": { + "symfony/expression-language": "~2.4|~3.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony HttpFoundation Component", + "homepage": "https://symfony.com", + "time": "2019-11-12T12:34:41+00:00" + }, + { + "name": "symfony/http-kernel", + "version": "v2.3.0", + "target-dir": "Symfony/Component/HttpKernel", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "5733d7e4ecdc8d93fea6ab4b284ad2e4e846c250" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/5733d7e4ecdc8d93fea6ab4b284ad2e4e846c250", + "reference": "5733d7e4ecdc8d93fea6ab4b284ad2e4e846c250", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "psr/log": "~1.0", + "symfony/debug": "~2.3", + "symfony/event-dispatcher": "~2.1", + "symfony/http-foundation": "~2.2" + }, + "require-dev": { + "symfony/browser-kit": "2.2.*", + "symfony/class-loader": "~2.1", + "symfony/config": "~2.0", + "symfony/console": "2.2.*", + "symfony/dependency-injection": "~2.0", + "symfony/finder": "~2.0", + "symfony/process": "~2.0", + "symfony/routing": "~2.2", + "symfony/stopwatch": "~2.2" + }, + "suggest": { + "symfony/browser-kit": "", + "symfony/class-loader": "", + "symfony/config": "", + "symfony/console": "", + "symfony/dependency-injection": "", + "symfony/finder": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\HttpKernel\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony HttpKernel Component", + "homepage": "http://symfony.com", + "time": "2013-06-03T14:13:35+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "3bff59ea7047e925be6b7f2059d60af31bb46d6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/3bff59ea7047e925be6b7f2059d60af31bb46d6a", + "reference": "3bff59ea7047e925be6b7f2059d60af31bb46d6a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/polyfill-mbstring": "^1.3", + "symfony/polyfill-php72": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "fa79b11539418b02fc5e1897267673ba2c19419c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fa79b11539418b02fc5e1897267673ba2c19419c", + "reference": "fa79b11539418b02fc5e1897267673ba2c19419c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" + }, + { + "name": "symfony/polyfill-php54", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php54.git", + "reference": "3c71ff0f90fcbd00ca8966f35526e3cbad15d31d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/3c71ff0f90fcbd00ca8966f35526e3cbad15d31d", + "reference": "3c71ff0f90fcbd00ca8966f35526e3cbad15d31d", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php54\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" + }, + { + "name": "symfony/polyfill-php55", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php55.git", + "reference": "875267200645e116261c31ff20c641dbae90fd8d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/875267200645e116261c31ff20c641dbae90fd8d", + "reference": "875267200645e116261c31ff20c641dbae90fd8d", + "shasum": "" + }, + "require": { + "ircmaxell/password-compat": "~1.0", + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php55\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "f048e612a3905f34931127360bdd2def19a5e582" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/f048e612a3905f34931127360bdd2def19a5e582", + "reference": "f048e612a3905f34931127360bdd2def19a5e582", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "1.1.0" +} diff --git a/tests/Resources/fixtures/security/locks/safe-composer.lock b/tests/Resources/fixtures/security/locks/safe-composer.lock new file mode 100644 index 00000000..4982b74c --- /dev/null +++ b/tests/Resources/fixtures/security/locks/safe-composer.lock @@ -0,0 +1,1239 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "f70e0f0aacc2bb6505321861cf53313e", + "packages": [ + { + "name": "aws/aws-sdk-php", + "version": "3.138.0", + "source": { + "type": "git", + "url": "https://github.com/aws/aws-sdk-php.git", + "reference": "32a4fa88dffc4328d415b922ef74819dfe060696" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/32a4fa88dffc4328d415b922ef74819dfe060696", + "reference": "32a4fa88dffc4328d415b922ef74819dfe060696", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-pcre": "*", + "ext-simplexml": "*", + "guzzlehttp/guzzle": "^5.3.3|^6.2.1|^7.0", + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.4.1", + "mtdowling/jmespath.php": "^2.5", + "php": ">=5.5" + }, + "require-dev": { + "andrewsville/php-token-reflection": "^1.4", + "aws/aws-php-sns-message-validator": "~1.0", + "behat/behat": "~3.0", + "doctrine/cache": "~1.4", + "ext-dom": "*", + "ext-openssl": "*", + "ext-pcntl": "*", + "ext-sockets": "*", + "nette/neon": "^2.3", + "phpunit/phpunit": "^4.8.35|^5.4.3", + "psr/cache": "^1.0", + "psr/simple-cache": "^1.0", + "sebastian/comparator": "^1.2.3" + }, + "suggest": { + "aws/aws-php-sns-message-validator": "To validate incoming SNS notifications", + "doctrine/cache": "To use the DoctrineCacheAdapter", + "ext-curl": "To send requests using cURL", + "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages", + "ext-sockets": "To use client-side monitoring" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Aws\\": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Amazon Web Services", + "homepage": "http://aws.amazon.com" + } + ], + "description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project", + "homepage": "http://aws.amazon.com/sdkforphp", + "keywords": [ + "amazon", + "aws", + "cloud", + "dynamodb", + "ec2", + "glacier", + "s3", + "sdk" + ], + "time": "2020-05-13T18:11:31+00:00" + }, + { + "name": "composer/installers", + "version": "v1.9.0", + "source": { + "type": "git", + "url": "https://github.com/composer/installers.git", + "reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/installers/zipball/b93bcf0fa1fccb0b7d176b0967d969691cd74cca", + "reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0" + }, + "replace": { + "roundcube/plugin-installer": "*", + "shama/baton": "*" + }, + "require-dev": { + "composer/composer": "1.6.* || 2.0.*@dev", + "composer/semver": "1.0.* || 2.0.*@dev", + "phpunit/phpunit": "^4.8.36", + "sebastian/comparator": "^1.2.4", + "symfony/process": "^2.3" + }, + "type": "composer-plugin", + "extra": { + "class": "Composer\\Installers\\Plugin", + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Installers\\": "src/Composer/Installers" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kyle Robinson Young", + "email": "kyle@dontkry.com", + "homepage": "https://github.com/shama" + } + ], + "description": "A multi-framework Composer library installer", + "homepage": "https://composer.github.io/installers/", + "keywords": [ + "Craft", + "Dolibarr", + "Eliasis", + "Hurad", + "ImageCMS", + "Kanboard", + "Lan Management System", + "MODX Evo", + "MantisBT", + "Mautic", + "Maya", + "OXID", + "Plentymarkets", + "Porto", + "RadPHP", + "SMF", + "Thelia", + "Whmcs", + "WolfCMS", + "agl", + "aimeos", + "annotatecms", + "attogram", + "bitrix", + "cakephp", + "chef", + "cockpit", + "codeigniter", + "concrete5", + "croogo", + "dokuwiki", + "drupal", + "eZ Platform", + "elgg", + "expressionengine", + "fuelphp", + "grav", + "installer", + "itop", + "joomla", + "known", + "kohana", + "laravel", + "lavalite", + "lithium", + "magento", + "majima", + "mako", + "mediawiki", + "modulework", + "modx", + "moodle", + "osclass", + "phpbb", + "piwik", + "ppi", + "puppet", + "pxcms", + "reindex", + "roundcube", + "shopware", + "silverstripe", + "sydes", + "sylius", + "symfony", + "typo3", + "wordpress", + "yawik", + "zend", + "zikula" + ], + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2020-04-07T06:57:05+00:00" + }, + { + "name": "fuel/core", + "version": "1.8.2", + "source": { + "type": "git", + "url": "https://github.com/fuel/core.git", + "reference": "050c3147b1d889223701b63e22f60e90bf46cc1e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fuel/core/zipball/050c3147b1d889223701b63e22f60e90bf46cc1e", + "reference": "050c3147b1d889223701b63e22f60e90bf46cc1e", + "shasum": "" + }, + "require": { + "composer/installers": "~1.0", + "michelf/php-markdown": "1.7.0", + "monolog/monolog": "^1.18", + "paragonie/sodium_compat": "^1.6", + "phpseclib/phpseclib": "^2.0.0" + }, + "type": "fuel-package", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "FuelPHP Development Team", + "email": "team@fuelphp.com" + } + ], + "description": "FuelPHP 1.x Core", + "homepage": "https://github.com/fuel/core", + "time": "2019-06-27T14:56:04+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "6.5.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "aab4ebd862aa7d04f01a4b51849d657db56d882e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/aab4ebd862aa7d04f01a4b51849d657db56d882e", + "reference": "aab4ebd862aa7d04f01a4b51849d657db56d882e", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.6.1", + "php": ">=5.5", + "symfony/polyfill-intl-idn": "^1.11" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", + "psr/log": "^1.1" + }, + "suggest": { + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.5-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2020-04-18T10:38:46+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "shasum": "" + }, + "require": { + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "time": "2016-12-20T10:07:11+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "239400de7a173fe9901b9ac7c06497751f00727a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a", + "reference": "239400de7a173fe9901b9ac7c06497751f00727a", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-zlib": "*", + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" + }, + "suggest": { + "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "time": "2019-07-01T23:21:34+00:00" + }, + { + "name": "michelf/php-markdown", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/michelf/php-markdown.git", + "reference": "1f51cc520948f66cd2af8cbc45a5ee175e774220" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/michelf/php-markdown/zipball/1f51cc520948f66cd2af8cbc45a5ee175e774220", + "reference": "1f51cc520948f66cd2af8cbc45a5ee175e774220", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-lib": "1.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "Michelf": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Michel Fortin", + "email": "michel.fortin@michelf.ca", + "homepage": "https://michelf.ca/", + "role": "Developer" + }, + { + "name": "John Gruber", + "homepage": "https://daringfireball.net/" + } + ], + "description": "PHP Markdown", + "homepage": "https://michelf.ca/projects/php-markdown/", + "keywords": [ + "markdown" + ], + "time": "2016-10-29T18:58:20+00:00" + }, + { + "name": "monolog/monolog", + "version": "1.25.3", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "fa82921994db851a8becaf3787a9e73c5976b6f1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/fa82921994db851a8becaf3787a9e73c5976b6f1", + "reference": "fa82921994db851a8becaf3787a9e73c5976b6f1", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "psr/log": "~1.0" + }, + "provide": { + "psr/log-implementation": "1.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^2.4.9 || ^3.0", + "doctrine/couchdb": "~1.0@dev", + "graylog2/gelf-php": "~1.0", + "jakub-onderka/php-parallel-lint": "0.9", + "php-amqplib/php-amqplib": "~2.4", + "php-console/php-console": "^3.1.3", + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "2.3.0", + "ruflin/elastica": ">=0.90 <3.0", + "sentry/sentry": "^0.13", + "swiftmailer/swiftmailer": "^5.3|^6.0" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-mongo": "Allow sending log messages to a MongoDB server", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "php-console/php-console": "Allow sending log messages to Google Chrome", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server", + "sentry/sentry": "Allow sending log messages to a Sentry server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "http://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "time": "2019-12-20T14:15:16+00:00" + }, + { + "name": "mtdowling/jmespath.php", + "version": "2.5.0", + "source": { + "type": "git", + "url": "https://github.com/jmespath/jmespath.php.git", + "reference": "52168cb9472de06979613d365c7f1ab8798be895" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/52168cb9472de06979613d365c7f1ab8798be895", + "reference": "52168cb9472de06979613d365c7f1ab8798be895", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "symfony/polyfill-mbstring": "^1.4" + }, + "require-dev": { + "composer/xdebug-handler": "^1.2", + "phpunit/phpunit": "^4.8.36|^7.5.15" + }, + "bin": [ + "bin/jp.php" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev" + } + }, + "autoload": { + "psr-4": { + "JmesPath\\": "src/" + }, + "files": [ + "src/JmesPath.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Declaratively specify how to extract elements from a JSON document", + "keywords": [ + "json", + "jsonpath" + ], + "time": "2019-12-30T18:03:34+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.99", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "shasum": "" + }, + "require": { + "php": "^7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "time": "2018-07-02T15:55:56+00:00" + }, + { + "name": "paragonie/sodium_compat", + "version": "v1.13.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/sodium_compat.git", + "reference": "bbade402cbe84c69b718120911506a3aa2bae653" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/bbade402cbe84c69b718120911506a3aa2bae653", + "reference": "bbade402cbe84c69b718120911506a3aa2bae653", + "shasum": "" + }, + "require": { + "paragonie/random_compat": ">=1", + "php": "^5.2.4|^5.3|^5.4|^5.5|^5.6|^7|^8" + }, + "require-dev": { + "phpunit/phpunit": "^3|^4|^5|^6|^7" + }, + "suggest": { + "ext-libsodium": "PHP < 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security.", + "ext-sodium": "PHP >= 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security." + }, + "type": "library", + "autoload": { + "files": [ + "autoload.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com" + }, + { + "name": "Frank Denis", + "email": "jedisct1@pureftpd.org" + } + ], + "description": "Pure PHP implementation of libsodium; uses the PHP extension if it exists", + "keywords": [ + "Authentication", + "BLAKE2b", + "ChaCha20", + "ChaCha20-Poly1305", + "Chapoly", + "Curve25519", + "Ed25519", + "EdDSA", + "Edwards-curve Digital Signature Algorithm", + "Elliptic Curve Diffie-Hellman", + "Poly1305", + "Pure-PHP cryptography", + "RFC 7748", + "RFC 8032", + "Salpoly", + "Salsa20", + "X25519", + "XChaCha20-Poly1305", + "XSalsa20-Poly1305", + "Xchacha20", + "Xsalsa20", + "aead", + "cryptography", + "ecdh", + "elliptic curve", + "elliptic curve cryptography", + "encryption", + "libsodium", + "php", + "public-key cryptography", + "secret-key cryptography", + "side-channel resistant" + ], + "time": "2020-03-20T21:48:09+00:00" + }, + { + "name": "phpseclib/phpseclib", + "version": "2.0.27", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "34620af4df7d1988d8f0d7e91f6c8a3bf931d8dc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/34620af4df7d1988d8f0d7e91f6c8a3bf931d8dc", + "reference": "34620af4df7d1988d8f0d7e91f6c8a3bf931d8dc", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phing/phing": "~2.7", + "phpunit/phpunit": "^4.8.35|^5.7|^6.0", + "sami/sami": "~2.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "suggest": { + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "type": "library", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], + "time": "2020-04-04T23:17:33+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "psr/log", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2020-03-23T09:12:05+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "3bff59ea7047e925be6b7f2059d60af31bb46d6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/3bff59ea7047e925be6b7f2059d60af31bb46d6a", + "reference": "3bff59ea7047e925be6b7f2059d60af31bb46d6a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/polyfill-mbstring": "^1.3", + "symfony/polyfill-php72": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "fa79b11539418b02fc5e1897267673ba2c19419c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fa79b11539418b02fc5e1897267673ba2c19419c", + "reference": "fa79b11539418b02fc5e1897267673ba2c19419c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "f048e612a3905f34931127360bdd2def19a5e582" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/f048e612a3905f34931127360bdd2def19a5e582", + "reference": "f048e612a3905f34931127360bdd2def19a5e582", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "1.1.0" +} diff --git a/tests/Resources/fixtures/security/security-advisories/aws/aws-sdk-php/CVE-2015-5723.yaml b/tests/Resources/fixtures/security/security-advisories/aws/aws-sdk-php/CVE-2015-5723.yaml new file mode 100644 index 00000000..52327efe --- /dev/null +++ b/tests/Resources/fixtures/security/security-advisories/aws/aws-sdk-php/CVE-2015-5723.yaml @@ -0,0 +1,8 @@ +title: Security Misconfiguration Vulnerability in the AWS SDK for PHP +link: https://github.com/aws/aws-sdk-php/releases/tag/3.2.1 +cve: CVE-2015-5723 +branches: + 3.x: + time: 2015-07-24 0:41:41 + versions: ['>=3.0.0', '<3.2.1'] +reference: composer://aws/aws-sdk-php diff --git a/tests/Resources/fixtures/security/security-advisories/bogus/bogus.yaml b/tests/Resources/fixtures/security/security-advisories/bogus/bogus.yaml new file mode 100644 index 00000000..9977a283 --- /dev/null +++ b/tests/Resources/fixtures/security/security-advisories/bogus/bogus.yaml @@ -0,0 +1 @@ +invalid diff --git a/tests/Resources/fixtures/security/security-advisories/fuel/core/2016-06-29-1.yaml b/tests/Resources/fixtures/security/security-advisories/fuel/core/2016-06-29-1.yaml new file mode 100644 index 00000000..b728ef83 --- /dev/null +++ b/tests/Resources/fixtures/security/security-advisories/fuel/core/2016-06-29-1.yaml @@ -0,0 +1,8 @@ +title: ImageMagick driver does not escape all shell arguments. +link: https://fuelphp.com/security-advisories +cve: ~ +branches: + master: + time: 2016-09-27 08:06:00 + versions: ['<1.8.0.4'] +reference: composer://fuel/core diff --git a/tests/Resources/fixtures/security/security-advisories/fuel/core/2018-04-14-1.yaml b/tests/Resources/fixtures/security/security-advisories/fuel/core/2018-04-14-1.yaml new file mode 100644 index 00000000..aa51366d --- /dev/null +++ b/tests/Resources/fixtures/security/security-advisories/fuel/core/2018-04-14-1.yaml @@ -0,0 +1,8 @@ +title: Crypt encryption compromised. +link: https://fuelphp.com/security-advisories +cve: ~ +branches: + master: + time: 2018-04-16 17:23:00 + versions: ['<1.8.1'] +reference: composer://fuel/core diff --git a/tests/Resources/fixtures/security/security-advisories/ignore.txt b/tests/Resources/fixtures/security/security-advisories/ignore.txt new file mode 100644 index 00000000..a4de8e4b --- /dev/null +++ b/tests/Resources/fixtures/security/security-advisories/ignore.txt @@ -0,0 +1 @@ +should be ignored diff --git a/tests/Resources/fixtures/security/security-advisories/symfony/http-kernel/CVE-2014-5245.yaml b/tests/Resources/fixtures/security/security-advisories/symfony/http-kernel/CVE-2014-5245.yaml new file mode 100644 index 00000000..b945b48d --- /dev/null +++ b/tests/Resources/fixtures/security/security-advisories/symfony/http-kernel/CVE-2014-5245.yaml @@ -0,0 +1,23 @@ +title: Direct access of ESI URLs behind a trusted proxy +link: https://symfony.com/cve-2014-5245 +cve: CVE-2014-5245 +branches: + 2.0.x: + time: 2014-09-03 07:40:02 + versions: ['>=2.0.0', '<2.1.0'] + 2.1.x: + time: 2014-09-03 07:40:02 + versions: ['>=2.1.0', '<2.2.0'] + 2.2.x: + time: 2014-09-03 07:40:02 + versions: ['>=2.2.0', '<2.3.0'] + 2.3.x: + time: 2014-09-03 07:40:02 + versions: ['>=2.3.0', '<2.3.19'] + 2.4.x: + time: 2014-09-03 07:40:02 + versions: ['>=2.4.0', '<2.4.9'] + 2.5.x: + time: 2014-09-03 07:40:02 + versions: ['>=2.5.0', '<2.5.4'] +reference: composer://symfony/http-kernel diff --git a/tests/Resources/fixtures/security/security-advisories/symfony/http-kernel/CVE-2015-2308.yaml b/tests/Resources/fixtures/security/security-advisories/symfony/http-kernel/CVE-2015-2308.yaml new file mode 100644 index 00000000..a22d677f --- /dev/null +++ b/tests/Resources/fixtures/security/security-advisories/symfony/http-kernel/CVE-2015-2308.yaml @@ -0,0 +1,26 @@ +title: Esi Code Injection +link: https://symfony.com/cve-2015-2308 +cve: CVE-2015-2308 +branches: + 2.0.x: + time: 2015-04-01 18:55:26 + versions: ['>=2.0.0', '<2.1.0'] + 2.1.x: + time: 2015-04-01 18:55:26 + versions: ['>=2.1.0', '<2.2.0'] + 2.2.x: + time: 2015-04-01 18:55:26 + versions: ['>=2.2.0', '<2.3.0'] + 2.3.x: + time: 2015-04-01 18:55:26 + versions: ['>=2.3.0', '<2.3.27'] + 2.4.x: + time: 2015-04-01 18:55:26 + versions: ['>=2.4.0', '<2.5.0'] + 2.5.x: + time: 2015-04-01 18:55:26 + versions: ['>=2.5.0', '<2.5.11'] + 2.6.x: + time: 2015-04-01 18:55:26 + versions: ['>=2.6.0', '<2.6.6'] +reference: composer://symfony/http-kernel diff --git a/tests/Resources/fixtures/security/security-advisories/symfony/http-kernel/CVE-2019-18887.yaml b/tests/Resources/fixtures/security/security-advisories/symfony/http-kernel/CVE-2019-18887.yaml new file mode 100644 index 00000000..bf7c7229 --- /dev/null +++ b/tests/Resources/fixtures/security/security-advisories/symfony/http-kernel/CVE-2019-18887.yaml @@ -0,0 +1,53 @@ +title: "CVE-2019-18887: Use constant time comparison in UriSigner" +link: https://symfony.com/cve-2019-18887 +cve: CVE-2019-18887 +branches: + 2.2.x: + time: ~ + versions: ['>=2.2.0', '<2.3.0'] + 2.3.x: + time: ~ + versions: ['>=2.3.0', '<2.4.0'] + 2.4.x: + time: ~ + versions: ['>=2.4.0', '<2.5.0'] + 2.5.x: + time: ~ + versions: ['>=2.5.0', '<2.6.0'] + 2.6.x: + time: ~ + versions: ['>=2.6.0', '<2.7.0'] + 2.7.x: + time: ~ + versions: ['>=2.7.0', '<2.8.0'] + 2.8.x: + time: 2019-11-13 08:00:00 + versions: ['>=2.8.0', '<2.8.52'] + 3.0.x: + time: ~ + versions: ['>=3.0.0', '<3.1.0'] + 3.1.x: + time: ~ + versions: ['>=3.1.0', '<3.2.0'] + 3.2.x: + time: ~ + versions: ['>=3.2.0', '<3.3.0'] + 3.3.x: + time: ~ + versions: ['>=3.3.0', '<3.4.0'] + 3.4.x: + time: 2019-11-13 08:00:00 + versions: ['>=3.4.0', '<3.4.35'] + 4.0.x: + time: ~ + versions: ['>=4.0.0', '<4.1.0'] + 4.1.x: + time: ~ + versions: ['>=4.1.0', '<4.2.0'] + 4.2.x: + time: 2019-11-13 08:00:00 + versions: ['>=4.2.0', '<4.2.12'] + 4.3.x: + time: 2019-11-13 08:00:00 + versions: ['>=4.3.0', '<4.3.8'] +reference: composer://symfony/http-kernel diff --git a/tests/Unit/Service/Security/SensioLabsSecurityCheckerTest.php b/tests/Unit/Service/Security/SensioLabsSecurityCheckerTest.php new file mode 100644 index 00000000..098c504d --- /dev/null +++ b/tests/Unit/Service/Security/SensioLabsSecurityCheckerTest.php @@ -0,0 +1,134 @@ +dbDir = sys_get_temp_dir().'/repman/security-advisories'; + $this->fixturesDir = __DIR__.'/../../../Resources/fixtures/security/locks'; + + $filesystem = new Filesystem(); + $filesystem->mirror( + __DIR__.'/../../../Resources/fixtures/security/security-advisories', + $this->dbDir + ); + + $this->checker = new SensioLabsSecurityChecker($this->dbDir, 'bogus'); + } + + public function testInvalidLockFile(): void + { + $this->expectException(\UnexpectedValueException::class); + $this->expectExceptionMessage('Invalid composer.lock'); + + $this->checker->check('invalid'); + } + + public function testMissingDatabase(): void + { + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('Advisories database does not exist'); + + $this->checker = new SensioLabsSecurityChecker(sys_get_temp_dir().'/bogus-security-advisories', ''); + $this->checker->check($this->insecureLock()); + } + + public function testEmptyLockFile(): void + { + self::assertEquals($this->checker->check('{}'), []); + } + + public function testSuccessfulScanWithAlerts(): void + { + self::assertEqualsCanonicalizing($this->checker->check($this->insecureLock()), [ + 'aws/aws-sdk-php' => [ + 'version' => '3.2.0', + 'advisories' => [ + [ + 'title' => 'Security Misconfiguration Vulnerability in the AWS SDK for PHP', + 'cve' => 'CVE-2015-5723', + 'link' => 'https://github.com/aws/aws-sdk-php/releases/tag/3.2.1', + ], + ], + ], + 'fuel/core' => [ + 'version' => '1.8.0', + 'advisories' => [ + [ + 'title' => 'ImageMagick driver does not escape all shell arguments.', + 'cve' => '', + 'link' => 'https://fuelphp.com/security-advisories', + ], + [ + 'title' => 'Crypt encryption compromised.', + 'cve' => '', + 'link' => 'https://fuelphp.com/security-advisories', + ], + ], + ], + 'symfony/http-kernel' => [ + 'version' => 'v2.3.0', + 'advisories' => [ + [ + 'title' => 'CVE-2019-18887: Use constant time comparison in UriSigner', + 'cve' => 'CVE-2019-18887', + 'link' => 'https://symfony.com/cve-2019-18887', + ], + [ + 'title' => 'Direct access of ESI URLs behind a trusted proxy', + 'cve' => 'CVE-2014-5245', + 'link' => 'https://symfony.com/cve-2014-5245', + ], + [ + 'title' => 'Esi Code Injection', + 'cve' => 'CVE-2015-2308', + 'link' => 'https://symfony.com/cve-2015-2308', + ], + ], + ], + ]); + } + + public function testSuccessfulScanWithoutAlerts(): void + { + self::assertEquals($this->checker->check($this->safeLock()), []); + } + + public function testUpdateWithGitClone(): void + { + $this->expectException(ProcessFailedException::class); + $this->checker->update(); + } + + public function testUpdateWithGitPull(): void + { + $this->expectException(ProcessFailedException::class); + $git = $this->dbDir.'/.git'; + @mkdir($git); + $this->checker->update(); + @rmdir($git); + } + + private function insecureLock(): string + { + return (string) file_get_contents($this->fixturesDir.'/insecure-composer.lock'); + } + + private function safeLock(): string + { + return (string) file_get_contents($this->fixturesDir.'/safe-composer.lock'); + } +}