From soundcheck
Audits LLM tool definitions, schemas, handlers, and plugins for OWASP LLM07:2025 vulnerabilities like unvalidated inputs, missing authorization, path traversal, and overbroad capabilities. Invoke when implementing tool parameter validation.
npx claudepluginhub thejefflarson/soundcheck --plugin soundcheckThis skill uses the workspace's default tool permissions.
Prevents LLM tools and plugins from being abused via malicious or malformed inputs
Audits MCP tool handlers and schemas for vulnerabilities like shell injection, arbitrary file access, hardcoded secrets, and unconstrained inputs. Use when defining MCP servers or Claude Code extensions with FS/shell/network access.
Applies LangChain security best practices: secrets management, prompt injection defense, safe tool execution, and LLM output validation for production apps.
Audits LLM applications for vulnerabilities using OWASP Top 10 for LLMs, threat modeling, penetration testing, and compliance with NIST AI RMF and ISO 42001.
Share bugs, ideas, or general feedback.
Prevents LLM tools and plugins from being abused via malicious or malformed inputs driven by prompt injection or jailbreaks. Unvalidated tool parameters let an attacker escalate from a chat window to arbitrary file access, command execution, or data exfiltration.
str path parameter with no allowlist — enables path traversal"type": "string" with no enum, maxLength, or pattern constraintsFlag the vulnerable code and explain the risk. Then suggest a fix that establishes these properties:
maxLength, pattern, enum, additionalProperties: false), a typed enum
or sealed class, runtime validation at the top of the handler, or an allowlist
lookup — the goal is that a malformed value never reaches the handler body.../), symlink escape, and absolute-path
injection all fail this check.action parameter. Narrow tools are easier to audit and harder to weaponize.Anchor — shape, not implementation:
schema: { filename: { type: string, maxLength: 128, pattern: "^[\\w-]+\\.(txt|csv)$" } }
def read_file(filename, *, caller):
require(caller.has_permission("file:read"))
target = (ALLOWED_ROOT / filename).resolve()
require(target.is_relative_to(ALLOWED_ROOT))
audit_log("read_file", caller.id, filename)
return target.read()
Confirm the following properties hold (language-agnostic):
maxLength/pattern/enum/additionalProperties: false), a typed enum or sealed class in the method signature, runtime regex/length validation at the top of the handler, or an allowlist lookup against a static set — before the value is usedaction parameter