{
  "schemaVersion": "1.0",
  "item": {
    "slug": "api-security",
    "name": "API Security Best Practices",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/brandonwise/api-security",
    "canonicalUrl": "https://clawhub.ai/brandonwise/api-security",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/api-security",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=api-security",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-23T16:43:11.935Z",
      "expiresAt": "2026-04-30T16:43:11.935Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
        "contentDisposition": "attachment; filename=\"4claw-imageboard-1.0.1.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/api-security"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/api-security",
    "agentPageUrl": "https://openagent3.xyz/skills/api-security/agent",
    "manifestUrl": "https://openagent3.xyz/skills/api-security/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/api-security/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "API Security Best Practices",
        "body": "Implement secure API design patterns including authentication, authorization, input validation, rate limiting, and protection against common API vulnerabilities."
      },
      {
        "title": "Description",
        "body": "USE WHEN:\n\nDesigning new API endpoints\nSecuring existing APIs\nImplementing authentication and authorization (JWT, OAuth 2.0, API keys)\nSetting up rate limiting and throttling\nProtecting against injection attacks (SQL, XSS, command)\nConducting API security reviews or preparing for audits\nHandling sensitive data in APIs\nBuilding REST, GraphQL, or WebSocket APIs\n\nDON'T USE WHEN:\n\nNeed vulnerability scanning (use vulnerability-scanner skill)\nBuilding frontend-only apps with no API\nNeed network-level security (firewalls, WAF config)\n\nOUTPUTS:\n\nSecure authentication implementations (JWT, refresh tokens)\nInput validation schemas (Zod, Joi)\nRate limiting configurations\nSecurity middleware examples\nOWASP API Top 10 compliance guidance"
      },
      {
        "title": "Step 1: Authentication & Authorization",
        "body": "Choose authentication method (JWT, OAuth 2.0, API keys)\nImplement token-based authentication\nSet up role-based access control (RBAC)\nSecure session management\nImplement multi-factor authentication (MFA)"
      },
      {
        "title": "Step 2: Input Validation & Sanitization",
        "body": "Validate all input data\nSanitize user inputs\nUse parameterized queries\nImplement request schema validation\nPrevent SQL injection, XSS, and command injection"
      },
      {
        "title": "Step 3: Rate Limiting & Throttling",
        "body": "Implement rate limiting per user/IP\nSet up API throttling\nConfigure request quotas\nHandle rate limit errors gracefully\nMonitor for suspicious activity"
      },
      {
        "title": "Step 4: Data Protection",
        "body": "Encrypt data in transit (HTTPS/TLS)\nEncrypt sensitive data at rest\nImplement proper error handling (no data leaks)\nSanitize error messages\nUse secure headers"
      },
      {
        "title": "Generate Secure JWT Tokens",
        "body": "// auth.js\nconst jwt = require('jsonwebtoken');\nconst bcrypt = require('bcrypt');\n\napp.post('/api/auth/login', async (req, res) => {\n  try {\n    const { email, password } = req.body;\n    \n    // Validate input\n    if (!email || !password) {\n      return res.status(400).json({ error: 'Email and password required' });\n    }\n    \n    // Find user\n    const user = await db.user.findUnique({ where: { email } });\n    \n    if (!user) {\n      // Don't reveal if user exists\n      return res.status(401).json({ error: 'Invalid credentials' });\n    }\n    \n    // Verify password\n    const validPassword = await bcrypt.compare(password, user.passwordHash);\n    if (!validPassword) {\n      return res.status(401).json({ error: 'Invalid credentials' });\n    }\n    \n    // Generate JWT token\n    const token = jwt.sign(\n      { userId: user.id, email: user.email, role: user.role },\n      process.env.JWT_SECRET,\n      { expiresIn: '1h', issuer: 'your-app', audience: 'your-app-users' }\n    );\n    \n    // Generate refresh token\n    const refreshToken = jwt.sign(\n      { userId: user.id },\n      process.env.JWT_REFRESH_SECRET,\n      { expiresIn: '7d' }\n    );\n    \n    // Store refresh token in database\n    await db.refreshToken.create({\n      data: {\n        token: refreshToken,\n        userId: user.id,\n        expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)\n      }\n    });\n    \n    res.json({ token, refreshToken, expiresIn: 3600 });\n  } catch (error) {\n    console.error('Login error:', error);\n    res.status(500).json({ error: 'An error occurred during login' });\n  }\n});"
      },
      {
        "title": "JWT Verification Middleware",
        "body": "// middleware/auth.js\nconst jwt = require('jsonwebtoken');\n\nfunction authenticateToken(req, res, next) {\n  const authHeader = req.headers['authorization'];\n  const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN\n  \n  if (!token) {\n    return res.status(401).json({ error: 'Access token required' });\n  }\n  \n  jwt.verify(\n    token, \n    process.env.JWT_SECRET,\n    { issuer: 'your-app', audience: 'your-app-users' },\n    (err, user) => {\n      if (err) {\n        if (err.name === 'TokenExpiredError') {\n          return res.status(401).json({ error: 'Token expired' });\n        }\n        return res.status(403).json({ error: 'Invalid token' });\n      }\n      req.user = user;\n      next();\n    }\n  );\n}\n\nmodule.exports = { authenticateToken };"
      },
      {
        "title": "❌ Vulnerable Code",
        "body": "// NEVER DO THIS - SQL Injection vulnerability\napp.get('/api/users/:id', async (req, res) => {\n  const userId = req.params.id;\n  const query = `SELECT * FROM users WHERE id = '${userId}'`;\n  const user = await db.query(query);\n  res.json(user);\n});\n\n// Attack: GET /api/users/1' OR '1'='1 → Returns all users!"
      },
      {
        "title": "✅ Safe: Parameterized Queries",
        "body": "app.get('/api/users/:id', async (req, res) => {\n  const userId = req.params.id;\n  \n  // Validate input first\n  if (!userId || !/^\\d+$/.test(userId)) {\n    return res.status(400).json({ error: 'Invalid user ID' });\n  }\n  \n  // Use parameterized query\n  const user = await db.query(\n    'SELECT id, email, name FROM users WHERE id = $1',\n    [userId]\n  );\n  \n  if (!user) {\n    return res.status(404).json({ error: 'User not found' });\n  }\n  \n  res.json(user);\n});"
      },
      {
        "title": "✅ Safe: Using ORM (Prisma)",
        "body": "app.get('/api/users/:id', async (req, res) => {\n  const userId = parseInt(req.params.id);\n  \n  if (isNaN(userId)) {\n    return res.status(400).json({ error: 'Invalid user ID' });\n  }\n  \n  const user = await prisma.user.findUnique({\n    where: { id: userId },\n    select: { id: true, email: true, name: true } // Don't select sensitive fields\n  });\n  \n  if (!user) {\n    return res.status(404).json({ error: 'User not found' });\n  }\n  \n  res.json(user);\n});"
      },
      {
        "title": "Schema Validation with Zod",
        "body": "const { z } = require('zod');\n\nconst createUserSchema = z.object({\n  email: z.string().email('Invalid email format'),\n  password: z.string()\n    .min(8, 'Password must be at least 8 characters')\n    .regex(/[A-Z]/, 'Must contain uppercase letter')\n    .regex(/[a-z]/, 'Must contain lowercase letter')\n    .regex(/[0-9]/, 'Must contain number'),\n  name: z.string().min(2).max(100),\n  age: z.number().int().min(18).max(120).optional()\n});\n\nfunction validateRequest(schema) {\n  return (req, res, next) => {\n    try {\n      schema.parse(req.body);\n      next();\n    } catch (error) {\n      res.status(400).json({ error: 'Validation failed', details: error.errors });\n    }\n  };\n}\n\napp.post('/api/users', validateRequest(createUserSchema), async (req, res) => {\n  // Input is validated at this point\n  const { email, password, name, age } = req.body;\n  const passwordHash = await bcrypt.hash(password, 10);\n  const user = await prisma.user.create({ data: { email, passwordHash, name, age } });\n  const { passwordHash: _, ...userWithoutPassword } = user;\n  res.status(201).json(userWithoutPassword);\n});"
      },
      {
        "title": "Rate Limiting",
        "body": "const rateLimit = require('express-rate-limit');\nconst RedisStore = require('rate-limit-redis');\nconst Redis = require('ioredis');\n\nconst redis = new Redis({\n  host: process.env.REDIS_HOST,\n  port: process.env.REDIS_PORT\n});\n\n// General API rate limit\nconst apiLimiter = rateLimit({\n  store: new RedisStore({ client: redis, prefix: 'rl:api:' }),\n  windowMs: 15 * 60 * 1000, // 15 minutes\n  max: 100, // 100 requests per window\n  message: { error: 'Too many requests, please try again later', retryAfter: 900 },\n  standardHeaders: true,\n  legacyHeaders: false,\n  keyGenerator: (req) => req.user?.userId || req.ip\n});\n\n// Strict rate limit for authentication\nconst authLimiter = rateLimit({\n  store: new RedisStore({ client: redis, prefix: 'rl:auth:' }),\n  windowMs: 15 * 60 * 1000,\n  max: 5, // Only 5 login attempts per 15 minutes\n  skipSuccessfulRequests: true,\n  message: { error: 'Too many login attempts, please try again later', retryAfter: 900 }\n});\n\napp.use('/api/', apiLimiter);\napp.use('/api/auth/login', authLimiter);\napp.use('/api/auth/register', authLimiter);"
      },
      {
        "title": "Security Headers (Helmet)",
        "body": "const helmet = require('helmet');\n\napp.use(helmet({\n  contentSecurityPolicy: {\n    directives: {\n      defaultSrc: [\"'self'\"],\n      styleSrc: [\"'self'\", \"'unsafe-inline'\"],\n      scriptSrc: [\"'self'\"],\n      imgSrc: [\"'self'\", 'data:', 'https:']\n    }\n  },\n  frameguard: { action: 'deny' },\n  hidePoweredBy: true,\n  noSniff: true,\n  hsts: { maxAge: 31536000, includeSubDomains: true, preload: true }\n}));"
      },
      {
        "title": "❌ Bad: Only Authentication",
        "body": "app.delete('/api/posts/:id', authenticateToken, async (req, res) => {\n  await prisma.post.delete({ where: { id: req.params.id } });\n  res.json({ success: true });\n});"
      },
      {
        "title": "✅ Good: Authentication + Authorization",
        "body": "app.delete('/api/posts/:id', authenticateToken, async (req, res) => {\n  const post = await prisma.post.findUnique({ where: { id: req.params.id } });\n  \n  if (!post) {\n    return res.status(404).json({ error: 'Post not found' });\n  }\n  \n  // Check if user owns the post or is admin\n  if (post.userId !== req.user.userId && req.user.role !== 'admin') {\n    return res.status(403).json({ error: 'Not authorized to delete this post' });\n  }\n  \n  await prisma.post.delete({ where: { id: req.params.id } });\n  res.json({ success: true });\n});"
      },
      {
        "title": "✅ Do This",
        "body": "Use HTTPS Everywhere - Never send sensitive data over HTTP\nImplement Authentication - Require authentication for protected endpoints\nValidate All Inputs - Never trust user input\nUse Parameterized Queries - Prevent SQL injection\nImplement Rate Limiting - Protect against brute force and DDoS\nHash Passwords - Use bcrypt with salt rounds >= 10\nUse Short-Lived Tokens - JWT access tokens should expire quickly\nImplement CORS Properly - Only allow trusted origins\nLog Security Events - Monitor for suspicious activity\nUse Security Headers - Implement Helmet.js\nSanitize Error Messages - Don't leak sensitive information"
      },
      {
        "title": "❌ Don't Do This",
        "body": "Don't Store Passwords in Plain Text\nDon't Use Weak Secrets - Use strong, random JWT secrets\nDon't Trust User Input - Always validate and sanitize\nDon't Expose Stack Traces - Hide error details in production\nDon't Use String Concatenation for SQL\nDon't Store Sensitive Data in JWT - JWTs are not encrypted\nDon't Ignore Security Updates - Update dependencies regularly\nDon't Log Sensitive Data"
      },
      {
        "title": "OWASP API Security Top 10",
        "body": "Broken Object Level Authorization - Always verify user can access resource\nBroken Authentication - Implement strong authentication mechanisms\nBroken Object Property Level Authorization - Validate which properties user can access\nUnrestricted Resource Consumption - Implement rate limiting and quotas\nBroken Function Level Authorization - Verify user role for each function\nUnrestricted Access to Sensitive Business Flows - Protect critical workflows\nServer Side Request Forgery (SSRF) - Validate and sanitize URLs\nSecurity Misconfiguration - Use security best practices and headers\nImproper Inventory Management - Document and secure all API endpoints\nUnsafe Consumption of APIs - Validate data from third-party APIs"
      },
      {
        "title": "Authentication & Authorization",
        "body": "Implement strong authentication (JWT, OAuth 2.0)\n Use HTTPS for all endpoints\n Hash passwords with bcrypt (salt rounds >= 10)\n Implement token expiration\n Add refresh token mechanism\n Verify user authorization for each request\n Implement role-based access control (RBAC)"
      },
      {
        "title": "Input Validation",
        "body": "Validate all user inputs\n Use parameterized queries or ORM\n Sanitize HTML content\n Validate file uploads\n Implement request schema validation\n Use allowlists, not blocklists"
      },
      {
        "title": "Rate Limiting & DDoS Protection",
        "body": "Implement rate limiting per user/IP\n Add stricter limits for auth endpoints\n Use Redis for distributed rate limiting\n Return proper rate limit headers\n Implement request throttling"
      },
      {
        "title": "Data Protection",
        "body": "Use HTTPS/TLS for all traffic\n Encrypt sensitive data at rest\n Don't store sensitive data in JWT\n Sanitize error messages\n Implement proper CORS configuration\n Use security headers (Helmet.js)"
      },
      {
        "title": "Additional Resources",
        "body": "OWASP API Security Top 10\nJWT Best Practices\nExpress Security Best Practices\nAPI Security Checklist"
      }
    ],
    "body": "API Security Best Practices\n\nImplement secure API design patterns including authentication, authorization, input validation, rate limiting, and protection against common API vulnerabilities.\n\nDescription\n\nUSE WHEN:\n\nDesigning new API endpoints\nSecuring existing APIs\nImplementing authentication and authorization (JWT, OAuth 2.0, API keys)\nSetting up rate limiting and throttling\nProtecting against injection attacks (SQL, XSS, command)\nConducting API security reviews or preparing for audits\nHandling sensitive data in APIs\nBuilding REST, GraphQL, or WebSocket APIs\n\nDON'T USE WHEN:\n\nNeed vulnerability scanning (use vulnerability-scanner skill)\nBuilding frontend-only apps with no API\nNeed network-level security (firewalls, WAF config)\n\nOUTPUTS:\n\nSecure authentication implementations (JWT, refresh tokens)\nInput validation schemas (Zod, Joi)\nRate limiting configurations\nSecurity middleware examples\nOWASP API Top 10 compliance guidance\nHow It Works\nStep 1: Authentication & Authorization\nChoose authentication method (JWT, OAuth 2.0, API keys)\nImplement token-based authentication\nSet up role-based access control (RBAC)\nSecure session management\nImplement multi-factor authentication (MFA)\nStep 2: Input Validation & Sanitization\nValidate all input data\nSanitize user inputs\nUse parameterized queries\nImplement request schema validation\nPrevent SQL injection, XSS, and command injection\nStep 3: Rate Limiting & Throttling\nImplement rate limiting per user/IP\nSet up API throttling\nConfigure request quotas\nHandle rate limit errors gracefully\nMonitor for suspicious activity\nStep 4: Data Protection\nEncrypt data in transit (HTTPS/TLS)\nEncrypt sensitive data at rest\nImplement proper error handling (no data leaks)\nSanitize error messages\nUse secure headers\nJWT Authentication Implementation\nGenerate Secure JWT Tokens\n// auth.js\nconst jwt = require('jsonwebtoken');\nconst bcrypt = require('bcrypt');\n\napp.post('/api/auth/login', async (req, res) => {\n  try {\n    const { email, password } = req.body;\n    \n    // Validate input\n    if (!email || !password) {\n      return res.status(400).json({ error: 'Email and password required' });\n    }\n    \n    // Find user\n    const user = await db.user.findUnique({ where: { email } });\n    \n    if (!user) {\n      // Don't reveal if user exists\n      return res.status(401).json({ error: 'Invalid credentials' });\n    }\n    \n    // Verify password\n    const validPassword = await bcrypt.compare(password, user.passwordHash);\n    if (!validPassword) {\n      return res.status(401).json({ error: 'Invalid credentials' });\n    }\n    \n    // Generate JWT token\n    const token = jwt.sign(\n      { userId: user.id, email: user.email, role: user.role },\n      process.env.JWT_SECRET,\n      { expiresIn: '1h', issuer: 'your-app', audience: 'your-app-users' }\n    );\n    \n    // Generate refresh token\n    const refreshToken = jwt.sign(\n      { userId: user.id },\n      process.env.JWT_REFRESH_SECRET,\n      { expiresIn: '7d' }\n    );\n    \n    // Store refresh token in database\n    await db.refreshToken.create({\n      data: {\n        token: refreshToken,\n        userId: user.id,\n        expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)\n      }\n    });\n    \n    res.json({ token, refreshToken, expiresIn: 3600 });\n  } catch (error) {\n    console.error('Login error:', error);\n    res.status(500).json({ error: 'An error occurred during login' });\n  }\n});\n\nJWT Verification Middleware\n// middleware/auth.js\nconst jwt = require('jsonwebtoken');\n\nfunction authenticateToken(req, res, next) {\n  const authHeader = req.headers['authorization'];\n  const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN\n  \n  if (!token) {\n    return res.status(401).json({ error: 'Access token required' });\n  }\n  \n  jwt.verify(\n    token, \n    process.env.JWT_SECRET,\n    { issuer: 'your-app', audience: 'your-app-users' },\n    (err, user) => {\n      if (err) {\n        if (err.name === 'TokenExpiredError') {\n          return res.status(401).json({ error: 'Token expired' });\n        }\n        return res.status(403).json({ error: 'Invalid token' });\n      }\n      req.user = user;\n      next();\n    }\n  );\n}\n\nmodule.exports = { authenticateToken };\n\nInput Validation (SQL Injection Prevention)\n❌ Vulnerable Code\n// NEVER DO THIS - SQL Injection vulnerability\napp.get('/api/users/:id', async (req, res) => {\n  const userId = req.params.id;\n  const query = `SELECT * FROM users WHERE id = '${userId}'`;\n  const user = await db.query(query);\n  res.json(user);\n});\n\n// Attack: GET /api/users/1' OR '1'='1 → Returns all users!\n\n✅ Safe: Parameterized Queries\napp.get('/api/users/:id', async (req, res) => {\n  const userId = req.params.id;\n  \n  // Validate input first\n  if (!userId || !/^\\d+$/.test(userId)) {\n    return res.status(400).json({ error: 'Invalid user ID' });\n  }\n  \n  // Use parameterized query\n  const user = await db.query(\n    'SELECT id, email, name FROM users WHERE id = $1',\n    [userId]\n  );\n  \n  if (!user) {\n    return res.status(404).json({ error: 'User not found' });\n  }\n  \n  res.json(user);\n});\n\n✅ Safe: Using ORM (Prisma)\napp.get('/api/users/:id', async (req, res) => {\n  const userId = parseInt(req.params.id);\n  \n  if (isNaN(userId)) {\n    return res.status(400).json({ error: 'Invalid user ID' });\n  }\n  \n  const user = await prisma.user.findUnique({\n    where: { id: userId },\n    select: { id: true, email: true, name: true } // Don't select sensitive fields\n  });\n  \n  if (!user) {\n    return res.status(404).json({ error: 'User not found' });\n  }\n  \n  res.json(user);\n});\n\nSchema Validation with Zod\nconst { z } = require('zod');\n\nconst createUserSchema = z.object({\n  email: z.string().email('Invalid email format'),\n  password: z.string()\n    .min(8, 'Password must be at least 8 characters')\n    .regex(/[A-Z]/, 'Must contain uppercase letter')\n    .regex(/[a-z]/, 'Must contain lowercase letter')\n    .regex(/[0-9]/, 'Must contain number'),\n  name: z.string().min(2).max(100),\n  age: z.number().int().min(18).max(120).optional()\n});\n\nfunction validateRequest(schema) {\n  return (req, res, next) => {\n    try {\n      schema.parse(req.body);\n      next();\n    } catch (error) {\n      res.status(400).json({ error: 'Validation failed', details: error.errors });\n    }\n  };\n}\n\napp.post('/api/users', validateRequest(createUserSchema), async (req, res) => {\n  // Input is validated at this point\n  const { email, password, name, age } = req.body;\n  const passwordHash = await bcrypt.hash(password, 10);\n  const user = await prisma.user.create({ data: { email, passwordHash, name, age } });\n  const { passwordHash: _, ...userWithoutPassword } = user;\n  res.status(201).json(userWithoutPassword);\n});\n\nRate Limiting\nconst rateLimit = require('express-rate-limit');\nconst RedisStore = require('rate-limit-redis');\nconst Redis = require('ioredis');\n\nconst redis = new Redis({\n  host: process.env.REDIS_HOST,\n  port: process.env.REDIS_PORT\n});\n\n// General API rate limit\nconst apiLimiter = rateLimit({\n  store: new RedisStore({ client: redis, prefix: 'rl:api:' }),\n  windowMs: 15 * 60 * 1000, // 15 minutes\n  max: 100, // 100 requests per window\n  message: { error: 'Too many requests, please try again later', retryAfter: 900 },\n  standardHeaders: true,\n  legacyHeaders: false,\n  keyGenerator: (req) => req.user?.userId || req.ip\n});\n\n// Strict rate limit for authentication\nconst authLimiter = rateLimit({\n  store: new RedisStore({ client: redis, prefix: 'rl:auth:' }),\n  windowMs: 15 * 60 * 1000,\n  max: 5, // Only 5 login attempts per 15 minutes\n  skipSuccessfulRequests: true,\n  message: { error: 'Too many login attempts, please try again later', retryAfter: 900 }\n});\n\napp.use('/api/', apiLimiter);\napp.use('/api/auth/login', authLimiter);\napp.use('/api/auth/register', authLimiter);\n\nSecurity Headers (Helmet)\nconst helmet = require('helmet');\n\napp.use(helmet({\n  contentSecurityPolicy: {\n    directives: {\n      defaultSrc: [\"'self'\"],\n      styleSrc: [\"'self'\", \"'unsafe-inline'\"],\n      scriptSrc: [\"'self'\"],\n      imgSrc: [\"'self'\", 'data:', 'https:']\n    }\n  },\n  frameguard: { action: 'deny' },\n  hidePoweredBy: true,\n  noSniff: true,\n  hsts: { maxAge: 31536000, includeSubDomains: true, preload: true }\n}));\n\nAuthorization Checks\n❌ Bad: Only Authentication\napp.delete('/api/posts/:id', authenticateToken, async (req, res) => {\n  await prisma.post.delete({ where: { id: req.params.id } });\n  res.json({ success: true });\n});\n\n✅ Good: Authentication + Authorization\napp.delete('/api/posts/:id', authenticateToken, async (req, res) => {\n  const post = await prisma.post.findUnique({ where: { id: req.params.id } });\n  \n  if (!post) {\n    return res.status(404).json({ error: 'Post not found' });\n  }\n  \n  // Check if user owns the post or is admin\n  if (post.userId !== req.user.userId && req.user.role !== 'admin') {\n    return res.status(403).json({ error: 'Not authorized to delete this post' });\n  }\n  \n  await prisma.post.delete({ where: { id: req.params.id } });\n  res.json({ success: true });\n});\n\nBest Practices\n✅ Do This\nUse HTTPS Everywhere - Never send sensitive data over HTTP\nImplement Authentication - Require authentication for protected endpoints\nValidate All Inputs - Never trust user input\nUse Parameterized Queries - Prevent SQL injection\nImplement Rate Limiting - Protect against brute force and DDoS\nHash Passwords - Use bcrypt with salt rounds >= 10\nUse Short-Lived Tokens - JWT access tokens should expire quickly\nImplement CORS Properly - Only allow trusted origins\nLog Security Events - Monitor for suspicious activity\nUse Security Headers - Implement Helmet.js\nSanitize Error Messages - Don't leak sensitive information\n❌ Don't Do This\nDon't Store Passwords in Plain Text\nDon't Use Weak Secrets - Use strong, random JWT secrets\nDon't Trust User Input - Always validate and sanitize\nDon't Expose Stack Traces - Hide error details in production\nDon't Use String Concatenation for SQL\nDon't Store Sensitive Data in JWT - JWTs are not encrypted\nDon't Ignore Security Updates - Update dependencies regularly\nDon't Log Sensitive Data\nOWASP API Security Top 10\nBroken Object Level Authorization - Always verify user can access resource\nBroken Authentication - Implement strong authentication mechanisms\nBroken Object Property Level Authorization - Validate which properties user can access\nUnrestricted Resource Consumption - Implement rate limiting and quotas\nBroken Function Level Authorization - Verify user role for each function\nUnrestricted Access to Sensitive Business Flows - Protect critical workflows\nServer Side Request Forgery (SSRF) - Validate and sanitize URLs\nSecurity Misconfiguration - Use security best practices and headers\nImproper Inventory Management - Document and secure all API endpoints\nUnsafe Consumption of APIs - Validate data from third-party APIs\nSecurity Checklist\nAuthentication & Authorization\n Implement strong authentication (JWT, OAuth 2.0)\n Use HTTPS for all endpoints\n Hash passwords with bcrypt (salt rounds >= 10)\n Implement token expiration\n Add refresh token mechanism\n Verify user authorization for each request\n Implement role-based access control (RBAC)\nInput Validation\n Validate all user inputs\n Use parameterized queries or ORM\n Sanitize HTML content\n Validate file uploads\n Implement request schema validation\n Use allowlists, not blocklists\nRate Limiting & DDoS Protection\n Implement rate limiting per user/IP\n Add stricter limits for auth endpoints\n Use Redis for distributed rate limiting\n Return proper rate limit headers\n Implement request throttling\nData Protection\n Use HTTPS/TLS for all traffic\n Encrypt sensitive data at rest\n Don't store sensitive data in JWT\n Sanitize error messages\n Implement proper CORS configuration\n Use security headers (Helmet.js)\nAdditional Resources\nOWASP API Security Top 10\nJWT Best Practices\nExpress Security Best Practices\nAPI Security Checklist"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/brandonwise/api-security",
    "publisherUrl": "https://clawhub.ai/brandonwise/api-security",
    "owner": "brandonwise",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/api-security",
    "downloadUrl": "https://openagent3.xyz/downloads/api-security",
    "agentUrl": "https://openagent3.xyz/skills/api-security/agent",
    "manifestUrl": "https://openagent3.xyz/skills/api-security/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/api-security/agent.md"
  }
}