Audit Python Dependencies Before a Breach
Learn a practical, no-fluff approach to auditing Python dependencies for vulnerabilities using tools like safety, pip-audit, and automated CI/CD scanning.
Here’s the article:
Stop Waiting for a Breach: Auditing Python Dependencies the Right Way
It starts with a single pip install. You grab a library because the docs look good, it has a million stars on GitHub, and it solves your problem in three lines of code. You never think about the two hundred other packages that came along for the ride. Then, one day, your CI/CD pipeline fails. Or worse—your production server gets flagged by a security scanner.
If this sounds familiar, you are not alone. At PythonSkillset, we see teams treat dependency auditing like an afterthought, something you do when a CVE hits the news. But you don’t have to wait for a disaster. Here is a practical, no-fluff guide to auditing your Python dependencies for vulnerabilities, starting today.
Why Bother with an Audit?
The Python ecosystem is massive and fast-moving. A package you installed six months ago might have three critical vulnerabilities discovered since then. Your code didn’t change, but the world did.
Auditing is not about paranoia. It is about knowing exactly what you ship. It saves you from last-minute scrambles, embarrassing breaches, and that sinking feeling when you realize your requests library is from 2019.
Step 1: Start with a Simple pip list and pip freeze
Before you bring in fancy tools, understand what you have. Run this in your project environment:
pip list --format=columns
pip freeze > requirements.txt
Look at the sheer volume. Chances are, you have packages you don’t even remember installing. Notice the version numbers. If you see something like 1.0.0 from three years ago, that is a red flag.
Step 2: Use safety for a Quick Baseline
safety is a command-line tool made by the team behind PyUp. It checks your installed packages against a known vulnerability database.
First, install it:
pip install safety
Then run it:
safety check
It scans your environment and spits out a report. It will tell you the package name, the affected versions, the severity, and a link to the advisory. This is your starting point. PythonSkillset recommends running this as a first step in any new project review.
Step 3: Integrate pip-audit for CI/CD
safety is great, but it relies on a proprietary database for some features. For a fully open-source alternative, use pip-audit. It uses the PyPI JSON API and the Open Source Vulnerabilities (OSV) database.
Install it:
pip install pip-audit
Run it against your requirements.txt or your installed packages:
pip-audit -r requirements.txt
The output is clean and actionable. It can even exit with a non-zero code if it finds vulnerabilities, which means you can plug it directly into your CI pipeline. If a new CVE drops for a library you use, your build fails before you merge a single line of code.
Step 4: Go Deeper with Dependency Trees
Sometimes, the vulnerable package is not one you installed directly. It is a dependency of a dependency. pip-audit handles this, but you can also visualize the mess with pipdeptree.
pip install pipdeptree
pipdeptree -p <your-package>
This shows you the full tree. You might find that Django depends on asgiref, which depends on something ancient. Now you know exactly where the risk hides.
Step 5: Automate with GitHub Dependabot or GitLab Dependency Scanning
If your code lives on GitHub, enable Dependabot. It is free and built into the platform. It will automatically scan your requirements.txt, Pipfile, or pyproject.toml and open pull requests to update vulnerable packages.
You don’t have to do anything except merge the PR. For GitLab, the built-in Dependency Scanning does the same thing using gemnasium-python. PythonSkillset recommends setting the update frequency to weekly. Daily updates can be noisy, but weekly gives you a manageable cadence.
Step 6: Lock Your Dependencies with pip freeze or pipenv
Auditing is useless if your installed versions drift from your committed requirements. Always lock your environment.
If you use plain pip, run pip freeze > requirements.txt after every meaningful install. If you use pipenv, it creates a Pipfile.lock automatically. If you use Poetry, it creates a poetry.lock. Keep these files in version control.
When you audit, audit the lock file, not just the top-level requirements. That gives you the real picture.
What Do You Do When You Find a Vulnerability?
You run the audit. It finds something. Now what?
- Check if it affects your runtime. Is the vulnerable function something you actually call? If not, the risk might be low.
- Update the package.
pip install --upgrade <package>is often enough. - If no patch exists, pin the version and add a note to your project README. Monitor the advisory for updates.
- Consider alternatives. If a library is consistently slow to patch critical issues, it might be time to switch. At PythonSkillset, we have seen projects migrate from
Pillowtothumboror fromcryptographytoPyNaClspecifically for maintenance reliability.
A Note on False Positives
No scanner is perfect. You will get alerts for vulnerabilities that exist in theory but not in your actual execution path. Do not ignore them entirely. Document why it is a false positive for your project. That way, when a real alert comes, you do not have to second-guess yourself.
Make It a Habit
Auditing once is good. Auditing every week is better. Here is a simple schedule:
- Every Monday: Run
pip-auditon your main branch. - After every
pip install: Run a quicksafety checkbefore committing. - Before every release: Do a full tree audit and document the results.
This takes ten minutes a week. It is ten minutes that can save you a weekend of panic.
Final Thought
Your code is only as secure as its weakest dependency. The Python community is fast at releasing patches, but they cannot install them for you. That part is on you. Start your audit today. Not next sprint. Not when a CVE hits the news. Today.
Your future self—and your users—will thank you.
Comments
Questions, corrections, and tips stay visible for everyone reading this page.
Join the discussion
No comments yet
Be the first to leave a note — it helps the next reader.