Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
SecureAI-Scan — SecureAI-Scan is a CLI tool that scans TypeScript and JavaScript codebases for security issues specific to AI-powered apps — prompt injection, MCP tool abuse, RAG data poisoning, agent trust violations, and more. | Kitploit
Herramientas/GitHubGitHub/akanthed/secureai-scan
Static AnalysisVulnerability ScannersCode AnalysisDevSecOpsSecret DetectionSupply Chain SecurityLearning & EducationAI Security
GitHubakanthed/secureai-scan

SecureAI-Scan

SecureAI-Scan is a CLI tool that scans TypeScript and JavaScript codebases for security issues specific to AI-powered apps — prompt injection, MCP tool abuse, RAG data poisoning, agent trust violations, and more.

Ver Repositorio
191hace 16h 43mAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir
Sitio web
Contenido no disponible en el idioma solicitado. Mostrando versión en inglés.

SecureAI-Scan

npm version npm downloads CI CodeQL OpenSSF Scorecard license Node OWASP

Offline CLI that scans TypeScript, JavaScript, and Python for LLM, MCP, Agent Skill, and RAG risks — import-resolved dataflow evidence, zero default false positives, mapped to OWASP LLM/ASI/MCP Top 10.

Most scanners in this space pattern-match a keyword and call it a finding. SecureAI-Scan traces the actual source → flow → sink path through real, import-resolved code — and a default scan shows you only what it can prove. No account, no cloud upload, nothing leaves your machine.

Covers the official OWASP Top 10 for LLM Applications 2026, Top 10 for Agentic Applications (2026), and the MCP Top 10 from launch week.

Get started in 30 seconds

root@kitploit:~
npx --yes [email protected] scan .

No account, cloud upload, Python interpreter, or configuration required. TypeScript, JavaScript, Python, MCP configs, and Agent Skill bundles are detected automatically.

Measured 0.9.0 release candidate: 136/136 tests · 88.08% statement coverage · 12,676 files across 9 public repositories · 0 new default-tier fingerprints against the reviewed baseline. Evidence · methodology and limits

root@kitploit:~
  ▌ HIGH  AI001  Prompt injection via user input
    PROVEN  LLM01:2026 Prompt Injection

    source src/chat.ts:8   request data `req.body.input`
    flow   src/chat.ts:13  passed as `systemPrompt`
    sink   src/chat.ts:10  openai.chat.completions.create — system role (OpenAI)

    fix    Keep system prompts static; pass user input as a user-role message.

Is this for you? SecureAI-Scan is scoped deliberately to LLM, MCP, and RAG/agent risks — prompt injection, tool poisoning, unsafe output handling, vector-store access control, agent-skill poisoning. It is not a general SAST or secrets scanner, and doesn't try to be one; a known-malicious package with no LLM-shaped payload (e.g. a hardcoded exfiltration address in an email API call) is caught by the offline advisory list (DEP003), not a pattern rule. If your codebase talks to an LLM, an MCP server, a vector store, or ships Agent Skills, this is built for you.

New: static config scanning for LiteLLM Proxy (config.yaml) — hardcoded secrets, plaintext provider endpoints, missing guardrails. See Rules (LLC001–LLC003).

Contents

  • Why this scanner is different
  • How it compares
  • Get started in 30 seconds
  • See it work
  • Commands
  • GitHub Action
  • Rules
  • Architecture
  • MCP server (use it from Claude)
  • Claude Skill
  • Trust and release assurance
  • The precision contract
  • Testing & benchmarking
  • Roadmap
  • Contributing

Why this scanner is different

  • Evidence tiers, not noise. Every finding is proven (traced dataflow or parsed config fact), likely (resolved sink, one heuristic hop), or heuristic. A default scan shows only proven + likely. Heuristics are opt-in via --paranoid.
  • Import-resolved detection. A call is only an "LLM call" if it resolves to a real SDK import (openai, @anthropic-ai/sdk, ai, @google/genai, LangChain, Bedrock, …). Your Google Maps client will never be flagged as an LLM again.
  • Precision-gated, and benchmarked against real repos. The test suite asserts every vulnerable fixture fires and every safe fixture stays clean — a false positive on the safe corpus fails the build. Beyond that, npm run regression scans real public repos (OpenAI/Anthropic/Vercel AI SDKs, official MCP servers, LlamaIndex) against a committed, hand-reviewed baseline and fails on any new proven/likely finding. See for the actual before/after numbers, or for the story behind them — a 6/6 catch rate on a labeled malicious-skill corpus, and why we're calling llama_index "vulnerable" over an honest library-level finding.

How it compares

SecureAI-Scan is not a replacement for a general SAST tool or a container/IaC scanner — run it alongside one, not instead of one. It is purpose-built for the LLM/MCP/RAG attack surface and emphasizes dataflow evidence over flat keyword findings.

If you already run Semgrep or GHAS, keep them — add SecureAI-Scan for the risk surface they don't model at all.

Prefer to ask questions first? Try the free SecureAI-Scan AI Security Advisor on ChatGPT.

About to run an MCP server you found on GitHub or Twitter? Paste its tool description into MCP X-Ray first — checks it for hidden Unicode, injected instructions, and known-malicious packages in your browser, no install.

See it work

Attack shapes the scanner traces end to end:

MCP tool-poisoning dataflowRAG context-injection dataflow
MCP attack traceRAG poisoning trace

Commands

The one you need 95% of the time:

root@kitploit:~
secureai-scan scan .

Everything else is there when you need it. secureai-scan scan . --help shows all of this in the terminal, grouped the same way:

Everyday

Scope which rules run

CI / workflow

FlagWhat it does

Advanced

Scan before you install — no clone, no config:

root@kitploit:~
secureai-scan skill anthropics/skills          # a GitHub "owner/repo" shorthand
secureai-scan skill https://github.com/…       # or a full git URL
secureai-scan skill ./some/local/skill-dir     # or a local path
secureai-scan mcp some-mcp-server-package      # a bare npm package name
secureai-scan mcp owner/mcp-server-repo        # or git, same as `skill`

skill and mcp fetch the target and scan it, then delete the fetched copy (--keep to inspect it instead). Nothing fetched is ever executed: an npm target is downloaded with npm pack — the tarball only, no install, no lifecycle scripts — and a git target is a plain git clone --depth 1. This is the moment that matters most: before a skill lands in ~/.claude/skills/ or a server lands in .mcp.json, not after.

Other commands:

root@kitploit:~
secureai-scan bom . --output AI_BOM.md   # AI Bill of Materials
secureai-scan explain AI001              # why + exploit + fix example, for any rule
secureai-scan threat-model .             # THREAT_MODEL.md with the OWASP coverage matrix
secureai-scan init                       # policy file + CI workflow, one-time setup

Suppress a reviewed finding in code:

root@kitploit:~
// secureai-ignore AI001: reviewed, input sanitized via allowlist

GitHub Action

root@kitploit:~
name: SecureAI-Scan
on: [pull_request]
permissions:
  contents: read
  security-events: write
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: akanthed/[email protected]
        with:
          scanner-version: 0.10.0
          fail-on: high

Findings appear as inline annotations on the PR and in the repository's Security tab. (secureai-scan init generates an equivalent workflow using the CLI directly.)

Scanning clean? Add the badge to your own README:

root@kitploit:~
[![secureai-scan](https://img.shields.io/badge/secureai--scan-passing-brightgreen)](https://github.com/akanthed/SecureAI-Scan)

Rules

42 rules, mapped to the official OWASP Top 10 for LLM Applications (2026) — plus, where applicable, the OWASP Top 10 for Agentic Applications (2026, ASI), the OWASP MCP Top 10 (2025), and an EU AI Act article. See the versioned 2026 coverage and limits; threat-model renders the matrix for each scanned project.

secureai-scan explain <RULE_ID> gives the exploit walkthrough and a before/after code example for any rule.

Architecture

Three independent scanning surfaces feed one merged, deduped finding list:

root@kitploit:~
                    ┌─────────────────────┐
  *.ts / *.js  ───▶ │  ts-morph AST rules │───┐
                    │  (import-resolved   │   │
                    │   sinks + dataflow) │   │
                    └─────────────────────┘   │
                                               │
                    ┌─────────────────────┐   │      ┌──────────────┐      ┌─────────────────┐
  *.py         ───▶ │  tree-sitter AST + │───┼───▶  │  scan.ts     │───▶  │  evidence filter │
                    │  local taint flow   │   │      │  merge/dedupe│      │  → confidence    │
                    └─────────────────────┘   │      │  + suppress  │      │  → severity      │
                                               │      │  (// secure- │      │  → baseline diff │
  .mcp.json,         ┌─────────────────────┐  │      │  ai-ignore)  │      │  → report        │
  SKILL.md      ───▶ │  Config/bundle scan │──┘      └──────────────┘      └─────────────────┘
                    │  (off-disk, evasion- │                                        │
                    │   resistant)         │                                        ▼
                    └─────────────────────┘                         terminal · sarif · json · md · html

  package.json,
  requirements.txt ─▶ dependency-guard.ts (advisories.ts, offline, version-aware)

Every AST rule only calls a function an "LLM call" if it resolves through real imports to a known SDK — never by name-matching alone. See docs/Architecture.md for the full breakdown of each surface, and docs/DetectionEngine.md for how the evidence-tier contract works.

MCP server (use it from Claude)

The package ships an MCP server exposing scan_repository, explain_rule, generate_bom, and scan_untrusted_target (fetch and scan a skill or MCP server before Claude recommends installing it — same fetch-without-executing behavior as the skill/mcp CLI commands):

root@kitploit:~
{
  "mcpServers": {
    "secureai-scan": {
      "command": "node",
      "args": ["/path/to/secureai-scan/mcp-server/index.js"]
    }
  }
}

Claude Skill

For Claude Code / Claude.ai users, skills/secureai-scan/SKILL.md teaches Claude when to run a scan (reviewing AI/LLM code, or checking an MCP server/Agent Skill before you install it) and how to read the results — no separate process to run, unlike the MCP server above. Copy the skills/secureai-scan/ directory into your .claude/skills/ to use it.

Evasion resistance

In July 2026, two pieces of public research showed that Agent Skill scanners are trivially bypassed.

Cloak and Detonate (Ji, Xu, Li, Gao, Wei, Wang & Cheung — HKUST, arXiv:2607.02357) ran an adversarial study against nine published skill scanners using 1,613 in-the-wild malicious skills. Two attack families, both of which preserve the payload exactly:

  • Reify — rewrite the bytes a rule matches, while the agent still reassembles the original at runtime. >80% bypass on most static scanners.
  • Disperse / SFS packing — move the payload outside the rule's scope: into a directory the scanner skips, behind a renamed extension, or archived and encoded into .git/, with a benign cover SKILL.md that rebuilds it on first run. ≥90% bypass on every scanner tested, ≥96% on most. One hybrid scanner's detection rate fell from ~99% to ~10%.

Separately, Gecko Security (VentureBeat) shipped a payload in a *.test.ts file. Every public scanner skipped it — but Jest and Vitest auto-discover and execute those files on the next npm test.

SecureAI-Scan handles each published technique. Every row below has a corresponding test in test/deobfuscate.test.js or a fixture in test-fixtures/vulnerable/skills/:

This does not weaken the precision contract

Deobfuscation is usually a precision risk — more matches, more noise. Here the logic is inverted: a match that appears only after deobfuscation is promoted to proven, not demoted. Ordinary documentation does not contain a zero-width joiner inside "ignore previous instructions", nor a Cyrillic с inside curl. The concealment is itself affirmative evidence of intent.

The comparison is against the set of raw matches, not merely "did the raw text match at all" — otherwise an attacker could mask the signal by leaving one innocuous phrase in the clear.

The two new bundle rules fire only on conjunctions, never on a keyword:

  • SKL004 needs an opaque blob and an unpack directive that references that blob by name — a README mentioning tar -x next to an unrelated binary asset is not enough. Real archives (gzip/zip/png/pdf/wasm — checked by magic bytes, not extension) are never "opaque" in the first place, however they're compressed.
  • SKL005 needs a concrete credential signal — a path (~/.aws/credentials, not the word "token") or bulk environment-variable enumeration (os.environ.items(), not os.environ["API_KEY"]) — and egress to a hardcoded non-local host, within 25 lines of each other in the same file, or a remote fetch that gets executed after being reassigned through one or more renames. A publish helper that reads ~/.npmrc in one function and calls a registry forty lines later stays clean, and reading one named env var for an API call is never flagged — both shapes are pinned as safe fixtures.

Validated against two real-world corpora, not just fixtures we wrote ourselves: 0 findings across all 18 real skill bundles in anthropics/skills and all 14 in vercel/ai, and 6/6 correct on cisco-ai-defense/skill-scanner's labeled eval corpus (20 skills, each with an _expected.json verdict) with zero false positives on anything labeled safe. See Testing & benchmarking.

What this is not

Honest limitation: the paper's conclusion is that runtime detonation beats static analysis, and that is correct. An adaptive adversary who knows these rules can write a transformation they don't cover. What changes here is the cost of evasion — the published, currently-circulating techniques no longer work, and the obfuscation needed to defeat them now itself raises the finding's severity. Static scanning is a filter, not a security boundary. Treat an untrusted skill as untrusted code regardless of what any scanner says.

Trust and release assurance

  • CI runs on Linux, Windows, and macOS across supported Node versions.
  • CodeQL, production dependency audit, OpenSSF Scorecard, Dependabot, and this scanner's own blocking self-scan provide independent checks.
  • Every manual npm publication invokes tests, coverage floors, the reviewed real-repository regression gate, and tarball inspection through prepublishOnly.
  • GitHub Actions receives no npm password or token and cannot publish the package.
  • Release assurance, single-maintainer governance, security reporting, and versioned benchmark evidence are public.

This is a single-maintainer project with no contractual SLA or independent certification. The controls above reduce risk; they do not turn a static scan into proof of security.

The precision contract

False positives kill scanners. SecureAI-Scan's rule engine follows three hard rules:

  1. Sinks are resolved through imports. If an identifier resolves to a module that is not an LLM SDK, it is definitively not an LLM call — no matter what it's named.
  2. Evidence is labeled, never blended. A traced dataflow and a word-proximity match are not the same thing, so they never share a tier.
  3. The safe corpus gates every release. test-fixtures/safe/ contains the patterns that used to cause false positives (redacted PII payloads, Google Maps clients, env-var API keys next to LLM clients, ordinary response logging, OAuth metadata fields, streaming-response chunks, fiction/narrative prompt text). Any finding there fails the suite.

Testing & benchmarking

Three layers, because one alone isn't enough to trust a scanner's claims — precision and recall are different failure modes, and both get checked.

1. Fixture corpus — precision + recall, runs on every build.

root@kitploit:~
npm test

test-fixtures/vulnerable/ and test-fixtures/safe/ are scanned together: every vulnerable fixture must fire its expected rule at proven/likely evidence (recall), every safe fixture must produce zero proven/likely findings (precision). Fast and deterministic — but it only proves the scanner behaves on code written specifically to test it.

2. Real-world regression benchmark — against public repos we didn't write.

root@kitploit:~
npm run regression                          # scan the full curated repo set
npm run regression -- --fresh               # re-clone everything first
npm run regression -- openai-node           # scan just one repo by name
npm run regression -- --update-baseline     # accept the current findings

scripts/regression-scan.js clones a curated, diverse set of real public repos (OpenAI/Anthropic/Vercel AI SDKs, the official MCP servers and TypeScript SDK, LlamaIndex, plus anthropics/skills and cisco-ai-defense/skill-scanner for skill-bundle coverage — spanning TS and Python, SDK-consumer example code and SDK-author source) and scans each with the built CLI.

It exits non-zero on any proven/likely finding not already in test/regression-baseline.json — a hand-reviewed record of findings already read against their source line. Fingerprints are repo|rule|file, not line numbers, so ordinary upstream churn doesn't produce noise. A new fingerprint is a claim the scanner has to justify: if it isn't a genuine issue it's a rule bug, fixed at the root cause and locked in as a new test-fixtures/safe/ fixture. Baselining a finding you haven't read defeats the entire mechanism.

Skill-bundle coverage gets its own line because cisco-ai-defense/skill-scanner's evals/ corpus is labeled — each of its 20 fixtures ships an _expected.json verdict and sits under a directory literally named malicious/ or safe/, so it doubles as a recall check, not just a precision one: 6/6 in-scope malicious fixtures fire, 0 findings on anything labeled safe, and 0 findings across all 18 real bundles in anthropics/skills and all 14 in vercel/ai. (The remaining Cisco categories — SQL injection, path traversal, resource exhaustion, generic eval() of a function argument, a payload deliberately split across four files — are either out of the documented LLM/MCP/RAG scope or beyond same-file conjunction analysis; see the 0.6.0 changelog entry for the specific reasoning on each.)

Historical before/after from the run that drove the original precision fixes (findings at default evidence level, no --paranoid):

Current run (2026-08-06) — versioned evidence is recorded in docs/benchmarks/v0.9.0.json:

The vercel/ai triage found three real, root-caused bugs — none specific to the v0.6.0 skill rules, all in shared logic used across many rules:

  1. resolveLlmSink treated any call resolved to an LLM SDK module as a model invocation, regardless of method name — flagging isToolUIPart (a type guard the ai package exports right alongside generateText) as an LLM call. This alone caused 3 of the 5 finding groups (AI001, AI003, AI010).
  2. DANGEROUS_CALLEES in AI005 includes "query" for SQL-injection-style sinks, but "query" is also a legitimate LLM/agent invocation verb — claudeSdk.query({ prompt, options }), the Claude Agent SDK's own model call, was flagged as "LLM output passed to a dangerous sink" purely because of the shared method name.
  3. REQUEST_SOURCES (duplicated identically across MCP002, MCP010, VEC003) matched a bare "params." — any function parameter conventionally named params, not necessarily HTTP request data. A URL-scheme validator (assertOpenLinkParams(params: unknown)) got flagged as "MCP server URL from user input."

All three fixed at the root cause (not the specific call site) and pinned as permanent fixtures under test-fixtures/. Full details in CHANGELOG.md.

3. Vulnerable-vs-patched validation — proves recall, not just precision.

The two layers above only check that the scanner stays quiet on safe code. DEP003's advisory checks are validated the other way: pin a package to a documented-vulnerable version and confirm it's flagged, then pin it to the patched version and confirm it isn't.

root@kitploit:~
node --test test/dependency-guard.test.js

covers: [email protected] (CVE-2025-6514, vulnerable) flagged / [email protected] (patched) clear; [email protected] (before the backdoor) clear / [email protected] (after — no legitimate patch exists for a malicious package) still flagged; llama-cpp-python==0.2.71 (CVE-2024-34359, from the OSV-generated set) flagged / ==0.2.72 (patched) clear, including under PyPI name normalization (llama_cpp_python); and langchain>=0.1.0-style unpinned specifiers producing zero default-report findings. Building this test caught a real gap: DEP003 used to match advisories by package name only, never actually comparing the declared version against the advisory's affected range — fixed in src/scanner/semver.ts.

Ambiguity is resolved differently per advisory kind, deliberately. A malicious package fires even when the declared version can't be resolved — installing a backdoor is unrecoverable, so it fails toward flagging. A CVE fires at proven only when the declared version is an exact pin provably inside the affected range; unpinned-but-possibly-affected drops to heuristic (--paranoid only). Applying the malicious-kind rule to a 162-entry CVE snapshot would put a critical finding on every repo that declares langchain>=0.1.0 — unactionable noise at scale.

Roadmap

See ROADMAP.md for what's shipped and what's planned. Both language engines are AST-based: ts-morph for TypeScript/JavaScript and Tree-sitter for Python. Python imports, calls, assignments, decorators, scopes, keyword arguments, dictionary fields, and strings are syntax nodes; target code is never imported or executed, and no Python interpreter is required. The remaining Python gap is bounded cross-function/cross-file taint depth, not parsing. Scan performance and known limits are documented in docs/Performance.md.

Contributing

Contributions are welcome — see CONTRIBUTING.md for the workflow, and docs/WritingRules.md / docs/RuleDevelopment.md for how to add a detection rule that meets the precision bar above. Every new rule needs a fixture in both test-fixtures/vulnerable/ and test-fixtures/safe/, an entry in src/scanner/catalog.ts, and a case in test/corpus.test.js — npm test enforces all three.

License

MIT © Akshay Kanthed

Descargar herramienta
Testing & benchmarking
What we found scanning real repos
not
Discussion write-up →
  • SARIF for GitHub code scanning. --output report.sarif puts findings inline on pull requests and in the Security tab.
  • AI-BOM. secureai-scan bom . builds a syntax-derived inventory of SDKs, model IDs, vector stores, agent frameworks, and MCP servers, mapped to OWASP LLM Top 10 / EU AI Act documentation needs.
  • MCP config scanning. Parses .mcp.json, claude_desktop_config.json, .cursor/mcp.json: unpinned npx -y servers, inline secrets, plaintext HTTP transports.
  • MCP tool-poisoning detection. Catches the pattern behind the WhatsApp MCP rug-pull and postmark-mcp backdoor — invisible Unicode, agent-directed injection phrases, and cross-tool shadowing in tool names/descriptions, statically, before you ever run the server.
  • MCP command-injection detection. Flags MCP stdio transport command/args built from request data — the pattern behind the 2026 MCP STDIO RCE disclosure.
  • Agent Skill poisoning detection. The same invisible-Unicode, injection-phrase, and shadowing checks applied to SKILL.md files — Agent Skills load into context wholesale, so a poisoned skill is a poisoned tool description by another name.
  • Evasion-resistant skill scanning. Skill bundles are scanned as directories, not just their SKILL.md, and every content check runs against deobfuscated variants of the text. This targets the published techniques — homoglyphs, zero-width splitting, payloads staged in .git/ or build/, exfiltration hidden in a *.test.ts file — that bypassed >90% of the nine scanners surveyed in Cloak and Detonate (arXiv:2607.02357). See Evasion resistance.
  • Known-vulnerable and known-malicious package advisories, version-aware. Checks every dependency and every MCP-launched package against a bundled advisory snapshot — a hand-curated list of documented in-the-wild backdoors, plus HIGH/CRITICAL OSV advisories for an LLM/MCP/RAG package watchlist, regenerated by scripts/sync-advisories.js. Runs offline on every scan, no flag required. A CVE only fires when your pinned version is provably inside the affected range; a documented-malicious package fires even on an ambiguous range, because installing a backdoor is unrecoverable.
  • Local-first. Nothing leaves your machine.
  • SecureAI-ScanSemgrep (OSS rules)TrivyGitHub Advanced Security
    Prompt injection (source→sink traced)✅ import-resolved dataflow⚠️ pattern rules only, community-maintained❌⚠️ CodeQL can, but no AI-specific ruleset
    MCP tool-poisoning / config risk✅ MCP007–010, config scanner❌❌❌
    Agent Skill poisoning (SKILL.md)✅ evasion-resistant, bundle-aware❌❌❌
    RAG / vector-store misconfig✅ VEC001–004❌❌❌
    Known-malicious AI package advisories✅ DEP003, offline, version-aware❌⚠️ general CVE feed, not AI-specific⚠️ Dependabot, general CVE feed
    General SAST (SQLi, XSS, path traversal)❌ out of scope by design✅❌✅
    Container / IaC scanning❌❌✅⚠️ via CodeQL/Actions
    Evidence tiers (proven/likely/heuristic)✅❌ findings are flat❌⚠️ CodeQL has some, not AI-tuned
    SARIF output (GitHub code scanning)✅✅✅native
    Runs offline, no account✅✅ (OSS rules)✅❌ requires GitHub
    FlagWhat it does
    (none)proven + likely findings — the default, no flags needed
    --paranoidalso include heuristic-tier findings
    -s, --severity <level>only show findings at/above low|medium|high|critical
    --output <file>write a full report — .sarif (GitHub code scanning), .json, .md, or .html
    FlagWhat it does
    -r, --rules <list>run only these rule IDs, e.g. AI001,MCP007
    --only-ai / --only-mcp / --only-vec / --only-sklrun only one rule category
    --check-dependenciesalso check package.json/requirements.txt against the npm/PyPI registry for typos and hallucinated packages (DEP001/DEP002). Auto-enabled if you select those rules directly via -r — you never need to remember to pass both. Not needed for DEP003 (known-malicious packages), which always runs offline
    --fail-on <severity>exit 1 if findings at/above this severity exist
    --baseline <file>track only new/changed issues against a saved baseline
    --policy <file>load thresholds, skipped paths, and blocked rules from a .secureai-policy.json (auto-detected if present — secureai-scan init creates one)
    FlagWhat it does
    --min-confidence <0-1>finer-grained than --paranoid: hide findings below an exact confidence score (0.9 proven / 0.65 likely / 0.35 heuristic)
    --limit <n>max rule groups shown in the terminal (default 10) — full detail always goes to --output
    --debugprint every file scanned and which rules ran
    RuleWhat it provesOWASP
    AI001User input flows into a system/developer prompt (traced source → sink, including across function/file boundaries)LLM01
    AI002Prompt content or secrets written to logs (in files that use an LLM SDK)LLM02
    AI003LLM call in a request handler with no auth check before itLLM06
    AI004Whole user/session object serialized into a prompt (field-picking is not flagged)LLM02
    AI005LLM output reaches eval/exec/SQL/HTML sinksLLM10
    AI006High-impact tools (delete, pay, deploy, …) exposed without an approval gateLLM03
    AI007Retrieved RAG content interpolated into privileged promptsLLM01
    AI008Secrets embedded in system prompt textLLM08
    AI009Unbounded user input / missing token limitsLLM06
    AI010Fetched external content flows into promptsLLM01
    AI011Agent output elevated to system-role in downstream callsLLM03
    AI012LLM output parsed without schema validationLLM10
    MCP001MCP tool metadata reaches the system prompt without validationLLM01
    MCP002MCP server URL constructed from user inputLLM04
    MCP003MCP tool results elevated to system-roleLLM10
    MCP004MCP server launched as an unpinned npx -y packageLLM04
    MCP005Secret inlined in a committed MCP configLLM02
    MCP006MCP server over plaintext HTTPLLM04
    MCP007Invisible/bidi Unicode hidden in MCP tool names or descriptionsLLM01 · MCP03
    MCP008Agent-directed injection phrases in MCP tool descriptionsLLM01 · MCP03
    MCP009A tool description that steers calls to a different tool (shadowing)LLM01 · MCP03
    MCP010MCP stdio server command/args constructed from user input (RCE)LLM04 · MCP05
    SKL001Invisible/bidi Unicode anywhere in an Agent Skill bundleLLM01
    SKL002Agent-directed injection phrasing in a skill's description or body (matched through obfuscation)LLM01
    SKL003A skill's content steers when/how a different skill is used (shadowing)LLM01
    SKL004Staged/self-extracting payload: opaque blob + instructions to decode and run itLLM04 · MCP04
    SKL005Credential read + hardcoded external egress in a bundle companion fileLLM02 · MCP04
    SKL006Load-time command execution via Claude Code's dynamic-context-injection syntax (!`cmd`/```!), before any tool-permission gateLLM04 · MCP05
    SKL007Unscoped Bash grant in a skill's allowed-tools frontmatterLLM03
    SKL008Skill fetches instructions from an external URL and directs the agent to follow them ("Circus of Skills")LLM04
    SKL009Skill persists a backdoor by writing into another context file (MEMORY.md/SOUL.md/AGENTS.md/CLAUDE.md)LLM05
    SKL010Unsafe YAML/JSON deserialization tag in a skill's frontmatter or a bundled config fileLLM04
    VEC001Vector search without a tenant/user filterLLM09
    VEC002Unbounded or user-controlled search limitLLM06
    VEC003User content ingested into a shared vector storeLLM05
    VEC004Ingestion without tenant/namespace taggingLLM09
    DEP001Dependency name not found in the registry (opt-in --check-dependencies)LLM04
    DEP002Dependency name one edit away from a popular package (opt-in)LLM04
    DEP003Dependency with a documented malicious release or critical CVE — checked offline on every scan, version-range aware (postmark-mcp, mcp-remote CVE-2025-6514, …)LLM04 · MCP04
    LLC001Hardcoded secret in a LiteLLM proxy config.yamlLLM02
    LLC002LiteLLM proxy api_base reachable over plaintext HTTPLLM04
    LLC003LiteLLM proxy config has no guardrails: section (heuristic, --paranoid only)LLM03
    Technique (paper's name)ExampleHow it's handled
    Zero-width insertionIgn‍ore all pre‍vious…Text is matched against invisible-stripped variants
    Confusable glyphsсurl (Cyrillic с)Homoglyph folding to ASCII before matching
    Case flipEvAlAll content patterns are case-insensitive
    Variable splicing'cu' + 'rl'Adjacent string literals joined before matching
    Per-line splittingev⏎al(x)Intra-word line breaks joined as an extra variant
    Per-file extractionpayload in a sourced helperWhole bundle is scanned, not just SKILL.md
    Directory relocationscripts/x.sh → build/x.shNo directory skip-list inside a bundle
    Extension renamingx.sh → x.txtFiles are scanned by content, not extension
    Size paddingpad past the scanner's capOversized files are head-read, never skipped
    SFS packingpayload in .git/skillpack.datAny non-git file under a bundle's .git/ is proven (SKL004)
    Test-file stagingpayload in *.test.tsBundle scanning deliberately does not demote test paths (SKL005)
    RepoBeforeAfterWhat was wrong
    vercel/ai7731examples/, top-level tests/, and hyphenated ecosystem-tests/-style directories weren't recognized as lower-trust paths; chunks (a common streaming-response variable) was treated as unambiguous RAG evidence
    openai/openai-node470Same path-detection gap, applied to the SDK's own examples//ecosystem-tests/
    anthropics/anthropic-sdk-typescript20Same path-detection gap on a top-level tests/ directory
    modelcontextprotocol/typescript-sdk30token_endpoint/tokenType-style OAuth metadata fields flagged as leaked secrets
    run-llama/llama_index1815A Python check flagged any description= field containing "system prompt" as proven MCP tool poisoning, regardless of context. The remaining 15 are VEC001 hits on the library's own generic retriever definitions — scanning a vector-DB SDK's own source, not application code, so a filter can't exist to check; an honest, inherent limit, not a bug
    RepoFindingsRulesStatus
    openai-node, anthropic-sdk-typescript, anthropic-sdk-python, modelcontextprotocol/typescript-sdk, modelcontextprotocol/servers0—clean
    anthropics/skills (18 real skill bundles)0—clean — pure precision check for SKL001–005
    vercel/ai (5,691 files)0—was 40 (AI001, AI003, AI005, AI010, MCP002) before triage — every one hand-reviewed against source and confirmed a false positive, traced to 3 independent root-cause bugs (see below), fixed, and re-confirmed clean on a full re-scan
    run-llama/llama_index46VEC001inherent limit, not a bug — the library's own generic retriever definitions, where no tenant filter can exist to find
    cisco-ai-defense/skill-scanner7SKL001, SKL002, SKL005all on fixtures labeled malicious/ — 6/6 in-scope, 0 on anything labeled safe/