skills/doanchienthangdev/omgkit/Applying OWASP Security

Applying OWASP Security

SKILL.md

Applying OWASP Security

Quick Start

// lib/security/validation.ts
import { z } from "zod";
import DOMPurify from "isomorphic-dompurify";

// Input validation
export const userSchema = z.object({
  email: z.string().email().max(254),
  password: z.string().min(12).max(128),
  name: z.string().min(2).max(100).regex(/^[\p{L}\s'-]+$/u),
});

// HTML sanitization
export const sanitizeHtml = (dirty: string) =>
  DOMPurify.sanitize(dirty, { ALLOWED_TAGS: ["b", "i", "em", "strong", "a", "p"] });

Features

Feature Description Reference
Injection Prevention SQL, NoSQL, command injection protection OWASP Injection
XSS Prevention Output encoding and HTML sanitization OWASP XSS
CSRF Protection Token-based cross-site request forgery defense OWASP CSRF
Authentication Security Password hashing, rate limiting, session management OWASP Auth
Security Headers CSP, HSTS, X-Frame-Options configuration OWASP Headers
Input Validation Schema validation and sanitization OWASP Validation

Common Patterns

Parameterized Queries (SQL Injection Prevention)

// BAD - SQL injection vulnerable
const result = await db.$queryRawUnsafe(`SELECT * FROM users WHERE id = '${userId}'`);

// GOOD - Parameterized query
const result = await db.user.findUnique({ where: { id: userId } });
const result = await db.$queryRaw`SELECT * FROM users WHERE id = ${userId}`;

CSRF Protection Middleware

import crypto from "crypto";

export function csrfProtection(req: Request, res: Response, next: NextFunction) {
  if (["GET", "HEAD", "OPTIONS"].includes(req.method)) return next();

  const cookieToken = req.cookies["csrf_token"];
  const headerToken = req.headers["x-csrf-token"];

  if (!cookieToken || !headerToken || cookieToken !== headerToken) {
    return res.status(403).json({ error: "CSRF validation failed" });
  }
  next();
}

Security Headers Configuration

import helmet from "helmet";

app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", "'strict-dynamic'"],
      styleSrc: ["'self'", "'unsafe-inline'"],
      imgSrc: ["'self'", "data:", "https:"],
      frameSrc: ["'none'"],
      objectSrc: ["'none'"],
    },
  },
  strictTransportSecurity: { maxAge: 31536000, includeSubDomains: true, preload: true },
  frameguard: { action: "deny" },
}));

Password Security

import bcrypt from "bcrypt";

const SALT_ROUNDS = 12;

export async function hashPassword(password: string): Promise<string> {
  return bcrypt.hash(password, SALT_ROUNDS);
}

export async function verifyPassword(password: string, hash: string): Promise<boolean> {
  return bcrypt.compare(password, hash);
}

export function validatePasswordStrength(password: string): string[] {
  const errors: string[] = [];
  if (password.length < 12) errors.push("Must be at least 12 characters");
  if (!/[a-z]/.test(password)) errors.push("Must contain lowercase");
  if (!/[A-Z]/.test(password)) errors.push("Must contain uppercase");
  if (!/\d/.test(password)) errors.push("Must contain digit");
  if (!/[!@#$%^&*]/.test(password)) errors.push("Must contain special character");
  return errors;
}

Best Practices

Do Avoid
Validate all input on the server side Trusting client-side validation alone
Use parameterized queries for all DB access String concatenation in queries
Set security headers on all responses Disabling security features for convenience
Implement rate limiting on sensitive endpoints Allowing unlimited attempts
Hash passwords with bcrypt (12+ rounds) Using weak/deprecated crypto algorithms
Log security events for monitoring Exposing detailed error messages to users
Keep dependencies updated Ignoring security warnings
Use HTTPS for all communications Hardcoding secrets in source code

References

Weekly Installs
0
GitHub Stars
3
First Seen
Jan 1, 1970