Skip to main content

ifinjected

If a coding agent on your machine got prompt-injected right now, what could it reach?

CI License: MIT

Website · Every rule · Every command · What is read

A share card: grade F for the machine; Claude Code F, Codex C and opencode F, each a lethal trifecta; reachable: SSH keys, cloud credentials, agent login tokens

One command reads the configuration of Claude Code, Codex, Gemini CLI, Cursor, opencode and Copilot CLI, finds the credentials that exist on this machine without reading them, and tells you, agent by agent, what an injected agent could read, around which rules, and where it could send it:

uvx ifinjected

Read-only and offline. Agent configuration is read as data and never run, credential values are never read or printed, nothing is written and nothing is sent anywhere. See what is read.

What it finds

Each agent gets a grade from its lethal trifecta (Simon Willison's term): private data it can reach, untrusted content it takes in, and a way to send data out. With all three open, one poisoned README, issue or web page can make it read a credential and send it away. A few things that surprised us, each straight from the agents' own documentation:

  • Claude Code runs read-only commands such as cat without a prompt in every mode (docs), so in the default Manual mode cat ~/.ssh/id_ed25519 needs nobody's approval.
  • A Read(~/.ssh/**) deny rule does not stop a Python one-liner: Claude Code's deny rules cover its file tools and the commands it recognises, not "arbitrary subprocesses that read or write files indirectly" (docs). ifinjected reports such a rule as walked around, with its line.
  • Turning a sandbox on does not protect your keys. Claude Code's sandbox reads "most of the machine, including credential files such as ~/.ssh and ~/.aws/credentials", and sandboxed commands run without a prompt by default (docs). Codex's read-only and workspace-write sandboxes start from read access to the whole disk (source).
  • opencode has no sandbox and allows most tools by default (docs): a default setup with credentials on disk is an F.
  • One committed .mcp.json configures two agents: Copilot CLI also loads Claude Code's .mcp.json and its hooks (docs).

ifinjected scan on a fake developer laptop: Claude Code F, Codex C, opencode F, then the findings with their fixes

Use

Needs Python 3.11 or newer.

uvx ifinjected                       # scan: a grade per agent, then what to fix
uv tool install ifinjected           # or keep it (pipx install ifinjected works too)
ifinjected agents                    # how each agent is configured here, layer by layer, with lines
ifinjected inventory                 # the credentials on this machine (location and header only)
ifinjected plan                      # the config change that closes each agent's exposures (never applied)
ifinjected explain IFJ-READ-003      # what a finding means, and its sources
ifinjected card -o card.svg          # a share card: grades and counts, nothing that identifies you
ifinjected prove --run               # open (never read) each credential under Codex's own sandbox
ifinjected scan --strict -f sarif    # for CI: exit 1 on a failing finding, SARIF for code scanning

--deep parses credential files for their structure (profile and host names, never values) and --include-env lists the variable names in .env files. A .ifinjected.toml sets which findings fail --strict and which risks you accept; every command and option is in docs/cli.md. Try it on a fake machine first:

uv run python examples/messy-laptop/build.py /tmp/messy
HOME=/tmp/messy/home/dev ifinjected --workspace /tmp/messy/home/dev/src/app

In CI: catch pull requests that widen agent permissions

A repository is the easiest place to plant agent configuration: one pull request that adds an MCP server, an allow rule or a hook to .claude/settings.json, .mcp.json, .codex/config.toml, .cursor/ or opencode.json changes what every agent working in it may do. ifinjected diff compares that configuration between two refs:

# .github/workflows/agents.yml
on: pull_request
permissions:
  contents: read
  security-events: write
jobs:
  ifinjected:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: BhuwanJoshi-01/ifinjected@v0.1.0
        id: ifinjected
      - uses: github/codeql-action/upload-sarif@v4
        if: always()
        with:
          sarif_file: ${{ steps.ifinjected.outputs.sarif }}

The step fails when a change fails the repository's policy, and the SARIF upload annotates the line that widened it. Locally: ifinjected diff --base origin/main.

What it checks

Agent Configuration it reads What decides reach
Claude Code managed, user, project and local settings, ~/.claude.json, .mcp.json permission mode, Read rules and their anchoring, Bash allow rules, workspace trust, the sandbox and its denyRead
Codex requirements.toml, managed, system, user, profile and trusted project config.toml sandbox mode or permissions profile, approval policy, network, environment policy
Gemini CLI system defaults and override, user and project settings, trusted folders, policy files tools.allowed/core/exclude, policy rules, sandbox kind (Seatbelt reads everything, Docker sees the workspace)
Cursor cli-config.json, sandbox.json, mcp.json run mode (Auto-review assumed for the IDE), Read Access, sandbox type, network allowlist
opencode user, project, .opencode/ and managed opencode.json(c) last-match permissions for read, bash, webfetch and external directories
Copilot CLI ~/.copilot/ settings and MCP config, .github/copilot/, .mcp.json, Claude Code's hooks permission mode, sandbox, the credentials it gives the sandbox

And on the machine: SSH keys (passphrase or not, from the key header), AWS, Google Cloud and Azure credentials, GitHub CLI, git, netrc, npm, PyPI, Cargo, Docker and Kubernetes credentials, service tokens, the agents' own login tokens and transcripts, .env files, browser cookie databases, password managers, secret-looking environment variable names, and credential sockets (ssh-agent, a writable Docker socket). 47 rules, each with a stable code (all of them). How grades are decided: docs/grading.md.

What it promises

  • Never prints, stores or logs a secret value. Credential files are stated; SSH keys are read up to 192 bytes to tell an encrypted key from an unencrypted one; deeper parsing keeps names only. A contract test plants marked fake secrets everywhere and checks every output format for them.
  • Never runs what an agent is configured to run: no MCP server, hook or helper is started.
  • Reads only what docs/what-is-read.md declares. A test records every file access during whole scans and fails on anything undeclared.
  • Writes nothing except a file you name with --output, and uses no network. The only process it starts outside diff (read-only git) is the prove --run probe, which calls open() and close() and never read(); a test parses the probe and fails on any other call.

ifinjected describes what an agent's configuration allows; it is not a sandbox and does not stop anything. A clean report is not a guarantee: agents change, and not everything they can do is in their configuration.

Contributing

New agents, credential locations and real-world reports are the most useful contributions; each needs a source. See CONTRIBUTING.md and the roadmap.

MIT licensed.

Metadata

Release files for ifinjected 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ifinjected 0.1.0
File Size Uploaded Provenance Actions
ifinjected-0.1.0.tar.gz 136.9 kB With provenance Details for ifinjected-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for ifinjected 0.1.0
File Interpreter ABI Platform Actions
ifinjected-0.1.0-py3-none-any.whl Python 3 none any Details for ifinjected-0.1.0-py3-none-any.whl

Total release size: 308.2 kB

Release files / ifinjected-0.1.0.tar.gz

Download URL ifinjected-0.1.0.tar.gz
Size 136.9 kB
Tags Source
SHA-256 checksum
How to use checksums
95b9c8b4d1b5ae7986fcd36672d92e492976f5727e20c709d9c771a8fbd8a0cd
BLAKE2b-256 checksum
How to use checksums
220dc03149822a95b09105c0505fb2633bd6537e4e43d06db77cb2fb60bd9891
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.

Transparency log

Release files / ifinjected-0.1.0-py3-none-any.whl

Download URL ifinjected-0.1.0-py3-none-any.whl
Size 171.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c271bc0c3d7ce465d690686cb1e7172b483eeec56d160a2e968f9b3ee87341ea
BLAKE2b-256 checksum
How to use checksums
6d31b2ddf06b0f61a65e9d0e8c2860416092ab097ae81fcec9114875f2e8e601
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.

Transparency log

Security for ifinjected 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for ifinjected-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

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