UNPKG

ubon

Version:

Security scanner for AI-generated apps (Cursor, Lovable, Windsurf, v0). Catches hardcoded secrets, prompt injection, hallucinated imports, Server Actions / Edge runtime mistakes, and the vibe-coded vulnerabilities traditional linters miss.

114 lines 5.97 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.agentRules = void 0; const make = (meta, fileTypes) => ({ meta, impl: { fileTypes: fileTypes || ['json', 'md', 'sh', 'mdc', 'yml', 'yaml'] } }); /** * Claude Code / agent-tooling pack — detects secrets and dangerous patterns * committed in `.claude/`, `.cursor/`, `.windsurf/`, `.aider*`, `CLAUDE.md`, * `.cursorrules`, `.windsurfrules` and MCP configs. Many AI workflows * accidentally commit OAuth tokens, API keys, or `rm -rf "$VAR"` shell hooks * into these dotfiles. */ exports.agentRules = { CC001: make({ id: 'CC001', category: 'security', severity: 'high', message: 'Secret literal inside `.claude/settings*.json`', fix: 'Move the value into `$HOME/.claude/settings.local.json` (outside the repo) or a secret manager. Rotate if it was committed.', impact: 'Claude Code settings committed to the repo are world-readable. API keys in them are instantly exposed on any clone.', helpUri: 'https://docs.claude.com/en/docs/claude-code/settings' }), CC002: make({ id: 'CC002', category: 'security', severity: 'high', message: 'Claude Code hook shell script uses unquoted variable in a destructive command (`rm`/`mv`/`cp`/`eval`)', fix: 'Quote every expansion: `rm -rf "$VAR"`, not `rm -rf $VAR`. Prefer `--` guards to stop flag injection.', impact: 'An unquoted `$VAR` that happens to be empty or contain `/` can wipe the whole working tree when the hook fires.', helpUri: 'https://www.shellcheck.net/wiki/SC2086' }), CC003: make({ id: 'CC003', category: 'security', severity: 'high', message: 'Claude Code hook executes `curl | sh` or pipes remote content to a shell', fix: 'Download to a temp file, verify a checksum, then execute. Never trust network output to run as-is.', impact: 'A compromised or typosquatted URL turns a hook into remote code execution on every tool use.', helpUri: 'https://docs.claude.com/en/docs/claude-code/hooks' }), CC004: make({ id: 'CC004', category: 'security', severity: 'high', message: 'Secret-shaped string inside `CLAUDE.md` / `.claude/agents/*.md`', fix: 'Remove the literal from the markdown. If it was ever committed, rotate the credential.', impact: 'Agent prompt files are part of the prompt itself and ship alongside the repo. A secret in here is as exposed as one in `config.js`.', helpUri: 'https://docs.claude.com/en/docs/claude-code/memory' }), CC005: make({ id: 'CC005', category: 'security', severity: 'high', message: 'MCP server config exposes a secret in its `env` block', fix: 'Read the value from the user\'s shell env at launch (`${VAR}` resolution) rather than committing the literal.', impact: '.mcp.json / `.cursor/mcp.json` / `.windsurf/mcp.json` / `cline_mcp_settings.json` are typically committed. A literal key in `env` leaks on every clone.', helpUri: 'https://modelcontextprotocol.io/docs/concepts/configuration' }), CC006: make({ id: 'CC006', category: 'security', severity: 'high', message: 'Secret-shaped string inside `.cursorrules` / `.cursor/rules/*.mdc` / `.windsurfrules` / `.aiderconfig`', fix: 'Remove the secret from the rules file. These are committed as part of the project prompt.', impact: 'Cursor / Windsurf / Aider rule files are part of the agent prompt and shipped with the repo — a secret here is already disclosed.' }), CC007: make({ id: 'CC007', category: 'security', severity: 'low', message: 'Claude Code session transcripts or TODO state committed to the repo', fix: 'Add `.claude/todos/` and `.claude/history/` to `.gitignore`.', impact: 'Transcripts routinely contain pasted secrets, internal URLs, or customer data. Committing them leaks that context.', helpUri: 'https://docs.claude.com/en/docs/claude-code/overview' }), CC008: make({ id: 'CC008', category: 'security', severity: 'medium', message: 'Prompt-injection marker inside agent rules / memory file', fix: 'Remove lines that try to override the agent\'s behavior (`IGNORE ALL PREVIOUS INSTRUCTIONS`, `disregard the system prompt`, etc.).', impact: 'Agent memory files are concatenated into the prompt. An injection line there redirects the model on every run.', helpUri: 'https://simonwillison.net/2023/May/2/prompt-injection-explained/' }), CC009: make({ id: 'CC009', category: 'config', severity: 'medium', message: 'Cursor hooks config uses an unknown hook event', fix: 'Use a supported Cursor hook event name (`afterFileEdit`, `beforeShellExecution`, `stop`, etc.).', impact: 'A misspelled hook event silently removes the guardrail you expected agents to run.' }), CC010: make({ id: 'CC010', category: 'security', severity: 'medium', message: 'Agent config grants broad autonomous write or network access', fix: 'Use the narrowest sandbox / approval policy that supports the workflow.', impact: 'Broad agent permissions turn prompt mistakes and compromised context into filesystem or network side effects.' }), CC011: make({ id: 'CC011', category: 'security', severity: 'medium', message: 'Agent skill or command runs a dangerous shell pattern', fix: 'Replace raw network shell execution, destructive commands, or publishing steps with explicit reviewed scripts.', impact: 'Skills and commands are reusable agent affordances. A dangerous command there becomes a repeatable foot-gun.' }) }; //# sourceMappingURL=index.js.map