Security Tip: Safely Updating Dependencies
[Tip #131] Updating packages used to be a no-brainer, but now you need to be careful. Updates may be malicious. But not updating leaves vulns unpatched. So what do you do??? 🤷
I've written many times about keeping your dependencies updated, and it used to be an easy process: you'd designate one day a week, fortnight, or month, jump into your command line and run:
composer update && npm updateWait for it to finish, run your tests, and commit. Job done.
But now?
As we talked about last week, dependencies are being targeted with malicious releases, and if one of your dependencies gets compromised, your seemingly innocent npm update could pull in a worm that infects your environment, scrapes your tokens, infects packages you maintain, and more...
As a friend said to me recently:
"I've been honestly scared to do those updates."
So what do we do??
The first thing you should do (somewhat ironically) is to update both composer and npm (or whatever tool you use instead) to the latest versions, and keep them updated. The package manager communities are working hard on security updates at the moment, so pulling in the latest versions will get you those updates and default behaviours which are designed to keep your apps safer.
Composer 2.10 has added a Malware Policy that uses a malware threat feed from Aikido to identify flagged package versions. With this update, package versions identified as malicious will no longer be available to install or update, and versions with security advisories can be installed but not updated to. Composer will also no longer fallback to downloading the raw source if a distribution artifact fails - which could be abused when dealing with custom composer repositories.
Minimum Release Age
Once you've updated these tools, Minimum Release Age is the next thing you want to enable. This defines how old a release needs to be before it is allowed to be used for your app. For example, if you set it to 3 days, an update will only be applied after it has been available for 3 days. This essentially gives security researchers 3 days to notice and block a malicious version.
npm added it in v11.10.0 and you define it using the min-release-age flag in your .npmrc file, specifying the number of days:
min-release-age=3
.npmrc
The downside of Minimum Release Age is you lose immediate access to critical security updates - and those 3 days could be critical for an actively exploited vulnerability. However, my recommendation here is to keep it enabled and if a security fix comes along, either lower it or use min-release-age-exclude to get the update sooner.
When Composer rolls this feature out, it'd be a good idea to enable it too. For npm packages when your app is a Laravel app, a couple of days should be safe - there are a limited set of vulnerabilities that can be exploited in your front end (although XSS would still be a critical issue!). When it comes to Composer, I'd be inclined to look at hours instead - security updates are a lot more important when your server is potentially exposed. But you really need to define your own risk levels here.
Disable Scripts
Another simple thing you can do is disable scripts and plugins in Composer when you don't need them to run:
composer install --no-plugins --no-scriptsThis option is also available for npm:
npm install --ignore-scriptsThis is incredibly useful when you're downloading third party code for review with no intention of actually running it locally. It should prevent any malicious code included within any of the installed packages from being executed, which is usually how these attacks propagate.
Other Tools
This is getting a bit long for a tip, so let's wrap up with some brief mentions of other tools you can use:
- Canary Tokens - install these in all of your environments and you'll get notified if anyone is sniffing around or harvesting credentials, rather than after a successful compromise when you're cleaning up the mess.
- Socket Firewall - a free security tool that prevents supported package managers (
npm,yarn,pnpm,pip,uv, andcargo) from installing malicious versions, provided by Socket, a third-party supply chain security company.
If you have other suggestions or know of other tools that help with this, let me know in the comments so others can see them too.
Found this security tip useful? 👍
Subscribe now to get weekly Security Tips straight to your inbox, filled with practical, actionable advice to help you build safer apps.
Want to learn more? 🤓
Upgrade to a Premium Subscription for exclusive monthly In Depth articles! Your support directly funds my security work in the Laravel community. 🥰
Need a second set of eyes on your code?
Book in a Laravel Security Audit and Penetration Test today! I offer budget-friendly Security Reviews too.
Finally, connect with me on Twitter, Bluesky, phpc.social, and LinkedIn.