Skip to main content

ctxsentry

Scan a repository for prompt-injection payloads before you point an AI coding agent at it.

PyPI CI Python License: MIT

Formerly published as ctxguard (≤ 0.3.0); renamed because that name was taken on PyPI.


The gap this fills

Every current MCP / AI-agent security scanner points outward — it probes a remote MCP server, or audits the agent framework you are building. Almost nothing points inward at the untrusted repository you are about to open in Cursor, Claude Code, Copilot, or Windsurf.

That repo is attacker-influenced text. The moment your agent reads its README.md, CLAUDE.md, .cursorrules, .mcp.json, issue templates, or even a filename, any instructions hidden in that content enter the model's context. Cloud Security Alliance research in 2026 documented "README instruction injection" against coding agents with attack success rates of 41–84%, and MCP tool-description poisoning (CVE-2025-54136) works the same way.

ctxsentry is a fast, dependency-free static scanner that flags that content so a human reviews it first.

→ See docs/walkthrough.md for a worked example: five planted attacks in a sample repo, and the scan that catches every one.

What it detects

Family Examples
Instruction override ignore all previous instructions, you are now…, chat-template tokens (<system>, [INST], <|im_start|>), do not tell the user, <IMPORTANT> priority markers, jailbreak / guardrail-removal phrasing (developer mode, do anything now, ignore your guidelines)
Agent-directed imperatives sentences addressed to "the AI / assistant / agent" that also name an action (run, curl, exfiltrate, install, push)
Data exfiltration & RCE instructions to send .env / tokens / file contents somewhere, callback URLs (webhook.site, ngrok, oast, requestbin…), markdown images with query strings, curl … | sh, reverse-shell one-liners (bash -i >& /dev/tcp/…)
Data exfiltration & RCE (cont.) DNS exfiltration (dig $(cat …).attacker), git remote add + git push to a non-GitHub URL, postinstall hooks that shell out
Context / prompt disclosure repeat the text above verbatim, what is your system prompt, fake --- END OF DOCUMENT --- / system override: boundaries injected into retrieved content
Hidden Unicode Unicode Tag characters U+E00xx (decoded and shown), bidirectional overrides (Trojan Source), zero-width runs, Private-Use-Area smuggling, Latin/Cyrillic/Greek homoglyph words
Deobfuscated rescan strips zero-width / tag characters and folds homoglyphs, then re-runs every rule — catches I​g​n​o​r​e all previous instructions and іgnоrе … evasions
Encoded payloads base64 / hex blobs are decoded and the plaintext rescanned — a hidden ignore all previous instructions… inside a base64 string is surfaced with the decoded text
Layout smuggling instruction text pushed off-screen by whitespace, display:none / color:#fff / font-size:0 spans, instruction-bearing HTML comments
MCP config poisoning .mcp.json description / instructions fields carrying hidden directives or secret references; server launch commands that pipe a download into a shell
Filename injection control / invisible / bidi characters in filenames, filenames that spell out an imperative

Severity is boosted by context: the same string is medium in a source comment but critical in .mcp.json or CLAUDE.md, because agents load those files as authoritative instructions.

Install

pipx install ctxsentry        # recommended
# or
pip install ctxsentry

From source:

git clone https://github.com/EivinDDu/ctxsentry
cd ctxsentry
pip install -e ".[dev]"

Usage

# scan the current repo
ctxsentry scan .

# scan a repo you just cloned, before opening it in your editor
ctxsentry scan ../suspicious-repo

# scan only what changed — fast pre-commit / PR gating
ctxsentry scan . --changed              # vs HEAD (+ staged/unstaged/untracked)
ctxsentry scan . --changed origin/main  # vs a base branch

# machine-readable output
ctxsentry scan . --format json  -o ctxsentry.json
ctxsentry scan . --format sarif -o ctxsentry.sarif   # upload to GitHub code scanning

# gate a pipeline
ctxsentry scan . --fail-on medium --git-history

# tune the noise
ctxsentry scan . --min-severity medium --min-confidence medium

# list every rule
ctxsentry rules

# score the detectors against the labelled corpus
ctxsentry bench

By default ctxsentry only reads files an agent treats as context (docs, rule files, MCP config, *.md, *.txt, config formats). Add --all-text to sweep source files too.

Exit codes

Code Meaning
0 completed; nothing at or above --fail-on
1 findings at or above --fail-on (default: high)
2 usage / runtime error

Pre-commit hook

# .pre-commit-config.yaml
- repo: https://github.com/EivinDDu/ctxsentry
  rev: v0.3.0
  hooks:
    - id: ctxsentry             # add: args: ["--changed"] for staged-only scans

GitHub Action

# .github/workflows/ctxsentry.yml
name: ctxsentry
on: [push, pull_request]
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: EivinDDu/ctxsentry@v0.3.0
        with:
          fail-on: high        # optional (default: high)
          # path: .
          # args: --changed origin/main   # PR-diff-only scan

Suppressing findings

Known-good matches (your own security docs, test fixtures) can be silenced two ways:

  • .ctxsentryignore at the scan root — one glob per line, optionally scoped to specific rule ids:

    docs/threat-model.md            # ignore every rule for this file
    examples/**                     # ignore a whole tree
    SECURITY.md:CG101,CG401         # ignore only these rules here
    
  • Inline comment on the flagged line or the line above it:

    <!-- ctxsentry: ignore CG401 -- example payload documented on purpose -->
    

How it works

path ─▶ file walk (skips vendored dirs, binaries, >1 MB)
     ─▶ decode (utf-8 / utf-16 / latin-1), keep invisible chars intact
     ─▶ classify context (mcp-config │ agent-instructions │ agent-skill │ docs │ generic)
     ─▶ run detectors:
          • regex rule table           (ctxsentry/rules.py)
          • invisible-Unicode scanner   (decodes U+E00xx tag runs)
          • deobfuscated rescan         (strip zero-width, fold homoglyphs, re-run rules)
          • encoded-payload scanner     (decodes base64 / hex, rescans plaintext)
          • layout / smuggling scanner
          • MCP JSON structure walk
          • filename scanner
     ─▶ context-adjust severity ─▶ sort ─▶ render (text │ json │ sarif │ markdown)

No network calls. No LLM. Deterministic.

Benchmark

ctxsentry bench runs the detectors over a labelled corpus in benchmark/ (20 malicious fixtures across every family, 18 realistic benign ones) and reports precision / recall / F1 / false-positive rate. CI fails the build on any regression:

cases: 38   TP 20  FN 0  FP 0  TN 18
precision 1.000   recall 1.000   F1 1.000   FP-rate 0.000   rule-accuracy 1.000

The benign fixtures are the point — normal READMEs, a SECURITY.md, setup docs that mention API keys, ### System Requirements headings — content that looks adjacent to an attack but must not trip the scanner.

Limitations

  • Static pattern matching: a novel paraphrase with no known markers can slip through, and benign security documentation about prompt injection will produce findings (tune with --min-confidence).
  • Not a replacement for mcp-scan (runtime MCP), secret scanners, or SAST — it covers the one thing they don't.

Development

pip install -e ".[dev]"
pytest
ctxsentry bench          # detection score against benchmark/

Adding a detector? Add a fixture to benchmark/malicious/ (and a benign counterpart if it could misfire), list it in benchmark/cases.jsonl, and keep ctxsentry bench at 100% recall / 0 false positives.

Releasing is documented in docs/RELEASING.md — tag a version and publish a GitHub Release; CI builds and uploads to PyPI via Trusted Publishing.

License

MIT

Download files

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

Source Distribution

ctxsentry-0.4.0.tar.gz (44.1 kB view details)

Uploaded Source

Built Distribution

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

ctxsentry-0.4.0-py3-none-any.whl (32.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: ctxsentry-0.4.0.tar.gz
  • Upload date:
  • Size: 44.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for ctxsentry-0.4.0.tar.gz
Algorithm Hash digest
SHA256 c34fed07ec0652b1d8d2d03c2b4181be6bed54f8d3c3ac8a9923f16448c38500
MD5 1e8a64c7797f7a8824c8381b67831069
BLAKE2b-256 46c5b5bd1218d19fb73b1d16329c7c891044adbdff1005ea7c3bc904afcae7c0

See more details on using hashes here.

Provenance

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

Publisher: publish.yml on EivinDDu/ctxsentry

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

File details

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

File metadata

  • Download URL: ctxsentry-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 32.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for ctxsentry-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 28c7e30db14d5c6548dad07a06e9b5d3f1f707ff98abce0024f1b8bdac97057a
MD5 5a1ebb49e00a39f68cfe197fed3b9059
BLAKE2b-256 2985d5f40379bfc15e61a8d13701b036749d736ded420e704a239dc7138e088d

See more details on using hashes here.

Provenance

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

Publisher: publish.yml on EivinDDu/ctxsentry

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

Release history Release notifications | RSS feed

0.5.0

2 files

This release

0.4.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page