Automatically controlling dependencies security with SensioLabs security checker, Jenkins
Today, we use more and more external libraries in our projects. Though it saves us time, it is possible that we may introduce security vulnerabilities via these libraries. Controlling this is unfortunately not systematic, and particularly seldom automated. SensioLabs offers a service to reference vulnerabilities (CVE) in many libraries, and use the Security Checker tool to check the dependencies of a project via the composer.lock file.
Security Checker
One can find this tool on Github as a Phar or library to add to a project. For example, I use the Phar version I added in my path for ease of use. I created an empty project by adding versions of libraries known to have a flaw. The use of the Security Checker is simple and provides a very clear result.
~/blog$ security-checker.phar security:check ./composer.lock Security Check Report ~~~~~~~~~~~~~~~~~~~~~ Checked file: /home/ulrich/blog/composer.lock [CRITICAL] 3 packages have known vulnerabilities doctrine/doctrine-bundle (v1.2.0) --------------------------------- * CVE-2015-5723: Security Misconfiguration Vulnerability in various Doctrine projects http://www.doctrine-project.org/2015/08/31/security_misconfiguration_vulnerability_in_various_doctrine_projects.html doctrine/orm (v2.3.6) --------------------- * CVE-2015-5723: Security Misconfiguration Vulnerability in various Doctrine projects http://www.doctrine-project.org/2015/08/31/security_misconfiguration_vulnerability_in_various_doctrine_projects.html zendframework/zend-json (2.2.1) ------------------------------- * Potential XXE/XEE attacks using PHP functions: simplexml_load_*, DOMDocument::loadXML, and xml_parse http://framework.zend.com/security/advisory/ZF2014-01 This checker can only detect vulnerabilities that are referenced Disclaimer in the SensioLabs security advisories database. Execute this command regularly to check the newly discovered vulnerabilities.
Automation
Like many (hopefully) I use a continuous integration tool, Jenkins in this case. I use Phing as the project builder - it is a great tool, even if it is an older one. This is an opportunity to talk a little about Phing and show how to make this job a little more "intelligent".At the end of th post I give snippet for Ant and Jenkins pipeline.
Basically I could create a task as follows:
<project name="checksecu" basedir="." default="secu"> <target name="secu"> <exec executable="security-checker.phar"> <arg value="security:check" /> <arg path="./composer.lock" /> </exec> </target> </project>
The execution provides:
~/blog$ phing.phar -f ../jenkinsbuildconf/checksecu.xml Buildfile: /home/ulrich/blog/../jenkinsbuildconf/checksecu.xml checksecu > secu: BUILD FINISHED Total time: 0.4584 seconds
The first problem is that I have no return, and the second problem is the build will never be checked for errors. To handle this, I will get the script output in a variable via outputProperty and display it. Then I can use checkreturn, giving me:
<project name="checksecu" basedir="." default="secu"> <target name="secu"> <exec executable="security-checker.phar" outputProperty="output" checkreturn="true"> <arg value="security:check" /> <arg path="./composer.lock" /> </exec> <echo message="output: ${output}" /> </target> </project>
And the execution provides:
~/blog$ phing.phar -f ../jenkinsbuildconf/checksecu.xml Buildfile: /home/ulrich/blog/../jenkinsbuildconf/checksecu.xml checksecu > secu: Execution of target "secu" failed for the following reason: /home/ulrich/blog/../jenkinsbuildconf/checksecu.xml:6:60: Task exited with code 1 BUILD FAILED /home/ulrich/blog/../jenkinsbuildconf/checksecu.xml:6:60: Task exited with code 1 Total time: 0.9041 seconds
Super, my build failed, but I don't have the output of security-checker.phar, which is annoying. I'll replace checkreturn with returnProperty to store the exit code of the command in a variable and then test it with an if.
<project name="checksecu" basedir="." default="secu"> <target name="secu"> <exec executable="security-checker.phar" outputProperty="output" returnProperty="return"> <arg value="security:check" /> <arg path="./composer.lock" /> </exec> <if> <equals arg1="${return}" arg2="1" /> <then> <echo message="output: ${output}" /> <fail message="Le composer.lock montre que le projet se base sur des libs ayant des CVE." /> </then> </if> </target> </project>
This execution provides:
~/blog$ phing.phar -f ../jenkinsbuildconf/checksecu.xml Buildfile: /home/ulrich/blog/../jenkinsbuildconf/checksecu.xml checksecu > secu: [echo] output: Security Check Report ~~~~~~~~~~~~~~~~~~~~~ Checked file: /home/ulrich/blog/composer.lock [CRITICAL] 3 packages have known vulnerabilities doctrine/doctrine-bundle (v1.2.0) --------------------------------- * CVE-2015-5723: Security Misconfiguration Vulnerability in various Doctrine projects http://www.doctrine-project.org/2015/08/31/security_misconfiguration_vulnerability_in_various_doctrine_projects.html doctrine/orm (v2.3.6) --------------------- * CVE-2015-5723: Security Misconfiguration Vulnerability in various Doctrine projects http://www.doctrine-project.org/2015/08/31/security_misconfiguration_vulnerability_in_various_doctrine_projects.html zendframework/zend-json (2.2.1) ------------------------------- * Potential XXE/XEE attacks using PHP functions: simplexml_load_*, DOMDocument::loadXML, and xml_parse http://framework.zend.com/security/advisory/ZF2014-01 This checker can only detect vulnerabilities that are referenced Disclaimer in the SensioLabs security advisories database. Execute this command regularly to check the newly discovered vulnerabilities. Execution of target "secu" failed for the following reason: /home/ulrich/blog/../jenkinsbuildconf/checksecu.xml:11:12: /home/ulrich/blog/../jenkinsbuildconf/checksecu.xml:15:30: Le composer.lock montre que le projet se base sur des libs ayant des CVE. BUILD FAILED /home/ulrich/blog/../jenkinsbuildconf/checksecu.xml:11:12: /home/ulrich/blog/../jenkinsbuildconf/checksecu.xml:15:30: Le composer.lock montre que le projet se base sur des libs ayant des CVE. Total time: 0.4784 seconds
There you go! All I need to do is add this task to my General phing build for Jenkins to run, and it will systematically test if my project is based on a library version with any known CVE. For those who prefer Ant to Phing, I think that this task can be very easily transferable if not reusable as is.
If you are using Ant instead of Phing, this is the task you could write in your build file:
<target name="checks:security" description="Checks if there is some security issues in our back-end dependencies"> <exec executable="security-checker.phar" failonerror="true"> <arg line="security:check composer.lock"/> </exec> </target>
If you are using pipeline in Jenkins, this is the snippet I used in my Jenkinsfile
stage ('Check Security') { steps { sh 'security-checker.phar security:check composer.lock' } }
Add a comment