skills/security-audit/SKILL.md
Audit security configurations - CSP, RLS, auth, dependencies, and OWASP vulnerabilities. Use before deployments or after adding integrations.
npx skillsauth add ahmedhamadto/software-forge security-auditInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Audit security configurations for your webapp and backend services.
Before starting, identify the security-relevant files in the current project:
# Locate security-relevant files
grep -rn "Content-Security-Policy" --include="*.html" --include="*.tsx" --include="*.jsx"
grep -rn "corsHeaders\|Access-Control" --include="*.ts" --include="*.js"
find . -name "*.sql" -path "*/migrations/*" | head -20
grep -rn "sanitize\|DOMPurify\|xss" --include="*.ts" --include="*.js" --include="*.jsx" --include="*.tsx"
grep -rn "AuthContext\|AuthProvider\|useAuth\|getSession" --include="*.ts" --include="*.js" --include="*.jsx" --include="*.tsx"
Look for: CSP meta tags in HTML or CSP headers in server/deployment config.
Reference policy:
<meta http-equiv="Content-Security-Policy" content="
default-src 'self';
script-src 'self';
style-src 'self' 'unsafe-inline';
img-src 'self' data: blob:;
font-src 'self';
connect-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self';
">
Audit Points:
default-src 'self' - Restrictive defaultunsafe-inline for scripts (if possible)object-src 'none' - Blocks pluginsframe-src limited to trusted sourcesWhen Adding New Services:
Stripe → add https://js.stripe.com to script-src
Analytics → add domain to connect-src
Fonts → add to font-src
Embeds → add to frame-src
Look for: Headers in deployment config (e.g., vercel.json, netlify.toml, nginx config, middleware).
Required headers:
{
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "X-Frame-Options", "value": "DENY" },
{ "key": "X-XSS-Protection", "value": "1; mode=block" },
{ "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
{ "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=()" },
{
"key": "Strict-Transport-Security",
"value": "max-age=31536000; includeSubDomains"
}
]
}
]
}
Audit Points:
Applies to: Projects using Supabase or similar row-level security.
Required Policies Per Table:
-- Enable RLS
ALTER TABLE table_name ENABLE ROW LEVEL SECURITY;
-- SELECT: Users see own data
CREATE POLICY "Users can view own data"
ON table_name FOR SELECT
USING (auth.uid() = owner_id);
-- INSERT: Users create own data
CREATE POLICY "Users can insert own data"
ON table_name FOR INSERT
WITH CHECK (auth.uid() = owner_id);
-- UPDATE: Users modify own data
CREATE POLICY "Users can update own data"
ON table_name FOR UPDATE
USING (auth.uid() = owner_id);
-- DELETE: Users delete own data
CREATE POLICY "Users can delete own data"
ON table_name FOR DELETE
USING (auth.uid() = owner_id);
Audit Points:
auth.uid() correctlyUSING (true) on sensitive tablesLook for: Sanitization utilities in the project.
Reference implementation:
import DOMPurify from 'dompurify';
export function sanitizeHtml(dirty) {
return DOMPurify.sanitize(dirty, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'p', 'br'],
ALLOWED_ATTR: [],
});
}
export function sanitizeText(input) {
if (typeof input !== 'string') return '';
return input
.replace(/[<>]/g, '') // Remove angle brackets
.trim()
.slice(0, 10000); // Length limit
}
Audit Points:
dangerouslySetInnerHTML without sanitizationAudit Points:
// Secure session handling pattern
const { data: { session } } = await supabase.auth.getSession();
if (!session) {
// Redirect to login
}
// Secure logout
await supabase.auth.signOut();
Environment Variables Audit:
# PUBLIC (OK to expose in frontend — framework-prefixed)
VITE_SUPABASE_URL=https://xxx.supabase.co
VITE_SUPABASE_ANON_KEY=eyJ... # Limited permissions via RLS
NEXT_PUBLIC_SENTRY_DSN=https://...
# SECRET (Never expose in frontend)
SUPABASE_SERVICE_ROLE_KEY=eyJ... # Full database access
STRIPE_SECRET_KEY=sk_...
DATABASE_URL=postgres://...
Audit Points:
.env files in .gitignoreVITE_, NEXT_PUBLIC_) only on public variablesCommands:
# Check for vulnerabilities
npm audit --production
# Auto-fix where possible
npm audit fix --production
# Check for outdated packages
npm outdated
Audit Points:
package-lock.json)Reference:
const corsHeaders = {
"Access-Control-Allow-Origin": "https://yourdomain.com", // Not "*" in production
"Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type",
"Access-Control-Allow-Methods": "POST, OPTIONS",
};
Audit Points:
* origin in productionSignature Verification:
// Always verify webhook signatures
const signature = req.headers.get("stripe-signature");
const event = stripe.webhooks.constructEvent(body, signature, webhookSecret);
Idempotency:
// Prevent duplicate processing
const { data: existing } = await db
.from("webhook_events")
.select("id")
.eq("event_id", event.id)
.single();
if (existing) {
return new Response("Already processed", { status: 200 });
}
Audit Points:
Audit Points:
# Security Audit Report
Date: YYYY-MM-DD
Auditor: [Name]
## Summary
- Critical Issues: X
- High Issues: X
- Medium Issues: X
- Low Issues: X
## Critical Findings
1. [Issue description]
- Location: [file:line]
- Risk: [description]
- Remediation: [steps]
## Recommendations
1. [Recommendation]
## Checklist Results
- [x] CSP configured
- [x] Security headers set
- [ ] RLS audit pending
- [x] Input sanitization in place
...
Add to package.json:
{
"scripts": {
"security:check": "npm audit --production --audit-level=high && npm outdated",
"precommit:security": "npm audit --production --audit-level=critical"
}
}
testing
Craft stunning macOS desktop experiences with SwiftUI — cinematic animations, particle systems, glass materials, and wallpaper-grade visual design. Use like `/apple-craftsman A minimalist weather widget with aurora particle effects`.
development
Use when you have a spec or requirements for a multi-step task, before touching code
development
Use when testing a web application for security vulnerabilities, before deployment or during security review — guides through a structured 10-phase penetration testing methodology covering mapping, authentication, session management, access controls, injection, logic flaws, and server configuration.
data-ai
Engineer system prompts for LiveKit voice agents with multilingual support. Use when creating or optimizing AI agent conversation flows.