
Vibe Security
Audit AI-heavy and vibe-coded apps for leaked API keys, unsafe client patterns, spend risk, and prompt-injection mistakes before users do.
Overview
Vibe Security is an agent skill most often used in Ship (also Build integrations) that audits vibe-coded and AI apps for API key exposure, spend abuse, and prompt-injection risks.
Install
npx skills add https://github.com/raroque/vibe-security-skill --skill vibe-securityWhat is this skill?
- AI API keys server-side only—no NEXT_PUBLIC or client-bundle key anti-patterns
- Spending caps on providers plus per-user usage limits in application code
- Prompt injection guidance: never concatenate raw user input into system prompts
- Tailored to vibe-coded stacks (Next.js, React Native/Expo) called out explicitly
- Default prompt: audit my project for security issues via implicit invocation
Adoption & trust: 1.7k installs on skills.sh; 744 GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
You shipped AI features quickly and are unsure whether keys, spend limits, or user-controlled prompts create account-draining or instruction-override vulnerabilities.
Who is it for?
Solo builders shipping Next.js, Expo, or agent apps that call OpenAI, Anthropic, or Google APIs from a hobby or indie codebase.
Skip if: SOX control testing, infrastructure hardening-only reviews with no AI surface, or teams that already enforce enterprise AppSec gates and formal pen tests.
When should I use this skill?
User wants to audit a project for security issues, especially vibe-coded or AI-integrated apps; default prompt uses $vibe-security.
What do I get? / Deliverables
You get a targeted security review of LLM integration patterns with fixes aligned to server-side keys, caps, and safe prompt composition.
- Security findings on keys, spend limits, and prompt handling
- Concrete code-pattern fixes (server-side proxy, caps, sanitized prompts)
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Ship/security is the canonical shelf because the skill is invoked as a pre-release audit gate on a working codebase. Security subphase matches vulnerability review and hardening patterns rather than feature implementation alone.
Where it fits
Validate API routes and env usage while adding chat or completion features.
Add per-user usage tracking and daily caps before exposing a public endpoint.
Run a full-project pass for client-side keys and injection patterns pre-release.
Re-audit after incidents involving runaway API spend or abused prompts.
How it compares
Use as a vibe-coded AppSec checklist for AI apps, not as a SOX workpaper or mobile store analytics skill.
Common Questions / FAQ
Who is vibe-security for?
Indie and solo developers building AI-powered web or mobile apps who want a fast audit of common LLM-related security mistakes.
When should I use vibe-security?
During Build while wiring AI integrations and again at Ship before launch; also after major refactors that touch API routes or client bundles.
Is vibe-security safe to install?
Review may read project files; check the Security Audits panel on this page and avoid pasting live secrets into chat during the audit.
SKILL.md
READMESKILL.md - Vibe Security
interface: display_name: "Vibe Security" short_description: "Audits vibe-coded apps for common security vulnerabilities." brand_color: "#DC2626" default_prompt: "Use $vibe-security to audit my project for security issues." policy: allow_implicit_invocation: true # AI / LLM Integration Security ## API Keys Are Server-Side Only AI API keys (OpenAI, Anthropic, Google, etc.) must never appear in client-side code. They allow unlimited API usage at your expense. A leaked key can drain thousands of dollars in minutes. - No `NEXT_PUBLIC_OPENAI_API_KEY` - No API keys in React Native / Expo bundles - No API keys in client-side JavaScript All AI API calls go through your backend. The client sends the user's message to your server; your server calls the AI API. ## Spending Caps Set hard spending caps on every AI API provider: - OpenAI: Usage limits in dashboard - Anthropic: Spending limits in console - Google: Budget alerts in Cloud Console Also implement **per-user usage limits** in your application: - Track token usage per user in your database - Set daily/monthly caps per user or per tier - Return a clear error when limits are exceeded - Don't rely on the AI provider's caps alone — they may have lag ## Prompt Injection User input must be sanitized before inclusion in prompts. Never concatenate raw user input into system prompts: ```typescript // BAD: user can override system instructions const prompt = `You are a helpful assistant. User says: ${userInput}`; // BETTER: separate system and user messages const messages = [ { role: 'system', content: 'You are a helpful assistant.' }, { role: 'user', content: userInput }, ]; ``` Even with separate messages, be aware that sophisticated prompt injection can still occur. For high-stakes applications, consider: - Input validation and filtering - Output validation before acting on LLM responses - Limiting the LLM's capabilities (no tool access for user-facing chat) ## LLM Output Is Untrusted LLM responses should be treated as untrusted user input: - **Sanitize before rendering as HTML** — LLM output can contain script tags or event handlers - **Never execute LLM output as code** without sandboxing - **Validate tool/function call parameters** — if using function calling, validate all returned parameters against an allowlist and schema before executing ## Tool / Function Calling If your application gives an LLM access to tools (database queries, API calls, file operations): - Restrict operations to a safe allowlist - Validate all parameters from the LLM against a schema - Use least-privilege access (read-only where possible) - Log all tool invocations for audit - Never let the LLM construct raw SQL or shell commands from user input # Authentication & Authorization ## JWT Handling - **Use `jwt.verify()`, never `jwt.decode()` alone.** `decode` reads the payload without checking the signature — an attacker can forge any payload. - **Explicitly reject `"alg": "none"`.** Some JWT libraries accept unsigned tokens if the algorithm is set to `"none"`. Your verification must reject this. - **Validate issuer, audience, and expiration** — not just the signature. ```typescript // BAD: reads token without verifying signature const payload = jwt.decode(token); // GOOD: verifies signature, rejects tampered tokens const payload = jwt.verify(token, secret, { algorithms: ['HS256'], issuer: 'your-app', }); ``` ## Next.js Middleware Is Not Enough Next.js middleware runs at the edge and is convenient for auth checks, but it is **not a reliable sole auth layer**. CVE-2025-29927 demonstrated that middleware could be completely bypassed via a spoofed `x-middleware-subrequest` header. Always verify auth again in: - Server Actions - Route Handlers (`app/api/`) - Data access functions / database queries Middleware should be a convenience layer, not the only wall between an attacker and your data. ## Server Actions Are Public Endpoints Server Actions compile into public POST