Skip to main content

Static security scanner for AI agents, MCP tools, and LLM applications. Finds prompt injection, tool poisoning, and agentic vulnerabilities. OWASP LLM Top 10 (2025) tagged.

Project description

PyPI version Python versions Downloads Build Status License: MIT codecov

secchecker

Static security scanner for AI agents, MCP tools, and LLM applications. Finds prompt injection, MCP tool poisoning, and agentic vulnerabilities before deployment.

secchecker helps developers catch prompt injection, MCP tool poisoning, unsafe agent behavior, exposed AI credentials, and deployment risks before code reaches production. Secrets scanning and infrastructure-as-code checks remain fully supported as proof points, so one command covers your AI application, your source code, and your deployment configs. Zero external dependencies. Runs anywhere Python runs.

Purpose-built for AI agents, MCP tool servers, and LLM applications — with secrets and DevSecOps coverage alongside.


The problem it solves

Modern applications have three distinct attack surfaces that legacy scanners address poorly:

Source code — Developers commit API keys, database credentials, and private keys directly into repositories. These persist in git history long after deletion.

AI and LLM applications — Teams building on top of OpenAI, Anthropic, or open-source models introduce new vulnerability classes: prompt injection, RAG data leakage, insecure output handling, and hardcoded model API keys. No mainstream PyPI scanner covers these.

Infrastructure as code — Terraform modules, Kubernetes manifests, Dockerfiles, and CI/CD pipelines contain misconfigurations that open production environments to privilege escalation, data exposure, and supply chain attacks.

secchecker audits all three in one pass.


Coverage at a glance

Scanner What it detects Patterns
LLM / AI Prompt injection, RAG leakage, eval of model output, hardcoded AI API keys 18+
MCP / Agentic AI Tool poisoning, tool-output execution, memory injection, PII to external agents 9 (NEW)
Secrets Cloud keys, private keys, database URIs, payment credentials, service tokens 52+
DevSecOps Dockerfile, Kubernetes, Terraform, CI/CD misconfigurations 28+
Entropy Unknown secrets with high Shannon entropy — catches what regex misses
AST Hardcoded secrets in Python assignments, eval/exec calls, tainted input to sinks

Every finding is tagged with OWASP Top 10 (2021) and OWASP LLM Top 10 (2025) classifications in SARIF output.

secchecker maps findings to OWASP Top 10 and OWASP LLM Top 10 categories for developer guidance only. This does not imply OWASP certification, endorsement, or compliance.


Installation

Install from PyPI:

pip install secchecker

Requires Python 3.8 or later. No external dependencies.


How to use it

secchecker accepts a file or directory path and optional flags. Run secchecker --help for the full reference.

Scan your AI agent / LLM app for prompt injection, MCP issues, and agentic risks:

secchecker . --type llm

Scan MCP tool servers and agent code, output SARIF:

secchecker ./mcp_server/ --type llm --format sarif

Scan a project for secrets:

secchecker . --type secrets

Scan infrastructure configs — Dockerfile, Terraform, Kubernetes:

secchecker . --type devsecops

Run all scanners together:

secchecker . --type all

Filter findings by severity and write a SARIF report:

secchecker . --type all --severity-threshold HIGH --format sarif --output report.sarif

Available flags:

Flag Values Default
--type secrets, llm, devsecops, all secrets
--format json, md, xml, sarif, html md
--output / -o file path secchecker_report.<format>
--severity-threshold LOW, MEDIUM, HIGH, CRITICAL
--config path to .secchecker.yml auto-detected
--no-entropy entropy enabled
--verbose / -v

Exit codes: 0 — no findings at or above threshold. 1 — findings detected. 2 — runtime error.


What gets detected

Secrets — 52+ patterns across 15 credential categories

Category Examples Severity
Private keys RSA, EC, DSA, PGP, SSH CRITICAL
Financial Credit cards (Luhn-validated), SSN CRITICAL
Vault tokens HashiCorp Vault CRITICAL
Cloud keys AWS, Google Cloud, Azure HIGH
Database URIs PostgreSQL, MySQL, MongoDB, Redis HIGH
Service tokens Stripe, Twilio, SendGrid, Datadog HIGH
VCS tokens GitHub, GitLab HIGH
Auth tokens JWT (structure-validated), Bearer MEDIUM
Config passwords Common password assignment patterns MEDIUM

Matches are validated post-regex — credit cards pass the Luhn algorithm, JWT tokens are verified for structural integrity — to reduce false positives.

MCP / Agentic AI — NEW in v0.4.0

Risk Example OWASP Severity
MCP tool poisoning Tool result injected into prompt without sanitization LLM01:2025 HIGH
Tool output executed eval(tool_result) / os.system(function_result) LLM05:2025 CRITICAL
Hardcoded MCP server URL External MCP server URL in source LLM02:2025 HIGH
Memory injection User input stored to agent memory unvalidated LLM01:2025 HIGH
PII passed to agent SSN/credit card passed to external LLM agent LLM02:2025 CRITICAL
Function call not validated LLM tool call result used without schema check LLM05:2025 CRITICAL

secchecker maps findings to OWASP LLM Top 10 categories for developer guidance. This does not imply OWASP certification, endorsement, or compliance.

LLM / AI security — 18+ patterns, tagged OWASP LLM Top 10 (2025)

Risk What it catches OWASP LLM Severity
Prompt injection User input concatenated directly into LLM prompt strings LLM01:2025 HIGH
Jailbreak literals Hardcoded override instructions in source LLM01:2025 HIGH
RAG data leakage Unfiltered database queries or file reads fed into model context LLM08:2025 HIGH
Insecure output handling Model response passed directly to eval or exec LLM05:2025 CRITICAL
AI API key exposure OpenAI, Anthropic, HuggingFace, Pinecone keys in source LLM02:2025 CRITICAL
Sensitive data in prompt PII or financial data concatenated into prompt strings LLM02:2025 CRITICAL
System prompt disclosure Hardcoded system prompts revealing application logic LLM07:2025 LOW

DevSecOps — 28+ patterns, tagged OWASP Top 10 (2021)

Category Risk examples Severity
Dockerfile Unpinned base images, secrets in ENV, curl-pipe-bash, root user HIGH
Kubernetes Privileged containers, hostNetwork, allow privilege escalation CRITICAL
Terraform Open security groups (0.0.0.0/0), public S3 buckets, plaintext credentials HIGH
CI/CD Secrets echoed to logs, pull_request_target misuse, unpinned actions HIGH

Output formats

secchecker writes results in five formats, selectable with --format:

Format Use case
Markdown Human-readable reports, pull request comments
JSON Programmatic consumption, custom dashboards
SARIF 2.1.0 GitHub Security tab, IDE integrations, OWASP/CWE tags included
HTML Self-contained audit reports for sharing with stakeholders
XML Legacy toolchain integration

SARIF output includes OWASP Top 10 2021 categories, OWASP LLM Top 10 2025 categories, and CWE IDs on every rule — compatible with the GitHub Security tab without additional configuration.


Architecture

Component overview

                        ┌─────────────────────────────────────────┐
                        │              cli.py  (main)              │
                        │  --type  --format  --severity-threshold  │
                        │  --config  --no-entropy  --output        │
                        └──────────────┬──────────────────────────┘
                                       │ orchestrates
              ┌────────────────────────┼────────────────────────┐
              ▼                        ▼                         ▼
   ┌──────────────────┐   ┌───────────────────────┐   ┌─────────────────────┐
   │  core.py         │   │  llm_scanner.py        │   │ devsecops_scanner.py│
   │  secrets scanner │   │  LLM/AI vuln scanner   │   │ infra config scanner│
   │  patterns.py     │   │  llm_patterns.py        │   │ devsecops_patterns  │
   └──────────────────┘   └───────────────────────┘   └─────────────────────┘
              │                        │                         │
              └────────────────────────┼─────────────────────────┘
                                       │ entropy.py (optional, overlaid)
                                       │
                        ┌──────────────▼──────────────────────────┐
                        │   Dict[filepath, Dict[pattern, matches]] │
                        │          shared result contract          │
                        └──────────────┬──────────────────────────┘
                                       │ passed to one reporter
        ┌──────────┬───────────────────┼──────────────┬──────────────┐
        ▼          ▼                   ▼               ▼              ▼
    reporter.py  reporter.py       reporter.py   sarif_reporter  html_reporter
      to_json()  to_markdown()     to_xml()      to_sarif()      to_html()

Module map

Module Role Key exports
cli.py Entry point, orchestration main()
core.py Secrets scanner + file filtering scan_file(), scan_directory(), should_skip_file(), should_skip_directory()
patterns.py 52+ secret regexes PATTERNS
llm_scanner.py LLM/AI vulnerability scanner scan_file_llm(), scan_directory_llm()
llm_patterns.py 18+ LLM/AI regexes LLM_PATTERNS, LLM_SEVERITY_MAP
devsecops_scanner.py Infra config scanner scan_file_devsecops(), scan_directory_devsecops()
devsecops_patterns.py 28+ infra regexes DEVSECOPS_PATTERNS, FILE_TYPE_FILTER
entropy.py Shannon entropy detection scan_file_entropy(), shannon_entropy()
ast_scanner.py Python AST structural analysis scan_file_ast(), scan_directory_ast()
validators.py Post-match false-positive reduction validate_match(), luhn_check(), is_valid_jwt()
owasp.py OWASP Top 10 / LLM Top 10 / CWE mapping get_owasp()
reporter.py JSON / Markdown / XML output to_json(), to_markdown(), to_xml(), get_severity()
sarif_reporter.py SARIF 2.1.0 output to_sarif(), generate_sarif_report()
html_reporter.py Self-contained HTML output to_html(), generate_html_report()
config.py .secchecker.yml loader load_config(), find_config_file()

Severity pipeline

Every finding flows through a single severity pipeline regardless of which scanner produced it:

Pattern definition          SEVERITY_MAP / LLM_SEVERITY_MAP / DEVSECOPS_SEVERITY_MAP
        |                           |
        +-------- get_severity() ---+
                       |
               CLI --severity-threshold     <- filter here before reporting
                       |
               Reporter (color / SARIF level / HTML badge)

SARIF level mapping: CRITICAL and HIGH map to error. MEDIUM maps to warning. LOW maps to note.

Design principles

  • Zero runtime dependencies — stdlib only, no pip install chain to audit
  • Python 3.8–3.12 compatible, tested in CI across all versions
  • All scanners share a single file-filtering contract via core.py — no scanner walks files independently
  • Config loading never raises — returns safe defaults on any parse error
  • Reporters are pure functions: identical input always produces identical output
  • Post-match validators (Luhn, JWT structure) reduce false positives before results are returned

Real-world scenarios

Scenario 1: Block secrets from reaching CI

A team uses secchecker as a pre-commit gate. Any commit that introduces a secret pattern at severity HIGH or above is rejected before it leaves the developer's machine. SARIF output is also uploaded to the GitHub Security tab on every pull request, giving security teams visibility without blocking developers.

Scenario 2: Audit an LLM-powered application

A FastAPI service wrapping OpenAI is scanned with the LLM scanner before each release. The scanner surfaces prompt strings that concatenate user input without sanitisation, database query results passed directly into model context, and eval calls against model responses — all common patterns in early-stage AI applications that create exploitable injection paths.

Scenario 3: Harden infrastructure before deployment

Infrastructure code for a Kubernetes-hosted service is scanned with the DevSecOps scanner as part of a Terraform plan stage. The scan catches open security groups, privileged container specs, and CI pipeline steps that echo secrets to logs — before the configuration reaches a production cluster.

Scenario 4: Continuous monitoring in CI/CD

secchecker runs on every push via GitHub Actions. SARIF results are uploaded directly to the repository's Security tab. Findings at CRITICAL severity fail the build. HIGH findings create annotations on the pull request diff. The team treats the Security tab as their primary finding triage surface.


GitHub Action

secchecker ships as a composite GitHub Action. Add it to any workflow:

- uses: vishnu-77/secchecker@v0.4.0
  with:
    path: '.'
    type: 'all'
    format: 'sarif'
    severity-threshold: 'LOW'
    fail-on-findings: 'true'

SARIF output is automatically uploaded to the GitHub Security tab.

Action inputs:

Input Default Description
path . Directory or file to scan
type secrets Scan type: secrets, llm, devsecops, all
format sarif Output format
severity-threshold LOW Minimum severity to report
output secchecker_report.sarif Output file path
fail-on-findings true Fail the workflow if findings are detected

Configuration

Create .secchecker.yml in your project root to control scan behaviour without passing flags each time:

severity_threshold: MEDIUM
exclude_paths:
  - "tests/"
  - "*.mock.*"
  - "node_modules/"
scan_types:
  - secrets
  - llm
entropy:
  enabled: true
  threshold: 4.5
custom_patterns:
  "Internal API Key": "myco_[a-zA-Z0-9]{32}"

CLI flags take precedence over the config file.


Python library

secchecker is also importable as a Python library. All scanners are available as functions that accept a file or directory path and return a consistent result structure. All reporters accept that structure and write to a file or return a string.

The shared result type is Dict[filepath, Dict[pattern_name, List[matched_strings]]]. Scanners can be run individually or composed — the CLI merges results from all active scanners before passing them to the selected reporter.

Available scanner functions: scan_file, scan_directory (secrets), scan_file_llm, scan_directory_llm, scan_file_devsecops, scan_directory_devsecops, scan_file_ast, scan_directory_ast, scan_file_entropy.

Available reporter functions: to_json, to_markdown, to_xml, to_sarif, to_html.


Why secchecker

  • The only PyPI scanner with a dedicated AI security layer — prompt injection, MCP tool poisoning, agentic risks, and PII-to-agent flows that general-purpose scanners don't touch
  • One pass, three surfaces — AI app code, source secrets, and infrastructure-as-code in a single scan
  • Findings you can act on — OWASP Top 10 (2021) + OWASP LLM Top 10 (2025) tags on every SARIF rule, straight to the GitHub Security tab
  • Validated, not noisy — Luhn and JWT post-match checks cut false positives before results are returned
  • Zero runtime dependencies — nothing to audit, installs anywhere Python runs

Contributing

Clone the repository, install in editable mode with dev dependencies, and run the test suite:

git clone https://github.com/vishnu-77/secchecker.git
cd secchecker
pip install -e ".[dev]"
pytest tests/ -v

To add a new secret pattern: add the regex to secchecker/patterns.py, add a severity entry to SEVERITY_MAP in secchecker/reporter.py, and add OWASP/CWE mappings to secchecker/owasp.py. Include a test in tests/test_patterns.py.

To add a new LLM check: add the pattern to secchecker/llm_patterns.py and a severity entry to LLM_SEVERITY_MAP. Include a test in tests/test_llm_scanner.py.

Pull requests are welcome. Keep changes focused and include tests for new patterns or behaviour.


Pre-commit integration

secchecker ships a .pre-commit-hooks.yaml so it can be used directly with the pre-commit framework. Add the following to your .pre-commit-config.yaml:

repos:
  - repo: https://github.com/vishnu-77/secchecker
    rev: v0.4.0
    hooks:
      - id: secchecker          # secret detection only
      # - id: secchecker-llm    # LLM/AI security only
      # - id: secchecker-all    # all scanners

Three hooks are available: secchecker (secrets), secchecker-llm (LLM/AI patterns), and secchecker-all (full audit). All default to failing on HIGH and above.


Roadmap

Delivered in 0.4.0: MCP and agentic AI security patterns, OWASP LLM Top 10 (2025) mappings for the new findings, and the AI/GenAI/MCP-first repositioning.

The following capabilities are planned for upcoming releases:

Feature Description Release target
Deeper taint analysis Track taint through function arguments, return values, and dict assignments in the AST scanner 0.5.0
VS Code integration Document SARIF viewer compatibility; evaluate a minimal diagnostic extension 0.5.0
Incremental scan / cache Hash-based file cache so only changed files are re-scanned — critical for large monorepos 0.6.0
Baseline file .secchecker-baseline.json to record accepted findings and suppress them on future runs 0.6.0
--diff mode Accept git diff on stdin and scan only changed lines — faster pre-push hook 0.6.0
Custom rule DSL Per-rule severity, description, and enable/disable in .secchecker.yml 0.6.0

Responsible use

secchecker is intended for security auditing of repositories you own or have explicit written permission to test. It is not a substitute for a full penetration test or security audit. The author assumes no liability for misuse.

If you find a security vulnerability in secchecker itself, see SECURITY.md for the responsible disclosure process.

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

secchecker-0.4.0.tar.gz (51.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

secchecker-0.4.0-py3-none-any.whl (43.0 kB view details)

Uploaded Python 3

File details

Details for the file secchecker-0.4.0.tar.gz.

File metadata

  • Download URL: secchecker-0.4.0.tar.gz
  • Upload date:
  • Size: 51.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for secchecker-0.4.0.tar.gz
Algorithm Hash digest
SHA256 7e044d6dc2b904a8ad4dfa481c7fa048a4738853b0d83903925cca394bd74495
MD5 06865bc3de76200f250cc13f7859b28e
BLAKE2b-256 d44ffde1b7963827d83e11250e3f56f8b442813fdd95d73857eac8c9f3b84f79

See more details on using hashes here.

Provenance

The following attestation bundles were made for secchecker-0.4.0.tar.gz:

Publisher: ci.yml on vishnu-77/secchecker

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file secchecker-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: secchecker-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 43.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for secchecker-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cac6523b49e48565a06396d1a0c64595ce7db6b01bf3cd716f8e1ea8b400f5df
MD5 0bd8ec11b886a2159b6535bebf9c195a
BLAKE2b-256 9f9dd7ee89bb77213a71d79289d4ec1970c42e390d0edaef6945dd74d27ad2cd

See more details on using hashes here.

Provenance

The following attestation bundles were made for secchecker-0.4.0-py3-none-any.whl:

Publisher: ci.yml on vishnu-77/secchecker

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page