Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
aiskillstore avatar

Security Best Practices

  • 1 installs
  • 404 repo stars
  • Updated August 5, 2026
  • aiskillstore/marketplace

security-best-practices is a skill for hardening web apps and APIs against OWASP Top 10 risks using Express.js patterns.

About

security-best-practices is a skill for implementing web application and infrastructure security. It provides Express.js patterns for HTTPS enforcement, security headers, rate limiting, input validation, SQL injection and XSS prevention, CSRF tokens, secrets management, and JWT with refresh-token rotation. A developer uses it when securing APIs or hardening a public-facing service.

  • HTTPS, security headers, and rate limiting with Helmet
  • Input validation, SQL injection, XSS, and CSRF prevention
  • Secrets management and JWT refresh-token rotation

Security Best Practices by the numbers

  • 1 all-time installs (skills.sh)
  • Ranked #1,834 of 2,203 Security skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
At a glance

security-best-practices capabilities & compatibility

Capabilities
security audit · api hardening · input validation · secrets management
Works with
stripe · kubernetes
Use cases
security audit · api development
Pricing
Free
From the docs

What security-best-practices says it does

Handles HTTPS, CORS, XSS, SQL Injection, CSRF, rate limiting, and OWASP Top 10.
SKILL.md
max: 5, // only 5 times per 15 minutes
SKILL.md
npx skills add https://github.com/aiskillstore/marketplace --skill security-best-practices

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs1
repo stars404
Last updatedAugust 5, 2026
Repositoryaiskillstore/marketplace

What it does

Harden a web API with security headers, input validation, CSRF, and secure JWT auth.

Who is it for?

Securing public APIs with headers, validation, CSRF protection, secrets management, and JWT rotation

Skip if: Non-web infrastructure or language-agnostic-only guidance

When should I use this skill?

Securing APIs, preventing common vulnerabilities, or implementing security policies

What you get

A hardened API with enforced HTTPS, validated input, CSRF protection, and rotated tokens.

  • Security middleware
  • Validation schemas
  • CSRF setup

By the numbers

  • Auth login capped at 5 requests per 15 minutes

Files

SKILL.mdMarkdownGitHub ↗

Security Best Practices

When to use this skill

  • New project: consider security from the start
  • Security audit: inspect and fix vulnerabilities
  • Public API: harden APIs accessible externally
  • Compliance: comply with GDPR, PCI-DSS, etc.

Instructions

Step 1: Enforce HTTPS and security headers

Express.js security middleware:

import express from 'express';
import helmet from 'helmet';
import rateLimit from 'express-rate-limit';

const app = express();

// Helmet: automatically set security headers
app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", "'unsafe-inline'", "https://trusted-cdn.com"],
      styleSrc: ["'self'", "'unsafe-inline'"],
      imgSrc: ["'self'", "data:", "https:"],
      connectSrc: ["'self'", "https://api.example.com"],
      fontSrc: ["'self'", "https:", "data:"],
      objectSrc: ["'none'"],
      mediaSrc: ["'self'"],
      frameSrc: ["'none'"],
    },
  },
  hsts: {
    maxAge: 31536000,
    includeSubDomains: true,
    preload: true
  }
}));

// Enforce HTTPS
app.use((req, res, next) => {
  if (process.env.NODE_ENV === 'production' && !req.secure) {
    return res.redirect(301, `https://${req.headers.host}${req.url}`);
  }
  next();
});

// Rate limiting (DDoS prevention)
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // max 100 requests per IP
  message: 'Too many requests from this IP, please try again later.',
  standardHeaders: true,
  legacyHeaders: false,
});

app.use('/api/', limiter);

// Stricter for auth endpoints
const authLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 5, // only 5 times per 15 minutes
  skipSuccessfulRequests: true // do not count successful requests
});

app.use('/api/auth/login', authLimiter);

Step 2: Input validation (SQL Injection, XSS prevention)

Joi validation:

import Joi from 'joi';

const userSchema = Joi.object({
  email: Joi.string().email().required(),
  password: Joi.string().min(8).pattern(/^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]/).required(),
  name: Joi.string().min(2).max(50).required()
});

app.post('/api/users', async (req, res) => {
  // 1. Validate input
  const { error, value } = userSchema.validate(req.body);

  if (error) {
    return res.status(400).json({ error: error.details[0].message });
  }

  // 2. Prevent SQL Injection: Parameterized Queries
  // ❌ Bad example
  // db.query(`SELECT * FROM users WHERE email = '${email}'`);

  // ✅ Good example
  const user = await db.query('SELECT * FROM users WHERE email = ?', [value.email]);

  // 3. Prevent XSS: Output Encoding
  // React/Vue escape automatically; otherwise use a library
  import DOMPurify from 'isomorphic-dompurify';
  const sanitized = DOMPurify.sanitize(userInput);

  res.json({ user: sanitized });
});

Step 3: Prevent CSRF

CSRF Token:

import csrf from 'csurf';
import cookieParser from 'cookie-parser';

app.use(cookieParser());

// CSRF protection
const csrfProtection = csrf({ cookie: true });

// Provide CSRF token
app.get('/api/csrf-token', csrfProtection, (req, res) => {
  res.json({ csrfToken: req.csrfToken() });
});

// Validate CSRF on all POST/PUT/DELETE requests
app.post('/api/*', csrfProtection, (req, res, next) => {
  next();
});

// Use on the client
// fetch('/api/users', {
//   method: 'POST',
//   headers: {
//     'CSRF-Token': csrfToken
//   },
//   body: JSON.stringify(data)
// });

Step 4: Manage secrets

.env (never commit):

# Database
DATABASE_URL=postgresql://user:password@localhost:5432/mydb

# JWT
ACCESS_TOKEN_SECRET=your-super-secret-access-token-key-min-32-chars
REFRESH_TOKEN_SECRET=your-super-secret-refresh-token-key-min-32-chars

# API Keys
STRIPE_SECRET_KEY=sk_test_xxx
SENDGRID_API_KEY=SG.xxx

Kubernetes Secrets:

apiVersion: v1
kind: Secret
metadata:
  name: myapp-secrets
type: Opaque
stringData:
  database-url: postgresql://user:password@postgres:5432/mydb
  jwt-secret: your-jwt-secret
// Read from environment variables
const dbUrl = process.env.DATABASE_URL;
if (!dbUrl) {
  throw new Error('DATABASE_URL environment variable is required');
}

Step 5: Secure API authentication

JWT + Refresh Token Rotation:

// Short-lived access token (15 minutes)
const accessToken = jwt.sign({ userId }, ACCESS_SECRET, { expiresIn: '15m' });

// Long-lived refresh token (7 days), store in DB
const refreshToken = jwt.sign({ userId }, REFRESH_SECRET, { expiresIn: '7d' });
await db.refreshToken.create({
  userId,
  token: refreshToken,
  expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)
});

// Refresh token rotation: re-issue on each use
app.post('/api/auth/refresh', async (req, res) => {
  const { refreshToken } = req.body;

  const payload = jwt.verify(refreshToken, REFRESH_SECRET);

  // Invalidate existing token
  await db.refreshToken.delete({ where: { token: refreshToken } });

  // Issue new tokens
  const newAccessToken = jwt.sign({ userId: payload.userId }, ACCESS_SECRET, { expiresIn: '15m' });
  const newRefreshToken = jwt.sign({ userId: payload.userId }, REFRESH_SECRET, { expiresIn: '7d' });

  await db.refreshToken.create({
    userId: payload.userId,
    token: newRefreshToken,
    expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)
  });

  res.json({ accessToken: newAccessToken, refreshToken: newRefreshToken });
});

Constraints

Required rules (MUST)

1. HTTPS Only: HTTPS required in production 2. Separate secrets: manage via environment variables; never hardcode in code 3. Input Validation: validate all user input 4. Parameterized Queries: prevent SQL Injection 5. Rate Limiting: DDoS prevention

Prohibited items (MUST NOT)

1. No eval(): code injection risk 2. No direct innerHTML: XSS risk 3. No committing secrets: never commit .env files

OWASP Top 10 checklist

- [ ] A01: Broken Access Control - RBAC, authorization checks
- [ ] A02: Cryptographic Failures - HTTPS, encryption
- [ ] A03: Injection - Parameterized Queries, Input Validation
- [ ] A04: Insecure Design - Security by Design
- [ ] A05: Security Misconfiguration - Helmet, change default passwords
- [ ] A06: Vulnerable Components - npm audit, regular updates
- [ ] A07: Authentication Failures - strong auth, MFA
- [ ] A08: Data Integrity Failures - signature validation, CSRF prevention
- [ ] A09: Logging Failures - security event logging
- [ ] A10: SSRF - validate outbound requests

Best practices

1. Principle of Least Privilege: grant minimal privileges 2. Defense in Depth: layered security 3. Security Audits: regular security reviews

References

Metadata

Version

  • Current version: 1.0.0
  • Last updated: 2025-01-01
  • Compatible platforms: Claude, ChatGPT, Gemini

Related skills

  • authentication-setup
  • deployment

Tags

#security #OWASP #HTTPS #CORS #XSS #SQL-injection #CSRF #infrastructure

Examples

Example 1: Basic usage

<!-- Add example content here -->

Example 2: Advanced usage

<!-- Add advanced example content here -->

Related skills

FAQ

How are auth endpoints rate-limited?

A stricter limiter caps login to 5 requests per 15 minutes and skips successful requests.

How should secrets be handled?

Store them in .env or Kubernetes Secrets, never commit them, and read them from environment variables.

Securityappsecsecrets

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.