security-auth

Security & Authentication Skill

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "security-auth" with this command: npx skills add tuckerandrew21/eft-tracker/tuckerandrew21-eft-tracker-security-auth

Security & Authentication Skill

Model Selection

Security-critical code requires Sonnet (not Haiku) due to:

  • High risk of vulnerabilities

  • Complex attack vectors

  • Need for thorough validation

NextAuth Configuration

Session Configuration

// Secure session settings export const authOptions: NextAuthOptions = { session: { strategy: "jwt", maxAge: 30 * 24 * 60 * 60, // 30 days }, cookies: { sessionToken: { name: __Secure-next-auth.session-token, options: { httpOnly: true, sameSite: "lax", path: "/", secure: true, // HTTPS only in production }, }, }, };

Protected Routes

// Server-side protection import { getServerSession } from "next-auth";

export async function GET(request: Request) { const session = await getServerSession(authOptions); if (!session) { return Response.json({ error: "Unauthorized" }, { status: 401 }); } // ... protected logic }

Password Security

Hashing

Always use bcrypt with sufficient rounds:

import bcrypt from "bcrypt";

const SALT_ROUNDS = 12; // Minimum 10, 12 recommended

// Hash password const hashedPassword = await bcrypt.hash(plainPassword, SALT_ROUNDS);

// Verify password const isValid = await bcrypt.compare(plainPassword, hashedPassword);

Password Reset Flow

  • User requests reset (email)

  • Generate secure token (crypto.randomBytes(32) )

  • Store hashed token with expiration (1 hour max)

  • Send reset link via email

  • Validate token on reset page

  • Hash new password, invalidate token

Critical:

  • Never log tokens

  • Rate limit reset requests

  • Invalidate all sessions on password change

OWASP Top 10 Checklist

  1. Injection
  • Use parameterized queries (Prisma handles this)

  • Validate all user input with Zod

  • Never concatenate SQL strings

  1. Broken Authentication
  • Strong password requirements

  • Rate limit login attempts

  • Secure session management

  • Password hashing (bcrypt 12+ rounds)

  1. Sensitive Data Exposure
  • HTTPS everywhere

  • Encrypt sensitive data at rest

  • No secrets in code/logs

  • Secure cookie flags

  1. XXE (XML External Entities)
  • Disable XML external entity processing

  • Use JSON instead of XML where possible

  1. Broken Access Control
  • Verify authorization on every request

  • Deny by default

  • Log access control failures

  1. Security Misconfiguration
  • Remove default credentials

  • Disable unnecessary features

  • Keep dependencies updated

  1. XSS (Cross-Site Scripting)
  • Never use dangerouslySetInnerHTML

  • Escape user output

  • Content Security Policy headers

  1. Insecure Deserialization
  • Validate serialized data

  • Use type-safe serialization

  1. Using Components with Known Vulnerabilities
  • Run npm audit regularly

  • Update dependencies

  • Monitor security advisories

  1. Insufficient Logging & Monitoring
  • Log security events

  • Monitor for anomalies

  • Alerting on suspicious activity

Rate Limiting

API Route Rate Limiting

import { Ratelimit } from "@upstash/ratelimit"; import { Redis } from "@upstash/redis";

const ratelimit = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.slidingWindow(10, "10 s"), });

export async function POST(request: Request) { const ip = request.headers.get("x-forwarded-for") ?? "127.0.0.1"; const { success } = await ratelimit.limit(ip);

if (!success) { return Response.json({ error: "Too many requests" }, { status: 429 }); } // ... handle request }

Sensitive Endpoint Limits

Endpoint Limit Window

Login 5 attempts 15 min

Password reset 3 requests 1 hour

API general 100 requests 1 min

Registration 3 accounts 1 hour

Input Validation

Always validate with Zod:

import { z } from "zod";

const loginSchema = z.object({ email: z.string().email(), password: z.string().min(8).max(128), });

const resetSchema = z.object({ email: z.string().email(), });

const newPasswordSchema = z.object({ token: z.string().min(32), password: z .string() .min(8) .max(128) .regex(/[A-Z]/, "Must contain uppercase") .regex(/[a-z]/, "Must contain lowercase") .regex(/[0-9]/, "Must contain number"), });

Security Headers

// next.config.ts const securityHeaders = [ { key: "X-DNS-Prefetch-Control", value: "on", }, { key: "Strict-Transport-Security", value: "max-age=63072000; includeSubDomains; preload", }, { key: "X-Frame-Options", value: "SAMEORIGIN", }, { key: "X-Content-Type-Options", value: "nosniff", }, { key: "Referrer-Policy", value: "origin-when-cross-origin", }, ];

Security Review Checklist

Before PR

  • No hardcoded secrets

  • All inputs validated

  • Authorization checks in place

  • Sensitive operations rate limited

  • Error messages don't leak info

  • Logs don't contain sensitive data

Critical Code Patterns

Never do:

// BAD - Hardcoded secret const API_KEY = "sk-1234567890";

// BAD - SQL injection risk const query = SELECT * FROM users WHERE id = ${userId};

// BAD - XSS risk return <div dangerouslySetInnerHTML={{ __html: userInput }} />;

// BAD - Timing attack vulnerability if (token === storedToken) { /* ... */ }

Always do:

// GOOD - Environment variable const API_KEY = process.env.API_KEY;

// GOOD - Parameterized (Prisma) const user = await prisma.user.findUnique({ where: { id: userId } });

// GOOD - Escaped output return <div>{userInput}</div>;

// GOOD - Constant-time comparison import { timingSafeEqual } from "crypto"; if (timingSafeEqual(Buffer.from(token), Buffer.from(storedToken))) { /* ... */ }

Environment Variables

Required for auth:

  • NEXTAUTH_SECRET

  • Random 32+ char string

  • NEXTAUTH_URL

  • Full URL of app

  • RESEND_API_KEY

  • For password reset emails

Never commit:

  • .env files with real values

  • API keys or tokens

  • Database credentials

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

frontend-design

No summary provided by upstream source.

Repository SourceNeeds Review
General

database-prisma

No summary provided by upstream source.

Repository SourceNeeds Review
General

testing-strategy

No summary provided by upstream source.

Repository SourceNeeds Review