{
  "rule": {
    "id": "S029",
    "name": "CSRF Protection Required",
    "description": "Require CSRF (Cross-Site Request Forgery) protection for state-changing operations. All POST, PUT, DELETE, and PATCH endpoints must implement CSRF token validation to prevent unauthorized requests from malicious sites.",
    "category": "security",
    "severity": "error",
    "languages": ["typescript", "javascript"],
    "frameworks": ["express", "nestjs", "node"],
    "version": "1.0.0",
    "status": "stable",
    "tags": ["security", "csrf", "xsrf", "authentication", "owasp"],
    "references": [
      "https://owasp.org/www-community/attacks/csrf",
      "https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html",
      "https://portswigger.net/web-security/csrf",
      "https://cwe.mitre.org/data/definitions/352.html"
    ]
  },
  "configuration": {
    "checkStateChangingMethods": ["POST", "PUT", "DELETE", "PATCH"],
    "csrfProtectionPatterns": [
      "csurf()",
      "csrfProtection",
      "verifyCsrfToken",
      "checkCsrf",
      "csrf-token",
      "_csrf",
      "req.csrfToken",
      "csrf.verify",
      "validateCSRF",
      "x-csrf-token",
      "x-xsrf-token"
    ],
    "globalMiddlewarePatterns": [
      "app.use(csurf())",
      "app.use(csrfProtection)",
      "router.use(csurf())"
    ],
    "routeHandlerPatterns": [
      "app.post",
      "app.put",
      "app.delete",
      "app.patch",
      "router.post",
      "router.put",
      "router.delete",
      "router.patch"
    ],
    "excludePatterns": [
      "test",
      "spec",
      "mock",
      "__tests__"
    ]
  },
  "examples": {
    "violations": [
      {
        "description": "POST endpoint without CSRF protection",
        "code": "app.post('/api/transfer', (req, res) => {\n  transferMoney(req.body.amount);\n});"
      },
      {
        "description": "DELETE endpoint without CSRF middleware",
        "code": "router.delete('/api/user/:id', (req, res) => {\n  deleteUser(req.params.id);\n});"
      },
      {
        "description": "PUT endpoint without token validation",
        "code": "app.put('/api/profile', (req, res) => {\n  updateProfile(req.body);\n});"
      }
    ],
    "fixes": [
      {
        "description": "Apply CSRF protection globally",
        "code": "const csrf = require('csurf');\nconst csrfProtection = csrf({ cookie: true });\napp.use(csrfProtection);\n\napp.post('/api/transfer', (req, res) => {\n  // CSRF token is automatically validated\n  transferMoney(req.body.amount);\n});"
      },
      {
        "description": "Apply CSRF protection per route",
        "code": "const csrfProtection = csrf({ cookie: true });\n\napp.post('/api/transfer', csrfProtection, (req, res) => {\n  transferMoney(req.body.amount);\n});"
      },
      {
        "description": "Manual CSRF token validation",
        "code": "app.post('/api/transfer', (req, res) => {\n  const token = req.body._csrf || req.headers['x-csrf-token'];\n  if (!validateCsrfToken(token, req.session)) {\n    return res.status(403).send('Invalid CSRF token');\n  }\n  transferMoney(req.body.amount);\n});"
      }
    ]
  },
  "testing": {
    "testCases": [
      {
        "name": "post_without_csrf",
        "type": "violation",
        "description": "POST endpoint without CSRF protection"
      },
      {
        "name": "put_without_csrf",
        "type": "violation",
        "description": "PUT endpoint without CSRF protection"
      },
      {
        "name": "delete_without_csrf",
        "type": "violation",
        "description": "DELETE endpoint without CSRF protection"
      },
      {
        "name": "global_csrf_protection",
        "type": "clean",
        "description": "Global CSRF middleware applied"
      },
      {
        "name": "route_specific_csrf",
        "type": "clean",
        "description": "Route-specific CSRF middleware"
      }
    ]
  },
  "performance": {
    "complexity": "O(n)",
    "description": "Linear complexity based on number of route handlers in the source code"
  },
  "owaspMapping": {
    "category": "A01:2021 – Broken Access Control",
    "subcategories": [
      "A04:2021 – Insecure Design"
    ],
    "description": "Validates that all state-changing endpoints have proper CSRF protection to prevent unauthorized cross-site requests"
  }
}
