← Back to DevBytes

How to Scan LLM Dependencies for Vulnerabilities

How to Scan LLM Dependencies for Vulnerabilities

Large Language Models (LLMs) have rapidly moved from research prototypes into production applications. While teams spend significant effort evaluating model accuracy and prompt design, the software supply chain behind these applications often receives far less attention. Every LLM-powered application depends on a web of libraries, model weights, datasets, plugins, and API clients — each of which can introduce security vulnerabilities. This tutorial walks through what LLM dependency scanning is, why it matters, and how to implement it in your own projects.

What Is LLM Dependency Scanning?

LLM dependency scanning is the process of identifying, inventorying, and analyzing every component your LLM application relies on — then checking those components against known vulnerability databases and risk indicators. Unlike traditional dependency scanning, which focuses on package manifests like package.json or requirements.txt, LLM scanning must account for a broader surface area:

A complete scanning strategy combines Software Composition Analysis (SCA), model artifact inspection, and runtime behavior monitoring.

Why It Matters

LLM applications inherit the same supply chain risks as any modern software project, plus several unique threats. A vulnerable version of a popular orchestration library can allow prompt injection, arbitrary code execution, or server-side request forgery. Malicious model files uploaded to public registries have already been caught containing pickle-based deserialization exploits. Because LLM apps frequently run with broad permissions — filesystem access, network egress, database credentials — a single compromised dependency can lead to full system compromise.

Regulatory frameworks such as the EU AI Act and executive orders on AI safety also increasingly require organizations to document and secure their AI supply chains. Scanning dependencies is the foundational step in meeting those obligations.

Setting Up a Scanning Pipeline

Step 1: Inventory Your Dependencies

Before scanning, you need a complete inventory. For Python-based LLM projects, start by exporting your dependency tree. The following command captures both direct and transitive dependencies in a machine-readable format:

pip install pip-audit
pip freeze > requirements-lock.txt
pip-audit -r requirements-lock.txt -f json -o audit-report.json

The pip-audit tool queries the PyPI Advisory Database and OSV.dev to flag known CVEs. For Node.js projects that use the OpenAI or Vercel AI SDKs, use npm audit:

npm install -g better-npm-audit
npm audit --json > npm-audit-report.json

Step 2: Scan Hugging Face Model Artifacts

Model files are a frequently overlooked attack vector. Hugging Face supports a built-in security scanner that checks repositories for malicious code patterns. You can query it programmatically before downloading any model:

import requests

def scan_hf_model(repo_id: str, token: str | None = None) -> dict:
    headers = {"Authorization": f"Bearer {token}"} if token else {}
    url = f"https://huggingface.co/api/models/{repo_id}/scan"
    response = requests.get(url, headers=headers, timeout=30)
    response.raise_for_status()
    return response.json()

report = scan_hf_model("meta-llama/Llama-3.1-8B")
print(report)

If the scan returns findings, do not load the model with transformers or safetensors until you have reviewed the report. Prefer models that use the safetensors format over legacy pickle or torch.save formats, since safetensors prevents arbitrary code execution during deserialization.

Step 3: Integrate SCA Into CI/CD

Dependency scanning should run on every pull request and nightly against the main branch. Below is a GitHub Actions workflow that runs pip-audit, checks Hugging Face artifacts, and fails the build on high-severity findings:

name: LLM Dependency Scan

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:
    - cron: "0 3 * * *"

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.11"

      - name: Install tools
        run: pip install pip-audit requests

      - name: Audit Python packages
        run: |
          pip install -r requirements.txt
          pip-audit -r requirements.txt -f sarif -o results.sarif || true

      - name: Scan HF models
        env:
          HF_TOKEN: ${{ secrets.HF_TOKEN }}
        run: python scripts/scan_models.py

      - name: Upload SARIF report
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: results.sarif

The scripts/scan_models.py script can iterate over a manifest file that lists every model your application loads:

import json
import sys
import requests

MODELS = [
    "meta-llama/Llama-3.1-8B",
    "sentence-transformers/all-MiniLM-L6-v2",
    "BAAI/bge-large-en-v1.5",
]

def main(token: str | None) -> int:
    failures = 0
    for repo_id in MODELS:
        headers = {"Authorization": f"Bearer {token}"} if token else {}
        url = f"https://huggingface.co/api/models/{repo_id}/scan"
        r = requests.get(url, headers=headers, timeout=30)
        if r.status_code != 200:
            print(f"[WARN] No scan available for {repo_id}")
            continue
        data = r.json()
        if data.get("status") == "infection":
            print(f"[FAIL] {repo_id} flagged as infected")
            failures += 1
        else:
            print(f"[OK] {repo_id} clean")
    return 1 if failures else 0

if __name__ == "__main__":
    import os
    sys.exit(main(os.environ.get("HF_TOKEN")))

Advanced Scanning Techniques

Detecting Typosquatting and Malicious Packages

LLM libraries are frequent targets for typosquatting attacks. Packages such as langchain-community have been impersonated by malicious lookalikes. Use pip-audit alongside tools like safety and socket to detect suspicious packages:

pip install safety
safety check --full-report --output json > safety-report.json

For npm projects, Socket.dev analyzes package behavior for network access, filesystem manipulation, and install-time scripts:

npx socket scan

Scanning LangChain and LlamaIndex Tool Dependencies

Orchestration frameworks dynamically load tools and integrations. Each integration pulls in its own dependencies. Audit them explicitly by generating a dependency graph:

pip install pipdeptree
pipdeptree --packages langchain,langchain-community,llama-index --graph svg > dep-graph.svg

Review the graph for unexpected packages, especially those with install-time hooks or network calls during import.

Runtime Monitoring With OWASP DepScan

Static scanning catches known CVEs but misses novel attacks. OWASP DepScan performs deep analysis including license risks and vulnerable call paths. Run it against your project:

pip install depscan
depscan --src . --reports-dir ./depscan-reports

Best Practices

To generate an SBOM for a Python LLM project, use cyclonedx-bom:

pip install cyclonedx-bom
cyclonedx-py requirements -r requirements-lock.txt -o sbom.json --schema-version 1.5

Conclusion

Securing LLM applications requires treating the model and its surrounding ecosystem as part of your software supply chain. By combining traditional SCA tools like pip-audit and safety with model-specific checks against Hugging Face's scanning API, runtime monitoring, and disciplined dependency pinning, you can dramatically reduce the risk of a compromised component taking down your application or leaking sensitive data. Build scanning into your CI/CD pipeline from day one, maintain an up-to-date SBOM, and remember that the model itself is just one dependency among many — every one of which deserves scrutiny.

— Ad —

Google AdSense will appear here after approval

← Back to all articles