public function execute() { // Handle the skip option if (Context::get('information-collector')->getValueFor(self::SKIP_OPTION)) { Context::get('output')->writeln('<error>composer security check skipped</error>'); return; } Context::get('output')->writeln('<comment>running composer security check</comment>'); // run the actual security check $checker = new SecurityChecker(); $alerts = $checker->check('composer.lock'); // exit succesfull if everything is fine if (count($alerts) == 0) { $this->confirmSuccess(); return; } // print out the advisories if available foreach ($alerts as $package => $alert) { Context::get('output')->writeln("<options=bold>{$package}</options=bold> {$alert['version']}"); foreach ($alert['advisories'] as $data) { Context::get('output')->writeln(''); Context::get('output')->writeln($data['title']); Context::get('output')->writeln($data['link']); Context::get('output')->writeln(''); } } // throw exception to have check fail throw new \Exception('composer.lock contains insecure packages (you can force a release with option --' . self::SKIP_OPTION . ')'); }
public function securityAdvisoriesCheck() { $path = $this->getComposerLockPath(); //$this->io->write("Path: " . $path); $checker = new SecurityChecker(); $alerts = $checker->check($path); if (count($alerts) == 0) { $this->io->write("All good from SensioLabs security advisories."); } else { $this->io->write("ALERTS from SensioLabs security advisories."); $this->io->write(""); foreach ($alerts as $projectName => $project) { $version = $project['version']; //print_r($project); $this->io->write(" *** " . $projectName . "[" . $version . "] *** "); $this->io->write(""); foreach ($project['advisories'] as $advisoryName => $advisory) { $this->io->write(" * " . $advisoryName); $this->io->write($advisory['title']); $this->io->write($advisory['link']); $this->io->write($advisory['cve']); $this->io->write(""); } $this->io->write(""); } $this->io->write("Please fix these alerts from SensioLabs security advisories."); } }
public function fire() { $checker = new SecurityChecker(); try { $alerts = $checker->check(base_path() . '/composer.lock'); if (!empty($alerts)) { foreach ($alerts as $package => $alert) { $this->error('Security advisories found!'); $this->info('======================'); $this->info('Package: ' . $package); foreach ($alert['advisories'] as $advisory) { $this->info('Version: ' . $alert['version']); $this->info('Title: ' . $advisory['title']); $this->info('Link: ' . $advisory['link']); if ($advisory['cve'] != "") { $this->info('CVE: ' . $advisory['cve']); } } } } else { $this->info('No security advisories found!'); } } catch (RuntimeException $e) { $this->error('Security check failed: ' . $e->getMessage()); } }
function it_push_error_message_and_alerts_when_vulnerability_found(SecurityChecker $securityChecker, ConsumerEvent $event, Message $message, \Pusher $pusher) { $event->getMessage()->shouldBeCalled()->willReturn($message); $message->getValue('channelName')->shouldBeCalled()->willReturn('new_channel'); $pusher->trigger('new_channel', 'consumer:new-step', array('message' => 'Checking vulnerability'))->shouldBeCalled(); $securityChecker->check(sys_get_temp_dir() . '/composer_dir/composer.lock', 'text')->shouldBeCalled()->willReturn($this->getVulnerabilityMessage()); $securityChecker->getLastVulnerabilityCount()->shouldBeCalled()->willReturn(1); $pusher->trigger('new_channel', 'consumer:step-error', array('message' => 'Vulnerability found : 1'))->shouldBeCalled(); $pusher->trigger('new_channel', 'consumer:vulnerabilities', array('message' => $this->getVulnerabilityMessage()))->shouldBeCalled(); $this->execute($event, 'composer_dir')->shouldReturn(0); }
public function execute() { $this->phpci->logExecOutput(false); $checker = new SecurityChecker(); $alerts = $checker->check($this->phpci->buildPath . '/composer.lock'); $this->build->storeMeta('composer-security-check-errors', $alerts); if (!$alerts) { return true; } return false; }
/** * @param $organization * @param array $repository */ private function checkComposerLock($organization, array $repository) { $tempFile = tempnam(sys_get_temp_dir(), 'sec'); $handle = fopen($tempFile, 'w'); fwrite($handle, $this->client->api('repo')->contents()->download($organization, $repository['name'], 'composer.lock')); fclose($handle); $alerts = $this->securityChecker->check($tempFile); $contributors = $this->client->api('repo')->contributors($organization, $repository['name']); $this->alertHandler->handleAlerts($repository, $contributors, $alerts); unlink($tempFile); }
/** * @throws \Exception */ public function handle() { \Log::info('QA::COMPOSER-SECURITY Run composer security checker'); $checker = new SecurityChecker(); $alerts = $checker->check('composer.lock'); if ($alerts !== false && !empty($alerts)) { $formatter = new TextFormatter($this->getHelperSet()->get('formatter')); $formatter->displayResults($this->output, 'composer.lock', $alerts); throw new \Exception('Vulnerability detected'); } $this->info("No vulnerability detected"); }
protected function execute(InputInterface $input, OutputInterface $output) { $io = new SymfonyStyle($input, $output); $io->title('Secuirty Check'); $fileName = __DIR__ . 'composer.lock'; if ($this->logger) { $this->logger->info('Start security check on ' . $fileName); } //@see: https://github.com/sensiolabs/security-checker $checker = new SecurityChecker(); $alerts = $checker->check('composer.lock'); count($alerts) > 0 ? $io->error($alerts) : $io->success('security checked!'); }
/** * Execute the console command. * * @return void */ public function fire() { $lockFile = $this->argument('lock'); try { $data = $this->checker->check($this->argument('lock'), $this->option('format')); } catch (\Exception $e) { $this->error($e->getMessage()); return 1; } $this->info($data); if ($this->checker->getLastVulnerabilityCount() > 0) { return 1; } }
public function check() { try { if (!file_exists($this->lockFilePath) || !is_file($this->lockFilePath)) { return new Failure(sprintf('Cannot find composer lock file at %s', $this->lockFilePath), $this->lockFilePath); } elseif (!is_readable($this->lockFilePath)) { return new Failure(sprintf('Cannot open composer lock file at %s', $this->lockFilePath), $this->lockFilePath); } $advisories = $this->securityChecker->check($this->lockFilePath, 'json'); $advisories = @json_decode($advisories); if (null === $advisories) { return new Warning('Could not parse response from security advisory service.'); } if (!empty($advisories)) { return new Failure(sprintf('Found security advisories for %u composer package(s)', count($advisories)), $advisories); } } catch (\Exception $e) { return new Warning($e->getMessage()); } return new Success(sprintf('There are currently no security advisories for packages specified in %s', $this->lockFilePath)); }
/** * @param SS_HTTPRequest $request */ public function run($request) { // to keep the list up to date while removing resolved issues we keep all ids of again encountered issues $remainingEntries = array(); // use the security checker of $checker = new SecurityChecker(); $alerts = $checker->check($this->getPathToComposerlock()); // Are there any issues known? If so save the information in the database if (is_array($alerts) && !empty($alerts)) { // go through all alerts for packages - each can contain multiple issues foreach ($alerts as $package => $packageDetails) { // go through each individual known security issue foreach ($packageDetails['advisories'] as $details) { // check if this vulnerability is already known $vulnerability = ComposerSecurityVulnerability::get()->filter(array('Package' => $package, 'Version' => $packageDetails['version'], 'Title' => $details['title'])); // Is this vulnerability known? No, lets add it. if ((int) $vulnerability->count() === 0) { $vulnerability = new ComposerSecurityVulnerability(); $vulnerability->Package = $package; $vulnerability->Version = $packageDetails['version']; $vulnerability->Title = $details['title']; $vulnerability->ExternalLink = $details['link']; $vulnerability->CVE = $details['cve']; $vulnerability->write(); // add the new entries to the list of the remaining entries $remainingEntries[] = $vulnerability->ID; } else { // add all matching known vulnerabilities - this way we can keep those. $remainingEntries = array_merge($remainingEntries, $vulnerability->column('ID')); } } } } // remove all entries which are resolved (not in $remainingEntries) foreach (ComposerSecurityVulnerability::get()->exclude(array('ID' => $remainingEntries)) as $vulnerability) { $vulnerability->delete(); } // notify that the task finished. $this->message('The task finished running. You can find the updated information in the database now.'); }
/** * @throws \RuntimeException in case of curl missing, file not found, server not responding etc. * @throws \InvalidArgumentException in case of wrong format parameter */ public function run() { $output = $this->getOutputStream(); $file = $this->parameters->get('file', 'composer.lock'); $format = $this->parameters->get('format', 'text'); $silent = $this->parameters->get('silent', true); $checker = new SecurityChecker(); if (!$silent) { $output->write('Checking "' . $file . '" for known security vulnerabilities...'); } try { $alerts = $checker->check($file, $format); } catch (\Exception $e) { throw new \RuntimeException('Failure while running ' . __CLASS__ . ': ' . $e->getMessage()); } if (!$silent) { $output->writeln('done.'); } if (!$silent && $checker->getLastVulnerabilityCount() > 0) { $output->writeln('Number of found known vulnerabilities: ' . $checker->getLastVulnerabilityCount()); } if ($checker->getLastVulnerabilityCount() > 0) { $this->addError('Number of found known vulnerabilities after checking "' . $file . '": ' . $checker->getLastVulnerabilityCount()); $this->addError($alerts); } else { $this->addInfo('No known vulnerabilities found after checking "' . $file . '".'); } }
public function main() { if (!in_array($this->format, ['text', 'json'])) { throw new BuildException(sprintf('Unsupported format "%s"', $this->format)); } if (!file_exists($this->file)) { throw new BuildException('File not found'); } try { $checker = new SecurityChecker(); $alerts = $checker->check($this->file, $this->format); } catch (\Exception $e) { throw new BuildException('Exception with SecurityChecker : ' . $e->getMessage()); } if (!$checker->getLastVulnerabilityCount()) { $this->log("Great! The checker did not detected known* vulnerabilities in your project dependencies."); return; } print $alerts; if ($this->outputProperty) { $this->project->setProperty($this->outputProperty, $alerts); } $this->logError("Caution ! The checker detected package(s) that have known* vulnerabilities in your project. We recommend you to check the related security advisories and upgrade these dependencies."); }
/** * @test * @expectedException \BuildException */ public function throwsBuildExceptionWhenVulnerabilitiesFound() { $this->checker->expects($this->any())->method('getLastVulnerabilityCount')->will($this->returnValue(1)); $this->checkerTask->setLockfile(__FILE__); $this->checkerTask->main(); }