security-checklist

SKILL开发
开发 未标注权限 许可证不明确

Comprehensive security checklist covering OWASP Top 10, SQL injection, XSS, CSRF, authentication, authorization, secrets management, input validation, and security headers. Use when scanning for vulnerabilities, reviewing security, implementing authentication/authorization, or handling sensitive data.

一句话选型结论

按资料字段整理

security-checklist是开发类的 Agent Skill,安装方式:GitHub 仓库,权限级别未标注,许可证不明确,没有现成安装命令,需按说明手动放置 SKILL.md。技能本质是给模型读的说明书,效果取决于模型与客户端;装完先用一个小任务验证,再放进正式流程。

分类开发 安装方式GitHub 仓库 权限级别未标注权限 许可证许可证不明确
累计安装 未标注 本周 未标注
GitHub 星标 6 仓库 titanium-plugins
下载量 未标注 技能市场下载数
权限级别 未标注权限 安装前请确认风险范围
许可证 许可证不明确 未说明

安装

GitHub 仓库
在支持 Skills 的客户端里执行,装完问一句「你有哪些技能」验证
  1. 1
    确认客户端支持

    确认你的客户端支持 Skills(Claude、Codex、Cursor 等),并升级到较新的版本。

  2. 2
    拿到技能文件

    按安装说明或仓库 README,把 SKILL.md 放到客户端的 skills 目录(一般一个技能一个文件夹)。

  3. 3
    刷新技能列表

    重新打开客户端,或刷新技能列表,让新放进来的技能被加载。

  4. 4
    验证是否生效

    问一句「你有哪些技能」,确认列表里出现它,再拿一个小任务试跑。

技能档案

开发
字段来自技能仓库与公开索引,中文说明由本站标注
作者 / 维护方webdevtodayjason仓库 titanium-plugins · 版本 未标注
宿主客户端未标注技能可被这些客户端加载
安装方式GitHub 仓库安装包 webdevtodayjason/titanium-plugins
权限级别未标注权限安装前请确认风险范围
许可证未说明许可证不明确,商用前请自行确认条款
仓库可用性available技能仓库当前是否可访问
最近核验未标注上游最后核验时间 · 数据更新 未标注
正文体量23.8 KBSKILL.md 原文大小,越大说明说明书写得越细

典型使用场景

3 类
按分类整理的常见用法,具体以 SKILL.md 为准
写代码与改 bug

按需求补代码、定位并修掉报错。

读仓库与生成改动

让模型读懂项目结构,再给出可落地的改动。

跑测试与排查故障

按现象排查问题,补测试用例并复跑。

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 基础信息齐全,可以先按说明装一个试试。

先想清楚的地方

  • 没有标注权限级别,实际能做什么要装好后确认。
  • 许可证不明确,商用或二次分发前先到仓库确认条款。
  • 没有现成安装命令,要按安装说明或仓库 README 手动放置。
  • 没有做站内核验,内容以作者仓库为准。
  • 技能只是说明书,实际效果取决于模型与客户端,装完先用小任务试一遍。

更适合

  • 需要在开发场景里给模型补一套做法的人。
  • 愿意先读一遍 SKILL.md、确认它会让模型做什么的人。

不太适合

  • 对许可证要求很严、必须明确可商用的人。
  • 只想装完就自动变强、不打算看说明书的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
技能权限级别安装方式累计安装宿主客户端安装命令
security-checklist当前 未标注权限 GitHub 仓库 未标注 未标注 无
技能审查员 浏览器控制 ClawHub 市场 877.9 万 OpenClaw 有
Vercel React 最佳实践 浏览器控制 GitHub 仓库 849.1 万 Codex、Claude、Cursor 有
GitHub 代码协作 联网访问 ClawHub 市场 763.3 万 OpenClaw 有
网页设计指南 联网访问 GitHub 仓库 668.6 万 Codex、Claude、Cursor 有
本体论 只读 ClawHub 市场 663.7 万 OpenClaw 有

SKILL.md 全文

23.8 KB
模型实际读到的说明书原文,来自技能仓库

Security Checklist

This skill provides comprehensive security guidance to protect your applications from common vulnerabilities and attacks.

OWASP Top 10 Vulnerabilities

1. Broken Access Control

What it is: Users can access resources or perform actions they shouldn't be authorized for.

Examples:
- Accessing another user's data by changing URL parameter
- Elevating privileges (user → admin)
- Bypassing authentication checks

Prevention:

// ❌ BAD - No authorization check
app.get('/api/users/:id', async (req, res) => {
  const user = await db.user.findUnique({ where: { id: req.params.id } });
  res.json(user);
});

// ✅ GOOD - Verify ownership or admin
app.get('/api/users/:id', authenticate, async (req, res) => {
  const requestedId = req.params.id;
  const currentUserId = req.user.id;
  const isAdmin = req.user.role === 'admin';

  if (requestedId !== currentUserId && !isAdmin) {
    return res.status(403).json({ error: 'Forbidden' });
  }

  const user = await db.user.findUnique({ where: { id: requestedId } });
  res.json(user);
});

Checklist:
- [ ] Enforce least privilege (deny by default)
- [ ] Verify user permissions on every request
- [ ] Never trust user IDs from client
- [ ] Log access control failures
- [ ] Use centralized access control logic

2. Cryptographic Failures

What it is: Exposing sensitive data due to weak or missing encryption.

Examples:
- Storing passwords in plain text
- Using weak hashing algorithms (MD5, SHA1)
- Transmitting sensitive data over HTTP

Prevention:

import bcrypt from 'bcrypt';
import crypto from 'crypto';

// ✅ Password hashing
async function hashPassword(password: string): Promise<string> {
  const saltRounds = 12; // Increase for more security
  return await bcrypt.hash(password, saltRounds);
}

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

// ✅ Encrypt sensitive data at rest
function encrypt(text: string, key: string): string {
  const iv = crypto.randomBytes(16);
  const cipher = crypto.createCipheriv('aes-256-gcm', Buffer.from(key), iv);

  let encrypted = cipher.update(text, 'utf8', 'hex');
  encrypted += cipher.final('hex');

  const authTag = cipher.getAuthTag().toString('hex');
  return `${iv.toString('hex')}:${authTag}:${encrypted}`;
}

Checklist:
- [ ] Use HTTPS everywhere
- [ ] Hash passwords with bcrypt (12+ rounds)
- [ ] Encrypt sensitive data at rest
- [ ] Use strong encryption algorithms (AES-256)
- [ ] Properly manage encryption keys
- [ ] Never commit secrets to version control

3. Injection Attacks

See SQL Injection Prevention section below

4. Insecure Design

What it is: Security flaws in the application architecture.

Examples:
- Missing rate limiting
- Unrestricted file uploads
- Insecure password reset flows

Prevention:

// ✅ Rate limiting
import rateLimit from 'express-rate-limit';

const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 5, // 5 attempts
  message: 'Too many login attempts, please try again later',
});

app.post('/api/auth/login', loginLimiter, async (req, res) => {
  // Login logic
});

// ✅ Secure file upload
import multer from 'multer';

const upload = multer({
  limits: {
    fileSize: 5 * 1024 * 1024, // 5MB max
  },
  fileFilter: (req, file, cb) => {
    const allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
    if (!allowedTypes.includes(file.mimetype)) {
      return cb(new Error('Invalid file type'));
    }
    cb(null, true);
  },
});

Checklist:
- [ ] Implement rate limiting on all endpoints
- [ ] Validate file uploads (type, size, content)
- [ ] Use secure password reset flows (token-based)
- [ ] Implement account lockout after failed attempts
- [ ] Log and monitor security events

5. Security Misconfiguration

What it is: Insecure default configurations, unnecessary features enabled.

Prevention:

// ✅ Secure Express configuration
import express from 'express';
import helmet from 'helmet';

const app = express();

// Security headers
app.use(helmet());

// Disable X-Powered-By
app.disable('x-powered-by');

// Environment-specific settings
if (process.env.NODE_ENV === 'production') {
  app.set('trust proxy', 1); // Trust first proxy
}

// CORS configuration
import cors from 'cors';

const corsOptions = {
  origin: process.env.ALLOWED_ORIGINS?.split(',') || [],
  credentials: true,
  optionsSuccessStatus: 200,
};

app.use(cors(corsOptions));

Checklist:
- [ ] Remove default accounts and passwords
- [ ] Disable directory listing
- [ ] Remove unnecessary features/endpoints
- [ ] Keep all software updated
- [ ] Use security headers (see section below)

6. Vulnerable and Outdated Components

Prevention:

# Check for vulnerabilities
npm audit

# Fix vulnerabilities
npm audit fix

# Update dependencies
npm update

# Use automated tools
npm install -g snyk
snyk test
snyk monitor

Checklist:
- [ ] Regularly update dependencies
- [ ] Monitor security advisories
- [ ] Remove unused dependencies
- [ ] Use dependabot or renovate
- [ ] Pin dependency versions in production

7. Identification and Authentication Failures

See Authentication Best Practices section below

8. Software and Data Integrity Failures

Prevention:

// ✅ Verify package integrity
// package-lock.json ensures same versions

// ✅ Use Subresource Integrity (SRI) for CDN
<script
  src="https://cdn.example.com/library.js"
  integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
  crossorigin="anonymous"
></script>

// ✅ Validate data from external sources
import { z } from 'zod';

const ExternalDataSchema = z.object({
  id: z.string().uuid(),
  amount: z.number().positive(),
  status: z.enum(['pending', 'completed', 'failed']),
});

function processExternalData(data: unknown) {
  const validated = ExternalDataSchema.parse(data);
  // Now safe to use
}

9. Security Logging and Monitoring Failures

Prevention:

import winston from 'winston';

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  transports: [
    new winston.transports.File({ filename: 'error.log', level: 'error' }),
    new winston.transports.File({ filename: 'combined.log' }),
  ],
});

// ✅ Log security events
logger.warn('Failed login attempt', {
  email: req.body.email,
  ip: req.ip,
  userAgent: req.get('user-agent'),
  timestamp: new Date().toISOString(),
});

logger.error('SQL injection attempt detected', {
  query: sanitizedQuery,
  ip: req.ip,
  endpoint: req.path,
});

Checklist:
- [ ] Log authentication events (login, logout, failures)
- [ ] Log authorization failures
- [ ] Log input validation failures
- [ ] Monitor for suspicious patterns
- [ ] Set up alerts for security events

10. Server-Side Request Forgery (SSRF)

Prevention:

import validator from 'validator';

// ❌ BAD - Allows SSRF
app.post('/api/fetch-url', async (req, res) => {
  const url = req.body.url;
  const response = await fetch(url);
  res.json(await response.json());
});

// ✅ GOOD - Validate and whitelist
app.post('/api/fetch-url', async (req, res) => {
  const url = req.body.url;

  // Validate URL format
  if (!validator.isURL(url, { protocols: ['https'] })) {
    return res.status(400).json({ error: 'Invalid URL' });
  }

  // Whitelist allowed domains
  const allowedDomains = ['api.trusted-service.com'];
  const urlObj = new URL(url);

  if (!allowedDomains.includes(urlObj.hostname)) {
    return res.status(403).json({ error: 'Domain not allowed' });
  }

  // Block internal IPs
  const hostname = urlObj.hostname;
  if (
    hostname === 'localhost' ||
    hostname.startsWith('192.168.') ||
    hostname.startsWith('10.') ||
    hostname.startsWith('172.')
  ) {
    return res.status(403).json({ error: 'Internal IPs not allowed' });
  }

  const response = await fetch(url);
  res.json(await response.json());
});

SQL Injection Prevention

Parameterized Queries

// ❌ VULNERABLE - String concatenation
const email = req.body.email;
const query = `SELECT * FROM users WHERE email = '${email}'`;
// Attacker can input: ' OR '1'='1
// Resulting query: SELECT * FROM users WHERE email = '' OR '1'='1'

// ✅ SAFE - Parameterized query
const email = req.body.email;
const query = 'SELECT * FROM users WHERE email = ?';
const user = await db.execute(query, [email]);

// ✅ SAFE - ORM (Prisma)
const user = await prisma.user.findUnique({
  where: { email: req.body.email },
});

Input Validation

import { z } from 'zod';

const UserQuerySchema = z.object({
  email: z.string().email(),
  id: z.string().uuid().optional(),
  name: z.string().max(100).optional(),
});

app.get('/api/users', async (req, res) => {
  try {
    const params = UserQuerySchema.parse(req.query);
    const users = await db.user.findMany({ where: params });
    res.json(users);
  } catch (error) {
    res.status(400).json({ error: 'Invalid query parameters' });
  }
});

XSS (Cross-Site Scripting) Prevention

Types of XSS

1. Stored XSS: Malicious script stored in database
2. Reflected XSS: Malicious script in URL/input reflected back
3. DOM-based XSS: Script manipulates DOM directly

Prevention

// ✅ React automatically escapes by default
function Comment({ text }: { text: string }) {
  return <p>{text}</p>; // Safe - React escapes HTML
}

// ❌ DANGEROUS - dangerouslySetInnerHTML
function Comment({ html }: { html: string }) {
  return <p dangerouslySetInnerHTML={{ __html: html }} />; // UNSAFE
}

// ✅ Sanitize HTML before rendering
import DOMPurify from 'dompurify';

function Comment({ html }: { html: string }) {
  const clean = DOMPurify.sanitize(html, {
    ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a'],
    ALLOWED_ATTR: ['href'],
  });
  return <p dangerouslySetInnerHTML={{ __html: clean }} />;
}

// ✅ Server-side sanitization
import sanitizeHtml from 'sanitize-html';

app.post('/api/comments', async (req, res) => {
  const clean = sanitizeHtml(req.body.content, {
    allowedTags: ['b', 'i', 'em', 'strong', 'a'],
    allowedAttributes: {
      'a': ['href'],
    },
  });

  const comment = await db.comment.create({
    data: { content: clean },
  });

  res.json(comment);
});

Content Security Policy (CSP)

app.use(
  helmet.contentSecurityPolicy({
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", 'https://trusted-cdn.com'],
      styleSrc: ["'self'", "'unsafe-inline'"],
      imgSrc: ["'self'", 'data:', 'https:'],
      connectSrc: ["'self'", 'https://api.example.com'],
      fontSrc: ["'self'", 'https://fonts.gstatic.com'],
      objectSrc: ["'none'"],
      upgradeInsecureRequests: [],
    },
  })
);

CSRF (Cross-Site Request Forgery) Protection

CSRF Token Pattern

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

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

app.use(cookieParser());

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

// Protect state-changing endpoints
app.post('/api/users', csrfProtection, async (req, res) => {
  // Token automatically verified by middleware
  const user = await createUser(req.body);
  res.json(user);
});

SameSite Cookies

// ✅ Set SameSite attribute
res.cookie('sessionId', token, {
  httpOnly: true,
  secure: true, // HTTPS only
  sameSite: 'strict', // or 'lax'
  maxAge: 24 * 60 * 60 * 1000, // 24 hours
});

Authentication Best Practices

Password Requirements

import { z } from 'zod';

const PasswordSchema = z
  .string()
  .min(12, 'Password must be at least 12 characters')
  .regex(/[A-Z]/, 'Password must contain uppercase letter')
  .regex(/[a-z]/, 'Password must contain lowercase letter')
  .regex(/[0-9]/, 'Password must contain number')
  .regex(/[^A-Za-z0-9]/, 'Password must contain special character');

// Check against common passwords
import { isCommonPassword } from 'common-passwords';

function validatePassword(password: string): boolean {
  if (isCommonPassword(password)) {
    throw new Error('Password is too common');
  }
  return true;
}

JWT Best Practices

import jwt from 'jsonwebtoken';

// ✅ Short-lived access tokens
function generateAccessToken(userId: string): string {
  return jwt.sign(
    { userId, type: 'access' },
    process.env.JWT_SECRET!,
    { expiresIn: '15m' } // Short expiry
  );
}

// ✅ Long-lived refresh tokens
function generateRefreshToken(userId: string): string {
  return jwt.sign(
    { userId, type: 'refresh' },
    process.env.JWT_REFRESH_SECRET!,
    { expiresIn: '7d' }
  );
}

// ✅ Verify token
function verifyAccessToken(token: string) {
  try {
    const payload = jwt.verify(token, process.env.JWT_SECRET!);
    if (payload.type !== 'access') {
      throw new Error('Invalid token type');
    }
    return payload;
  } catch (error) {
    throw new Error('Invalid token');
  }
}

// ✅ Blacklist tokens on logout
const tokenBlacklist = new Set<string>();

app.post('/api/auth/logout', authenticate, (req, res) => {
  const token = req.headers.authorization?.split(' ')[1];
  if (token) {
    tokenBlacklist.add(token);
  }
  res.json({ message: 'Logged out' });
});

Multi-Factor Authentication (MFA)

import speakeasy from 'speakeasy';
import QRCode from 'qrcode';

// Generate MFA secret
async function enableMFA(userId: string) {
  const secret = speakeasy.generateSecret({
    name: `MyApp (${user.email})`,
  });

  // Generate QR code
  const qrCode = await QRCode.toDataURL(secret.otpauth_url!);

  // Save secret to database (encrypted)
  await db.user.update({
    where: { id: userId },
    data: { mfaSecret: encrypt(secret.base32) },
  });

  return { secret: secret.base32, qrCode };
}

// Verify MFA token
function verifyMFAToken(secret: string, token: string): boolean {
  return speakeasy.totp.verify({
    secret,
    encoding: 'base32',
    token,
    window: 2, // Allow 2 time steps before/after
  });
}

Authorization Patterns

Role-Based Access Control (RBAC)

enum Role {
  USER = 'user',
  MODERATOR = 'moderator',
  ADMIN = 'admin',
}

const permissions = {
  [Role.USER]: ['read:own', 'write:own'],
  [Role.MODERATOR]: ['read:own', 'write:own', 'read:all', 'delete:others'],
  [Role.ADMIN]: ['*'], // All permissions
};

function authorize(requiredPermission: string) {
  return (req: Request, res: Response, next: NextFunction) => {
    const userRole = req.user.role;
    const userPermissions = permissions[userRole];

    if (!userPermissions.includes('*') && !userPermissions.includes(requiredPermission)) {
      return res.status(403).json({ error: 'Forbidden' });
    }

    next();
  };
}

// Usage
app.delete('/api/posts/:id', authenticate, authorize('delete:others'), async (req, res) => {
  await deletePost(req.params.id);
  res.json({ success: true });
});

Attribute-Based Access Control (ABAC)

interface AccessPolicy {
  subject: { role: string; department?: string };
  resource: { type: string; owner?: string };
  action: string;
  conditions?: Record<string, any>;
}

function checkAccess(
  user: User,
  resource: Resource,
  action: string
): boolean {
  // User can access own resources
  if (resource.ownerId === user.id) {
    return true;
  }

  // Admins can access everything
  if (user.role === 'admin') {
    return true;
  }

  // Department managers can access department resources
  if (
    user.role === 'manager' &&
    user.department === resource.department
  ) {
    return true;
  }

  return false;
}

Secrets Management

Environment Variables

// ✅ .env file (NOT committed to git)
DATABASE_URL=postgresql://user:password@localhost:5432/db
JWT_SECRET=super-secret-key-change-in-production
API_KEY=sk_live_abc123xyz

// ✅ .env.example (committed to git)
DATABASE_URL=
JWT_SECRET=
API_KEY=

// ✅ Load environment variables
import dotenv from 'dotenv';
dotenv.config();

// ✅ Validate required env vars
const requiredEnvVars = ['DATABASE_URL', 'JWT_SECRET', 'API_KEY'];

for (const envVar of requiredEnvVars) {
  if (!process.env[envVar]) {
    throw new Error(`Missing required environment variable: ${envVar}`);
  }
}

Key Vault Integration

// ✅ AWS Secrets Manager
import { SecretsManager } from '@aws-sdk/client-secrets-manager';

async function getSecret(secretName: string): Promise<string> {
  const client = new SecretsManager({ region: 'us-east-1' });
  const response = await client.getSecretValue({ SecretId: secretName });
  return response.SecretString!;
}

// ✅ Azure Key Vault
import { SecretClient } from '@azure/keyvault-secrets';

async function getAzureSecret(secretName: string): Promise<string> {
  const client = new SecretClient(vaultUrl, credential);
  const secret = await client.getSecret(secretName);
  return secret.value!;
}

Input Validation

Validation Schema

import { z } from 'zod';

const CreateUserSchema = z.object({
  email: z.string().email().max(255),
  password: z.string().min(12).max(100),
  name: z.string().min(1).max(100),
  age: z.number().int().min(18).max(120),
  phone: z.string().regex(/^\+?[1-9]\d{1,14}$/).optional(),
  website: z.string().url().optional(),
});

app.post('/api/users', async (req, res) => {
  try {
    const data = CreateUserSchema.parse(req.body);
    const user = await createUser(data);
    res.json(user);
  } catch (error) {
    if (error instanceof z.ZodError) {
      return res.status(400).json({
        error: 'Validation failed',
        details: error.errors,
      });
    }
    throw error;
  }
});

Sanitization

import validator from 'validator';

function sanitizeInput(input: string): string {
  // Trim whitespace
  let clean = input.trim();

  // Escape HTML entities
  clean = validator.escape(clean);

  // Remove null bytes
  clean = clean.replace(/\0/g, '');

  return clean;
}

Security Headers

Comprehensive Header Configuration

import helmet from 'helmet';

app.use(
  helmet({
    // Content Security Policy
    contentSecurityPolicy: {
      directives: {
        defaultSrc: ["'self'"],
        scriptSrc: ["'self'", "'unsafe-inline'"],
        styleSrc: ["'self'", "'unsafe-inline'"],
        imgSrc: ["'self'", 'data:', 'https:'],
      },
    },

    // HTTP Strict Transport Security
    hsts: {
      maxAge: 31536000, // 1 year
      includeSubDomains: true,
      preload: true,
    },

    // X-Frame-Options
    frameguard: {
      action: 'deny', // or 'sameorigin'
    },

    // X-Content-Type-Options
    noSniff: true,

    // X-XSS-Protection
    xssFilter: true,

    // Referrer-Policy
    referrerPolicy: {
      policy: 'strict-origin-when-cross-origin',
    },
  })
);

// Additional custom headers
app.use((req, res, next) => {
  res.setHeader('X-Content-Type-Options', 'nosniff');
  res.setHeader('X-Frame-Options', 'DENY');
  res.setHeader('X-XSS-Protection', '1; mode=block');
  res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload');
  next();
});

Rate Limiting

Endpoint-Specific Rate Limits

import rateLimit from 'express-rate-limit';

// Strict limit for authentication
const authLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 5,
  message: 'Too many authentication attempts',
  standardHeaders: true,
  legacyHeaders: false,
});

// Moderate limit for API endpoints
const apiLimiter = rateLimit({
  windowMs: 1 * 60 * 1000, // 1 minute
  max: 60,
  message: 'Too many requests',
});

// Apply rate limiters
app.post('/api/auth/login', authLimiter, loginHandler);
app.post('/api/auth/register', authLimiter, registerHandler);
app.use('/api', apiLimiter);

Logging Security Events

What NOT to Log

❌ Never log:
- Passwords (plain or hashed)
- Credit card numbers
- Social Security numbers
- API keys/secrets
- Session tokens
- Personally identifiable information (PII) in clear text

// ❌ BAD - Logs sensitive data
logger.info('User login', { email, password });

// ✅ GOOD - Logs non-sensitive data
logger.info('User login attempt', {
  email,
  ip: req.ip,
  userAgent: req.get('user-agent'),
  success: true,
});

Security Event Logging

enum SecurityEvent {
  LOGIN_SUCCESS = 'login_success',
  LOGIN_FAILURE = 'login_failure',
  PASSWORD_RESET = 'password_reset',
  ACCOUNT_LOCKED = 'account_locked',
  PERMISSION_DENIED = 'permission_denied',
  SUSPICIOUS_ACTIVITY = 'suspicious_activity',
}

function logSecurityEvent(
  event: SecurityEvent,
  userId: string | null,
  metadata: Record<string, any>
) {
  logger.warn({
    type: 'security',
    event,
    userId,
    timestamp: new Date().toISOString(),
    ip: metadata.ip,
    userAgent: metadata.userAgent,
    ...metadata,
  });
}

Dependency Scanning

Automated Security Scanning

# .github/workflows/security.yml
name: Security Scan

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:
    - cron: '0 0 * * 0' # Weekly

jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Run npm audit
        run: npm audit --audit-level=high

      - name: Run Snyk security scan
        uses: snyk/actions/node@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

      - name: Run Trivy vulnerability scanner
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: 'fs'
          scan-ref: '.'

Security Checklist Summary

Pre-Deployment Checklist

Authentication & Authorization:
- [ ] Passwords hashed with bcrypt (12+ rounds)
- [ ] JWT tokens have short expiry (15 minutes)
- [ ] Refresh tokens properly implemented
- [ ] MFA available for sensitive accounts
- [ ] Authorization checks on all endpoints
- [ ] Rate limiting on auth endpoints

Input Validation:
- [ ] All inputs validated with schemas
- [ ] SQL queries use parameterized statements
- [ ] File uploads restricted (type, size)
- [ ] HTML content sanitized
- [ ] No eval() or Function() with user input

Security Headers:
- [ ] HTTPS enforced
- [ ] CSP configured
- [ ] HSTS enabled
- [ ] X-Frame-Options set
- [ ] X-Content-Type-Options set

Data Protection:
- [ ] Sensitive data encrypted at rest
- [ ] Secrets stored in environment variables/vault
- [ ] No secrets in version control
- [ ] PII handled according to regulations
- [ ] Database backups encrypted

Logging & Monitoring:
- [ ] Security events logged
- [ ] No sensitive data in logs
- [ ] Failed auth attempts monitored
- [ ] Unusual activity alerts configured
- [ ] Log retention policy defined

Dependencies:
- [ ] All dependencies up to date
- [ ] No known vulnerabilities (npm audit)
- [ ] Dependabot/Renovate configured
- [ ] Unused dependencies removed

API Security:
- [ ] CORS properly configured
- [ ] CSRF protection enabled
- [ ] Rate limiting implemented
- [ ] API keys rotated regularly
- [ ] Endpoints documented

When to Use This Skill

Use this skill when:
- Conducting security audits
- Implementing authentication/authorization
- Reviewing code for vulnerabilities
- Setting up new projects
- Handling sensitive data
- Responding to security incidents
- Training team on security
- Preparing for compliance audits
- Deploying to production
- Integrating third-party services


Remember: Security is not a one-time task but an ongoing process. Stay informed about new vulnerabilities, keep dependencies updated, and always assume malicious actors are trying to exploit your application.

常见问题

5 问
答案由本站依据条目字段整理
security-checklist怎么安装?

没有现成安装命令:按安装说明或仓库 README,把 SKILL.md 放进客户端的 skills 目录(一般一个技能一个文件夹)。

security-checklist支持哪些客户端?

资料没有标注宿主客户端,但只要客户端支持 Skills(Claude、Codex、Cursor 等),一般都能加载。

security-checklist权限高吗,安全吗?

权限级别为未标注权限。安装前先看它会读取或写入哪些内容。

security-checklist收费吗?

本站不代收费用,也没有标注具体价格。是否收费取决于技能本身和所用的模型或客户端,正式使用前按作者说明确认。

security-checklist用什么许可证?

许可证标注为 未说明(许可证不明确)。商用或二次分发前请到仓库确认条款原文。

热门专题

按场景挑技能
全部专题 →

技能内容以作者仓库为准;分类、权限级别与许可证状态的中文说明为中文整理,最近核验 未标注。