Trusting Untrusted Dependencies

There is a real risk to business associated with the proliferation of external dependencies. Indeed, it makes development real faster and much more efficient, but there’s a fine line between accelerating the time to market to please your project manager, and dancing with a time bomb that is already ticking while chewing on glass. I’m not here to sell you on SBOM, SCA, third party dependency signatures and restrictive security control, don’t worry! But i think it’s important that at least, developers know what they are dealing with and be equipped with minimal knowledge that will go much farther than any other super restrictive control organizations can put in place.

The Tell-tale Signs

First and foremost, you need to at least consider and acknowledge to yourself that, almost every dependency that you bring in your software development / automation projects are “untrusted code written by someone that you don’t know shit about”. I’m the type of person who believes that most people have good intentions and want to do the right things. But you can never know until you really try to know the person and understand their motivations. I think you need to take a good hard look under the hood to know what is up. So what’s the point I’m trying to make in regards to software dependencies ? The point is that, in most of those dependencies, there is information that is available for your eyes to see; the company, the name, the version, the source code, the reputation, and so on. Some of that information are easy to see and are basically right there available for you, but some of them will require you to put on your OSINT hat and do some digging. Especially in critical projects where security should be one of your main focus. Let’s face it, you wouldn’t want to build something critical wrapped around an unknown dependency.

So how can you make sure that the what you bring in is good, and will do what is supposed to do ? I guess the first step is to try to understand how bad actors are trying to smuggle in some bad code that can potentially make your life miserable. There’s almost and always the same tell-tale signs that a dependency is bad to fetch. The tactics, techniques and procedures are for the most part (as in late 2024) gravitating around the same attack types.

Here is a list of the most popular attack method used by threat actors, we will then try to unwrap them in the context of a developer.

1. Dependencies Confusion
2. Malware
3. Typosquatting

1. Dependencies Confusion

In short, a dependency confusion attack is the type of attack that consists of someone (probably a bad actor), exploiting a system that uses both public and private package repositories. For example, many modern software project uses package managers like npm, pip or NuGet, to fetch and manage their dependencies. Those package managers are usually hosted out there on the internet, and anyone can download from them. Now on the local side of things, many mid-size to big-size organizations use internal repository, self-hosted or rented, to host dependency or to fetch from remote repo (many also uses a combination of both public and private package manager).

Dependency confusion attack occurs when the local package manager mistakenly downloads a malicious package from a public repository instead of the intended internal package. The attacker leverages the fact that many organizations name their dependencies using a consistent and predictable naming convention (e.g., internal-payment-lib). That information can be often easily accessible via leaked source code online, by analyzing error messages, logs or mentioning internal package names in comment.

To perform the attack, the attacker publishes a malicious package on a public repository with the same name as one of the organization’s internal packages, but the twist is, the attacker just need to set a higher version number, since most modern package manager prioritize higher version numbers assuming by design that they are more up-to-date. So in short, if the organization hasn’t specifically configured the package manager to strictly prioritize private and internal repositories, the malicious package is downloaded and baked in the software, giving the attacker execution of arbitrary code on the software or system.

So what’s in it for you as a developer ? Mmm, there’s not much you can do about this one but you can pin a specific version of a dependency burned into the code. Remember that with great power comes great responsibility, since doing that will require you to stay up-to-date with current CVE on a specific version and update to the latest one when necessary. If you are responsible for managing your internal package repository, try to configure the platform to not source automatically dependencies from the internet, it’s much better to bring in an older version of a dependency than bringing in unwanted software.

2. Malware

Yes, there is malware in public package manager. It’s like the public pool in your city. You probably swim in it, but no way you’ll pour yourself a glass of water. The good news is that the community is doing a great job at vouching a lot of public source code and are on the constant lookout for a sneaky mofo trying to hide bad code into seemingly legitimate code. The risk of using dependency must always be remembered since there is a whole spectrum of malware that has, and will continue to spread there. Just to name a few attack types :

1. Credential stealers
2. Data exfiltration
3. Cryptocurrency miners
4. Remote Access Trojans
5. Command execution 
6. Watering hole attacks
7 ...

You can reduce the risk by avoiding less popular dependency or obscure one. Try sticking to the popular one or at least, some that have been in use for some times and had the time to be slightly scrutinized by the community. In the end, remember that it’s a code that someone else wrote. Check and double-check, verify the packages, and to reduce the risks associated with malware in dependencies, try avoiding bringing in unnecessary dependencies in the name of reducing the attack surface of your program.

3. Typosquatting

This type of attack is specifically targetted to you my sweet ADHDevOps brain. It leverage the fact that you don’t pay attention to small details. This is a very old type of attack that was heavily used in phishing email. I’m sure you already received one weird email from [email protected] asking you to log in your Amazon account. This attack use the same principle, but you do not need to perform any actions other than a type of dependency name.

It’s so simple, yet so beautiful ;

import requet

Instead of :

import request

In short, the attacker just needs to publish bad code (that work in appearance, but with slight changes to suit his needs) to a public repository, with a minor change in the dependency name. It’s just subtle enough so that busy people will pull in a malicious dependency and probably will never notice until someone review the source code or until you take your an adderall that day and realize how distracted you’ve been trying to close those Jira tickets.

How to check for known vulnerable dependency ?

There is a wide range of resources available for you on the internet. I will not try to push you into any particular product, but i can give you some directions and point you to some very well known and respected organizations that keep a list of known vulnerability. For the most part, they all offer API integration, or tooling so you can wrap your desired processes around those platforms or integrate their tools into your current SDLC.

1. Sonatype - https://ossindex.sonatype.org/search 
2. MITRE - https://www.cve.org/ 
3. NIST - NVD (National Vulnerability Database) - https://nvd.nist.gov/ 
4. OWASP - Dependency Check - https://owasp.org/www-project-dependency-check/ 

The End

So this it, that was my short take on dependencies, the risk associated with modern developments, the 3 major types of attack targetting developers in late 2024 and some tips on how to keep track of known vulnerabilities. In the end, don’t forget to breathe, relax and pay attention to what you pull in.