Advanced Api Security Best
Enterprise-grade skill for implement, secure, design, patterns. Includes structured workflows, validation checks, and reusable patterns for security.
Advanced API Security Best Practices
Design and implement secure APIs with defense-in-depth security controls covering authentication, authorization, input validation, rate limiting, encryption, and protection against OWASP API Top 10 vulnerabilities. This skill covers security architecture patterns for REST and GraphQL APIs.
When to Use This Skill
Choose Advanced API Security Best Practices when you need to:
- Design authentication and authorization schemes for new API services
- Implement input validation and output encoding to prevent injection attacks
- Configure rate limiting, throttling, and abuse prevention controls
- Audit existing APIs against OWASP API Security Top 10
Consider alternatives when:
- You need to actively test APIs for vulnerabilities (use API Fuzzing skill)
- You need network-level API protection (use WAF/API gateway configuration)
- You need compliance-specific security (use SOC 2 or HIPAA compliance frameworks)
Quick Start
# Secure API middleware example (Express.js-style in Python/Flask) from flask import Flask, request, jsonify, abort from functools import wraps import jwt import re import time from collections import defaultdict app = Flask(__name__) SECRET_KEY = "your-secret-key" # Use env variable in production # Rate limiter rate_limits = defaultdict(list) def rate_limit(max_requests=100, window_seconds=60): def decorator(f): @wraps(f) def wrapper(*args, **kwargs): client_ip = request.remote_addr now = time.time() rate_limits[client_ip] = [ t for t in rate_limits[client_ip] if now - t < window_seconds ] if len(rate_limits[client_ip]) >= max_requests: abort(429, description="Rate limit exceeded") rate_limits[client_ip].append(now) return f(*args, **kwargs) return wrapper return decorator # JWT authentication def require_auth(f): @wraps(f) def wrapper(*args, **kwargs): auth_header = request.headers.get('Authorization', '') if not auth_header.startswith('Bearer '): abort(401, description="Missing or invalid authorization") token = auth_header[7:] try: payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256']) request.user = payload except jwt.ExpiredSignatureError: abort(401, description="Token expired") except jwt.InvalidTokenError: abort(401, description="Invalid token") return f(*args, **kwargs) return wrapper # Input validation def validate_input(schema): def decorator(f): @wraps(f) def wrapper(*args, **kwargs): data = request.get_json(silent=True) or {} for field, rules in schema.items(): value = data.get(field) if rules.get('required') and value is None: abort(400, description=f"Missing required field: {field}") if value is not None: if 'max_length' in rules and len(str(value)) > rules['max_length']: abort(400, description=f"{field} exceeds max length") if 'pattern' in rules and not re.match(rules['pattern'], str(value)): abort(400, description=f"{field} has invalid format") request.validated_data = data return f(*args, **kwargs) return wrapper return decorator @app.route('/api/users', methods=['GET']) @rate_limit(max_requests=60, window_seconds=60) @require_auth def list_users(): return jsonify({"users": []}) @app.route('/api/users', methods=['POST']) @rate_limit(max_requests=10, window_seconds=60) @require_auth @validate_input({ 'email': {'required': True, 'pattern': r'^[^@]+@[^@]+\.[^@]+$', 'max_length': 254}, 'name': {'required': True, 'max_length': 100}, }) def create_user(): return jsonify({"created": True}), 201
Core Concepts
OWASP API Security Top 10 (2023)
| # | Vulnerability | Mitigation |
|---|---|---|
| API1 | Broken Object Level Authorization | Verify user owns requested resource |
| API2 | Broken Authentication | Strong tokens, MFA, rate-limit auth endpoints |
| API3 | Broken Object Property Level Authorization | Whitelist allowed fields in responses |
| API4 | Unrestricted Resource Consumption | Rate limiting, pagination limits, payload size caps |
| API5 | Broken Function Level Authorization | Role-based access control on every endpoint |
| API6 | Unrestricted Access to Sensitive Business Flows | Bot detection, CAPTCHA on sensitive operations |
| API7 | Server-Side Request Forgery (SSRF) | URL allowlists, disable redirects, validate schemes |
| API8 | Security Misconfiguration | Disable debug, remove defaults, harden headers |
| API9 | Improper Inventory Management | API versioning, deprecation, documentation |
| API10 | Unsafe Consumption of APIs | Validate third-party API responses, use timeouts |
Authorization Middleware Pattern
from functools import wraps from flask import request, abort class RBAC: """Role-Based Access Control for API endpoints.""" def __init__(self): self.permissions = {} def register(self, role, resources): """Register permissions for a role.""" self.permissions[role] = set(resources) def require(self, resource, action="read"): """Decorator to enforce authorization.""" permission = f"{resource}:{action}" def decorator(f): @wraps(f) def wrapper(*args, **kwargs): user = getattr(request, 'user', None) if not user: abort(401) user_role = user.get('role', 'guest') allowed = self.permissions.get(user_role, set()) if permission not in allowed and f"{resource}:*" not in allowed: abort(403, description=f"Insufficient permissions for {permission}") return f(*args, **kwargs) return wrapper return decorator # Setup RBAC rbac = RBAC() rbac.register('admin', ['users:*', 'settings:*', 'reports:*']) rbac.register('editor', ['users:read', 'reports:read', 'reports:write']) rbac.register('viewer', ['users:read', 'reports:read']) # Usage: # @app.route('/api/users', methods=['DELETE']) # @require_auth # @rbac.require('users', 'delete') # def delete_user(user_id): # ...
Configuration
| Parameter | Description | Default |
|---|---|---|
jwt_algorithm | JWT signing algorithm | "HS256" |
token_expiry | Token expiration time | 3600 (1 hour) |
rate_limit_window | Rate limit window in seconds | 60 |
rate_limit_max | Max requests per window | 100 |
max_payload_size | Maximum request body size | 1MB |
cors_origins | Allowed CORS origins | [] (none) |
security_headers | Response security headers | OWASP recommended |
input_max_length | Default field max length | 1000 |
Best Practices
-
Validate authorization on every request at the resource level — Don't rely on hiding endpoints or client-side checks. Every API handler must verify that the authenticated user has permission to access the specific resource they're requesting. Check ownership: "Does user X own resource Y?"
-
Use parameterized queries and ORMs to prevent SQL injection — Never concatenate user input into SQL queries. Use parameterized queries (
?placeholders) or ORM methods that handle escaping. This applies to all database interactions, including search, filter, and sort parameters. -
Implement rate limiting at multiple levels — Apply per-IP limits at the infrastructure level (API gateway/WAF), per-user limits at the application level, and per-endpoint limits for sensitive operations (login, password reset, payment). Use sliding window algorithms for accurate limiting.
-
Return minimal error information in production — Detailed error messages (stack traces, SQL errors, internal paths) help attackers. Return generic messages ("An error occurred") with error codes for client-side handling. Log detailed errors server-side for debugging.
-
Whitelist response fields instead of blacklisting — Explicitly define which fields are returned in API responses rather than excluding sensitive ones. Blacklists are fragile — new sensitive fields added to the model are automatically exposed. Use serializers or response schemas that whitelist allowed fields.
Common Issues
JWT tokens are stolen and replayed — JWTs are bearer tokens — anyone who has the token can use it. Use short expiry times (15-60 minutes), implement token rotation with refresh tokens, and store refresh tokens server-side with revocation capability. For sensitive operations, require re-authentication.
CORS misconfiguration exposes API to cross-origin attacks — Never set Access-Control-Allow-Origin: * with credentials. Whitelist specific trusted origins and validate the Origin header against the whitelist. Reflect arbitrary origins back is equivalent to no CORS protection.
Rate limiting is bypassed via distributed IPs — IP-based rate limiting fails against botnets. Layer rate limiting: per-IP, per-user-token, per-API-key, and per-operation. Implement account-level rate limits that can't be bypassed by changing IP addresses.
Reviews
No reviews yet. Be the first to review this template!
Similar Templates
Full-Stack Code Reviewer
Comprehensive code review skill that checks for security vulnerabilities, performance issues, accessibility, and best practices across frontend and backend code.
Test Suite Generator
Generates comprehensive test suites with unit tests, integration tests, and edge cases. Supports Jest, Vitest, Pytest, and Go testing.
Pro Architecture Workspace
Battle-tested skill for architectural, decision, making, framework. Includes structured workflows, validation checks, and reusable patterns for development.