pip safety check python dependencies: Secure Your Code from Vulnerabilities

Published:

Think your requirements.txt is safe?
Every pip install can bring known vulnerabilities, and a 650% rise in attacks on open source shows it’s no longer optional.
Use pip safety check python dependencies to catch issues before they hit production.
Run safety check on your environment or requirements file, export JSON for CI, and fail builds on high-severity finds.
This post shows quick commands, how to read results, and practical fixes so you can stop late-night security fires and keep releases moving.

Immediate Methods to Run a Python Dependency Vulnerability Check

BI4cb6_0WHuay6i7d2EJ4Q

A 650% increase in next-generation cyberattacks targeting open source tools makes scanning Python dependencies essential. Every pip install introduces code into your environment, and that code might carry known vulnerabilities. Running regular checks against both installed packages and requirements.txt catches issues before they reach production.

pip-audit scans your current environment with a single command: pip-audit. To check a requirements file before installation, run pip-audit -r requirements.txt. For JSON output that’s easier to parse in scripts or CI, use pip-audit --format json > audit.json. This tool queries the Python Packaging Advisory Database through PyPI’s JSON API and returns results in seconds.

Safety works similarly. Run safety check to scan installed packages, or safety check -r requirements.txt to audit a file. For a detailed breakdown, use safety check --full-report, which lists every vulnerability with context. JSON output is available via safety check --json > safety.json, making it straightforward to integrate into automated workflows or parse with tools like jq.

When reviewing vulnerability results, focus on these fields:

fixed_in shows the version number where the vulnerability was patched. Upgrade to this or later.

advisory ID gives you the CVE or OSV identifier you can look up for full disclosure details.

vulnerable_versions lists the range of package versions affected by the issue.

severity tells you what matters most. HIGH and CRITICAL findings demand immediate action. MEDIUM within a week.

installed_version is your current version. Compare it to the vulnerable range to confirm impact.

Understanding How pip-audit Performs Python Dependency Checks

9gB-HloaXXiRsDO7ZApsSA

pip-audit was developed by Trail of Bits with support from Google and is licensed under Apache 2.0, making it free to use without restrictions. It queries the Python Packaging Advisory Database via the PyPI JSON API, which aggregates vulnerability disclosures from multiple sources including OSV.dev and the National Vulnerability Database. When you run pip-audit, it builds a list of installed packages and their versions, then cross-references each one against known advisories. The tool returns any matches with details about the vulnerable version range, the patched version, and the advisory source.

Interpreting pip-audit output is straightforward once you know the structure. The vulnerableversions field uses Python version specifiers like <2.0.0 or >=1.5,<1.6.2, telling you exactly which releases are unsafe. The fixedin field shows the first safe version. Upgrade to that or any later release. Advisory IDs like PYSEC-2023-45 or CVE-2023-12345 let you research the issue in depth. When a package appears in results, check your installed_version against the vulnerable range. If it falls inside, remediation is required.

Package Installed Version Vulnerable Range Fixed Version Advisory Source
requests 2.27.0 <2.31.0 2.31.0 PYSEC-2023-74
urllib3 1.26.4 <1.26.5 1.26.5 CVE-2021-33503
jinja2 3.0.1 >=3.0.0,<3.0.3 3.0.3 GHSA-g3rq-g295-4j3m
cryptography 38.0.0 <39.0.1 39.0.1 PYSEC-2023-12

Using Safety for Python Dependency Vulnerability Checks

tNDj-5s3WUa386c0JPSx_g

Safety maintains its own vulnerability database, called Safety DB, which is updated monthly for the free tier. The paid PyUp service offers a more frequently updated database, support for Common Vulnerability Scoring System (CVSS) scores, and the ability to sync the database locally for offline scanning. When you run Safety, it compares your installed packages or requirements file against this database and flags known issues.

Running Safety is as simple as safety check for your active environment. To scan a requirements.txt file before deploying, use safety check -r requirements.txt. If you need machine-readable output for automation, add --json to produce structured data you can parse with scripts. A Docker image is available, making it easy to run Safety in containerized CI environments without installing Python dependencies on the host. The --full-report flag provides detailed context for each vulnerability, including descriptions and affected version ranges.

Safety is faster than pip-audit in most benchmarks and offers better documentation, which is why it’s often recommended for teams that value quick setup and clear guidance. The main tradeoff is cost. Paid tiers add significant expense. The free Safety DB only updates monthly, so newly disclosed vulnerabilities might not appear for weeks. Another limitation: the default output lists vulnerability IDs but omits severity levels unless you’re on a paid plan with CVSS support. This means you’ll need to manually look up advisory details to prioritize fixes, or pay for the service.

Running pip Safety Checks in CI/CD Pipelines

ZY-aHXBTWKi56NkYE4BxNQ

Integrating vulnerability scans into your CI pipeline catches issues before they merge into main or deploy to production. Both pip-audit and Safety return non-zero exit codes when vulnerabilities are detected, making it straightforward to fail a build or block a pull request. A typical pattern is to run the scan after installing dependencies and before running tests, then parse the output to decide whether to gate or warn.

For scheduled monitoring, configure a weekly cron job that scans your main branch and posts results to Slack or opens tickets for any new findings. This catches vulnerabilities disclosed after your last manual scan. Storing scan results as JSON artifacts in your CI system creates an audit trail and lets you track remediation progress over time. Use a threshold approach: fail on HIGH or CRITICAL severity, warn on MEDIUM, and log LOW for future cleanup.

Example GitHub Actions Configuration

A GitHub Actions workflow for pip-audit or Safety follows a standard setup: check out the code, install Python, install the scanner, and run the scan with JSON output. You can then use jq or Python scripts to count vulnerabilities and decide whether to exit with failure.

Setup Python. Use actions/setup-python@v4 to install the Python version your project requires (e.g., 3.10 or 3.11).

Install scanner. Run pip install pip-audit or pip install safety in a workflow step to make the tool available.

Run scan with JSON output. Execute pip-audit --format json > audit.json or safety check --json > safety.json to capture structured results.

Fail or pass based on vulnerability count. Parse the JSON with a shell script like if [ $(jq '.vulnerabilities | length' audit.json) -gt 0 ]; then exit 1; fi to block the pipeline when issues exist.

Fixing Vulnerabilities Found During pip Safety Checks

MmQ3GZ6XVhipcIKN-Lrgng

When a scan flags a package, your first step is to check if a patched version exists. Look at the fixed_in field and run pip install package==X.Y.Z to upgrade directly to the safe version. After upgrading, re-run the scanner to confirm the issue is resolved. If the vulnerability affects a transitive dependency (a package you don’t directly install), update the parent package that pulls it in, or add the transitive dependency to your requirements with an explicit safe version.

Some vulnerabilities have no available fix yet, especially for abandoned or slow-moving projects. In those cases, evaluate whether you can replace the package with a maintained alternative. If replacement isn’t practical, isolate the risky functionality by wrapping it in additional validation or sandboxing at runtime. Document the mitigation in your codebase and track the advisory ID so you can revisit when a patch arrives.

Create a ticket for each vulnerability with the CVE or OSV identifier, the affected package and version, and a target remediation date. HIGH and CRITICAL severity issues should have timelines measured in hours or days. 24 to 72 hours is a common SLA. MEDIUM severity findings can be scheduled within a week, and LOW severity within 30 days. Tracking remediation this way ensures nothing falls through the cracks.

Upgrade immediately to the fixed_in version or later for HIGH/CRITICAL findings.

Run your test suite after upgrading to catch any breaking changes introduced by the new version.

If the vulnerability is in a transitive dependency, pin or upgrade the direct dependency that pulls it in.

When no fix exists, consider replacing the package or isolating its use behind strict input validation and error handling.

Best Practices for Safe and Reproducible Python Dependency Management

MJFXxNfyUViTYb2bgNJ3Gg

Pinning package versions in requirements.txt or a lockfile eliminates unexpected upgrades that might introduce vulnerabilities or break functionality. Use exact version specifiers like requests==2.31.0 rather than loose constraints like requests>=2.0. For transitive dependencies, generate a full lockfile with pip freeze > requirements.lock.txt after installing your direct dependencies, capturing every package version in your environment.

Hash-based verification adds another layer of integrity. When you run pip install --require-hashes -r requirements.txt, pip refuses to install any package unless its file hash matches the one in your requirements file. Generate hashes with pip-compile --generate-hashes requirements.in, which produces a requirements.txt that includes --hash=sha256:... for each package. This ensures that even if a PyPI mirror is compromised, you won’t install a tampered package.

Tools like pip-compile (from pip-tools) and Poetry make lockfile management automatic. pip-compile reads a high-level requirements.in file with your direct dependencies and resolves the full dependency graph, writing a requirements.txt with pinned versions and hashes. Poetry uses poetry.lock for the same purpose, regenerating it whenever you add or update dependencies. Both approaches give you reproducible installs. Every developer and CI run uses identical package versions.

Pruning unused dependencies reduces your attack surface. Regularly audit your requirements file and remove packages you no longer import. Fewer dependencies mean fewer potential vulnerabilities and faster scans. When evaluating new packages, prefer those with active maintenance, strong community support, and a history of timely security patches.

Supplementary Security Tools That Enhance pip Dependency Checks

ttVT56NPUEG1q8cJ-6W1qg

pipask is a pre-install vetting tool that prompts for consent before executing third-party code during pip’s dependency resolution. It checks package reputation (GitHub stars, download counts), release age, and known vulnerabilities via PyPI and OSV.dev, then asks you to confirm before proceeding. Install it with pipx install pipask and alias it to pip for interactive workflows. This catches suspicious packages before they’re on your system, complementing post-install scanners like pip-audit.

Generating a Software Bill of Materials (SBOM) for your project creates a machine-readable inventory of all dependencies, versions, and licenses. Tools like pip-licenses or syft can produce SBOM files in CycloneDX or SPDX format. Store these SBOMs in your CI artifacts or version control so you have a historical record of what shipped in each release, useful for compliance audits and incident response when a new vulnerability is disclosed.

pipask does pre-install checks for reputation, download stats, and vulnerabilities. It prevents code execution before you vet the package.

Snyk is a commercial scanner with deep vulnerability intelligence and automated fix PRs. It integrates with GitHub, GitLab, and Bitbucket.

Trivy scans containers and filesystems to detect vulnerabilities in Python packages, OS packages, and application dependencies in Docker images.

How pip Resolves Python Dependencies and Why That Affects Security

oCFqLJosUqqdDAsyDVmGDg

pip’s dependency resolver reads package metadata to determine what other packages are required, then installs everything recursively. For source distributions (sdist packages), this metadata often lives in setup.py or requires running a PEP 517 build backend like setuptools or poetry-core. That means pip can execute arbitrary Python code on your machine just to figure out what dependencies to install. Before you’ve explicitly consented to installing the package.

Wheels (binary distributions) bundle pre-built code and include metadata without requiring code execution during install. When you use pip install --only-binary=:all:, pip refuses to fall back to source distributions, eliminating the risk of malicious setup.py code. The catch is that many packages, especially those with C extensions or niche platform support, don’t publish wheels for every Python version and operating system. Forcing wheels-only installs can break compatibility, so it’s not a universal solution. Understanding this tradeoff helps you decide when to prioritize speed and convenience versus minimizing attack surface.

Scheduling and Automating Regular pip Safety Checks

CGERhjnqWESIAE2ucAx0lw

Vulnerabilities are disclosed constantly, so a one-time scan is never enough. Schedule scans to run daily or weekly on your main branch to catch new advisories as they’re published. Daily scans make sense for high-security environments. Weekly scans are a practical default for most teams. Configure your CI system to run pip-audit or Safety on a cron schedule, store the JSON output as an artifact, and alert via Slack or email when new issues appear.

Dependabot and Renovate automate the upgrade process by opening pull requests when newer versions of your dependencies are released. Dependabot scans your requirements files, checks for updates, and creates PRs with changelogs and release notes. Pair this with your vulnerability scanner in CI: when Dependabot opens a PR, your pipeline runs pip-audit or Safety to confirm the upgrade resolves known issues and doesn’t introduce new ones.

Storing scan reports over time lets you build dashboards that track vulnerability trends. How many HIGH severity issues are open, median time to remediation, and compliance with internal SLAs. Export the JSON from each scan to a data store or log aggregator, then visualize with Grafana, Datadog, or a custom script. This creates accountability and helps prioritize security work alongside feature development.

Final Words

In the action, you ran pip-audit and Safety, inspected JSON/table outputs, and checked key fields like fixed_in and advisory IDs.

You added scans to CI, scheduled regular runs, and practiced safe pinning, lockfiles, and SBOM generation to cut risk.

Keep automation, quick triage, and patching part of the workflow, and that’s the core of a reliable pip safety check python dependencies setup. Run checks weekly and treat HIGH/Critical as first priority. Doable, and you’ll ship safer code.

FAQ

Q: How to check pip package dependencies and view the dependency tree?

A: To check pip package dependencies and view the dependency tree, list installed packages (pip list or pip show ), use pip freeze for exact pins, and install pipdeptree (pip install pipdeptree) to print a tree or JSON.

Q: How to check dependency vulnerability?

A: To check dependency vulnerability, run pip-audit or Safety against your virtualenv or requirements.txt. Example commands: pip-audit or safety check -r requirements.txt –full-report –json, then parse JSON for CI and tracking.

curtisharmon
Curtis has spent over two decades guiding hunters and anglers through the backcountry of Montana and Wyoming. His expertise in elk hunting and fly fishing has made him a sought-after voice in the outdoor community. Curtis combines traditional woodsmanship with modern techniques to help readers succeed in the field.

Related articles

Recent articles