shieldline
v0.1.9
Published
Security scanner for vibe-coded apps — catches hardcoded secrets, unprotected routes, weak JWT secrets, unverified webhooks, and more before you deploy
Maintainers
Readme
🛡️ Shieldline
A security scanner for vibe-coded apps.
Shieldline catches the high-impact, easy-to-miss security mistakes before you ship — hardcoded secrets, unprotected API routes, unverified webhooks, weak JWT secrets, and more. It runs in seconds, outputs plain English, and gets out of your way.
npx shieldline scan 🛡️ GUARDRAIL · security scan
CRITICAL Hardcoded secret detected ● certain
src/lib/stripe.ts:3
1 │ import Stripe from 'stripe';
2 │
❯ 3 │ const stripe = new Stripe('sk_live_51Mz9xYLk...');
• Risk: If this gets pushed to GitHub, bots will find it within minutes
and drain your Stripe account.
• Fix: Move to an environment variable: process.env.STRIPE_SECRET_KEY
• Rule: hardcoded-secrets · Issue #1
────────────────────────────────────────────────────────────────────────
✖ 1 issue found · 42 files · 87ms
1 critical · 0 high · 0 medium · 0 low
⚠ Fix critical and high issues before deploying.Install
# Clone the repo
git clone https://github.com/your-username/shieldline.git
cd shieldline
# Install dependencies
npm install
# Run a scan (development)
npx shieldline scan /path/to/your/projectnpm package coming soon. For now, clone and run directly.
Usage
Scan a project
# Scan current directory
npx shieldline scan
# Scan a specific directory
npx shieldline scan /path/to/your/project
# Only show high severity and above
npx shieldline scan --min-severity high
# CI mode — exit with code 1 if issues found
npx shieldline scan --strict
# JSON output (for CI/CD pipelines, editor integrations)
npx shieldline scan --json
# Disable a specific rule
npx shieldline scan --disable-rule hardcoded-secretsGet an AI explanation (BYOK)
Shieldline can explain any issue in plain English, describe a realistic attack scenario, and give you step-by-step fix instructions — powered by your own API key.
# Explain issue #1 from your last scan
npx shieldline explain 1
# Explain by issue ID
npx shieldline explain hardcoded-secret-12
# Explain issues in a specific directory
npx shieldline explain 1 --dir /path/to/projectSet your API key to unlock AI explanations:
# Anthropic (recommended)
export ANTHROPIC_API_KEY=your-key-here
# Get one at: https://console.anthropic.com
# Or OpenAI
export OPENAI_API_KEY=your-key-here
# Get one at: https://platform.openai.com/api-keysThe scanner works fully without an API key. The explainer degrades gracefully to static output.
What Shieldline checks
| Rule | What it catches | Severity |
|---|---|---|
| hardcoded-secrets | API keys, tokens, and passwords committed to source code. Uses known prefix matching (Stripe, AWS, GitHub, etc.) + entropy analysis. | Critical |
| leaky-env | NEXT_PUBLIC_ / VITE_ / REACT_APP_ variables that expose secrets to the browser bundle. | Critical |
| unauth-mutations | DELETE, PUT, and PATCH route handlers with no authentication guard. Framework-aware: recognizes Clerk, Supabase, NextAuth, Firebase, Auth0, Lucia, Passport, tRPC, and Next.js middleware. | High |
| unauth-server-actions | Next.js Server Actions ('use server') that mutate data without an auth check. | High |
| unverified-webhook | Webhook handlers (Stripe, Svix, GitHub, etc.) that don't verify the request signature — allowing anyone to send fake events. | High |
| wildcard-cors | Access-Control-Allow-Origin: * — escalates to Critical when combined with credentials: true. | High / Critical |
| dangerous-inner-html | dangerouslySetInnerHTML without a sanitization library. Detects user-controlled input and missing DOMPurify. | High / Critical |
| weak-jwt-secret | JWT and session secrets that are hardcoded, too short, or obviously guessable ("secret", "password", etc.). | Critical |
| dynamic-execution | eval() with dynamic arguments, new Function(), and import() with data: URIs — RCE vectors. | Critical / High |
Framework support
Shieldline is framework-aware. It understands how auth actually looks in modern stacks:
Auth detection: Clerk (auth(), auth.protect(), currentUser()), Supabase (supabase.auth.getUser(), createServerClient()), NextAuth/Auth.js (getServerSession(), await auth()), Firebase Admin (verifyIdToken()), Auth0 (withApiAuthRequired()), Better Auth, Lucia, Passport.js, tRPC (protectedProcedure), and generic patterns.
Middleware: Reads your middleware.ts matcher config and checks whether it actually covers the route being scanned. A middleware that excludes /api won't suppress warnings on /api routes.
Webhook verification: Recognizes Stripe (constructEvent), Svix, PayPal, GitHub, Shopify, and generic HMAC patterns.
Configuration
.shieldlineignore
Works like .gitignore. Place in your project root to exclude paths:
# .shieldlineignore
src/generated/**
legacy/**CLI options
| Flag | Default | Description |
|---|---|---|
| --min-severity | medium | Minimum severity to report (critical, high, medium, low) |
| --min-confidence | low | Minimum confidence to report |
| --strict | off | Exit code 1 if any issues found (for CI) |
| --json | off | Output as JSON |
| --disable-rule | none | Disable specific rule(s) by ID |
CI/CD integration
# GitHub Actions
- name: Shieldline security scan
run: |
cd shieldline
npx shieldline scan /path/to/your/app --strict --jsonThe --strict flag makes Shieldline exit with code 1 on any finding, blocking the deploy. Use --min-severity high if you only want to block on high/critical issues.
Design philosophy
High signal, low noise. Every rule is tuned to near-zero false positives on real-world codebases. We've tested against 8+ production repos. If Shieldline says HIGH/HIGH, it's worth your attention.
Honest about confidence. Issues are labeled certain, high, medium, or low confidence. A medium/low advisory is not the same as a critical/certain finding. The tool doesn't treat them the same and neither should you.
Fast. Scans run entirely locally with no network calls. A 5,000-file monorepo scans in under 5 seconds.
No lock-in. The scanner is free, offline, and requires no account. AI explanations use your own API key — we never see your code or your credentials.
What Shieldline is NOT
- Not a full static analysis tool (no data-flow / taint analysis)
- Not a pentesting tool
- Not a replacement for
npm audit(dependency vulnerabilities are out of scope) - Not continuous monitoring (run it pre-deploy, not as a daemon)
For deeper analysis, pair Shieldline with Semgrep or CodeQL.
Development
# Run tests
npm test
# Watch mode
npm run test:watch
# Build
npm run buildAdding a rule
Each rule is a single file in src/rules/ that exports a Rule object:
export const myRule: Rule = {
id: 'my-rule',
name: 'Human Readable Name',
description: 'What this rule detects.',
run(ctx: RuleContext): Issue[] {
// ctx.filePath, ctx.fileContent, ctx.lines
// Return [] for no issues, or Issue[] with findings
return [];
},
};Register it in src/rules/index.ts and add tests in tests/rules/.
License
MIT
