Development teams rarely perform code reviews on third-party dependencies, but the libraries and toolkits we use are often a source of software vulnerabilities. As a site owner, you need to ensure code written by other people is not making your system insecure.
Almost every kind of website vulnerability has manifested itself in commonly used software libraries at some point:
- SQL Injection vulnerabilities that allow execution of arbitrary SQL statements against a database.
- Command Injection vulnerabilities that allow execution of arbitrary scripts on the server.
Including these vulnerabilities into you systems opens you (and your users) to data theft, infection by malware, and system takeover.
Increasingly, dependencies are a vector for “supply-chain attacks”, where an attacker injects malicious code into third-party software. Researchers have revealed how easy it is to inject malicious code via badly configured build processes.
Careful consideration of how you manage dependencies is key to keeping your system secure. There are number of aspects you need to get right.
Automate your build and deployment processes. To make your code secure, you need to know what code you are running. This means declaring all third-party libraries within build scripts or dependency management systems; building and deploying from source control; and keeping records of deployment logs.
Deploy known-good versions of software. Dependency management tools often allow you to leave the version of each dependency indeterminate, which is shorthand for “grab the latest available version at build time.” Try to avoid this - upgrade versions deliberately, when you have had chance to review the release notes, and pin dependency versions in your code.
Be careful of private dependencies. Large organizations often mix public and private dependencies in the same codebase. You should be careful how you configure the precedence of repositories in your build process, since dependency confusion attacks - where an attacker uploads a malicious copy of a private dependency to a public repository - have caught many organizations off guard.
Use dedicated tools to scan your dependency tree for security risks. Many programming languages and utilities are able to spot compromised dependencies. Consider using one or more of the following:
- Github security alerts
- GitLab security scanning
bundler auditfor Ruby.
- OWASP dependency-check for Java and .NET
Keep on top of security bulletins. Make sure your team is on the lookout for security announcements for the software you use. This can mean signing up for mailing lists, joining forums, or following library developers on social media. The development community is often the first become aware of security issues.
Perform regular code reviews so your whole development team knows what third-party libraries are being used, and which parts of your codebase depend on them.
Make penetration testing part of your development lifecycle. Penetration testing tools will attempt to take advantage of known exploits, checking whether your technology stack contains vulnerable components.
If you don’t yet use dependency management, you probably should start. Here are the most popular dependency management systems for some major programming languages: