implementing-api-schema-validation-security
使用OpenAPI规范和JSON Schema实现API Schema验证,强制执行输入/输出契约,防止注入、数据泄露和批量赋值攻击。
Best use case
implementing-api-schema-validation-security is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
使用OpenAPI规范和JSON Schema实现API Schema验证,强制执行输入/输出契约,防止注入、数据泄露和批量赋值攻击。
Teams using implementing-api-schema-validation-security should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/implementing-api-schema-validation-security/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How implementing-api-schema-validation-security Compares
| Feature / Agent | implementing-api-schema-validation-security | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
使用OpenAPI规范和JSON Schema实现API Schema验证,强制执行输入/输出契约,防止注入、数据泄露和批量赋值攻击。
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# 实施API Schema验证安全
## 概述
API Schema验证(Schema Validation)确保通过API交换的所有数据符合OpenAPI规范(OAS)或JSON Schema文档中预定义的结构。这可以防止注入攻击(SQLi、XSS、XXE),通过拒绝未知属性来阻断批量赋值(Mass Assignment),通过验证响应Schema来防止数据泄露(Data Leakage),并确保所有API交互的类型安全。Schema验证在API网关层面(运行时强制执行)和开发阶段(安全左移)均可运行。
## 前置条件
- 所有API端点的OpenAPI规范v3.0或v3.1
- 支持Schema验证的API网关(Cloudflare API Shield、Kong、AWS API Gateway)
- 理解JSON Schema draft-07或更高版本
- 配备OpenAPI验证库的开发环境
- 用于自动化Schema合规测试的CI/CD流水线
## 核心实现
### 带安全约束的OpenAPI Schema
```yaml
openapi: 3.1.0
info:
title: Secure E-Commerce API
version: 2.0.0
servers:
- url: https://api.example.com/v2
description: Production (HTTPS enforced)
security:
- OAuth2:
- read:products
- write:orders
paths:
/products:
post:
operationId: createProduct
security:
- OAuth2: [write:products]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProductCreate'
responses:
'201':
description: Product created
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
'400':
$ref: '#/components/responses/ValidationError'
'401':
$ref: '#/components/responses/Unauthorized'
/products/{productId}:
get:
operationId: getProduct
parameters:
- name: productId
in: path
required: true
schema:
type: string
format: uuid
pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
components:
schemas:
ProductCreate:
type: object
required: [name, price, category]
properties:
name:
type: string
minLength: 1
maxLength: 200
pattern: '^[a-zA-Z0-9\s\-\.]+$' # 无特殊字符,防注入
description:
type: string
maxLength: 2000
# 净化HTML实体
price:
type: number
format: float
minimum: 0.01
maximum: 999999.99
exclusiveMinimum: 0
category:
type: string
enum: [electronics, clothing, food, furniture, other]
tags:
type: array
items:
type: string
maxLength: 50
pattern: '^[a-zA-Z0-9\-]+$'
maxItems: 10
uniqueItems: true
additionalProperties: false # 关键:防止批量赋值
Product:
type: object
required: [id, name, price]
properties:
id:
type: string
format: uuid
readOnly: true
name:
type: string
price:
type: number
category:
type: string
tags:
type: array
items:
type: string
createdAt:
type: string
format: date-time
readOnly: true
additionalProperties: false # 防止内部字段数据泄露
ValidationErrorResponse:
type: object
required: [code, message]
properties:
code:
type: string
enum: [VALIDATION_ERROR]
message:
type: string
maxLength: 500
details:
type: array
items:
type: object
properties:
field:
type: string
error:
type: string
additionalProperties: false
maxItems: 50
additionalProperties: false
responses:
ValidationError:
description: Request validation failed
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationErrorResponse'
Unauthorized:
description: Authentication required
securitySchemes:
OAuth2:
type: oauth2
flows:
authorizationCode:
authorizationUrl: https://auth.example.com/authorize
tokenUrl: https://auth.example.com/token
scopes:
read:products: Read product data
write:products: Create and update products
write:orders: Create orders
```
### 服务端Schema验证(Python/FastAPI)
```python
"""FastAPI API Schema验证中间件
对所有请求和响应负载强制执行严格的Schema验证,
防止注入、批量赋值和数据泄露攻击。
"""
from fastapi import FastAPI, Request, Response, HTTPException
from fastapi.middleware import Middleware
from pydantic import BaseModel, Field, field_validator, ConfigDict
from typing import List, Optional
import re
import json
from starlette.middleware.base import BaseHTTPMiddleware
app = FastAPI()
# 带安全约束的严格Pydantic模型
class ProductCreate(BaseModel):
model_config = ConfigDict(extra='forbid') # 拒绝未知字段(防批量赋值)
name: str = Field(min_length=1, max_length=200, pattern=r'^[a-zA-Z0-9\s\-\.]+$')
description: Optional[str] = Field(default=None, max_length=2000)
price: float = Field(gt=0, le=999999.99)
category: str = Field(pattern=r'^(electronics|clothing|food|furniture|other)$')
tags: Optional[List[str]] = Field(default=None, max_length=10)
@field_validator('name')
@classmethod
def sanitize_name(cls, v):
# 通过HTML实体防止XSS
dangerous_patterns = ['<script', 'javascript:', 'onerror=', 'onload=']
lower_v = v.lower()
for pattern in dangerous_patterns:
if pattern in lower_v:
raise ValueError(f'名称中含有无效字符')
return v
@field_validator('description')
@classmethod
def sanitize_description(cls, v):
if v is None:
return v
# 过滤潜在的SQL注入模式
sql_patterns = [
r"('|--|;|/\*|\*/|xp_|exec\s|union\s+select|drop\s+table)",
]
for pattern in sql_patterns:
if re.search(pattern, v, re.IGNORECASE):
raise ValueError('描述中含有无效内容')
return v
@field_validator('tags')
@classmethod
def validate_tags(cls, v):
if v is None:
return v
if len(v) > 10:
raise ValueError('最多允许10个标签')
for tag in v:
if not re.match(r'^[a-zA-Z0-9\-]+$', tag) or len(tag) > 50:
raise ValueError(f'标签格式无效: {tag}')
return v
class ProductResponse(BaseModel):
"""显式定义允许输出字段的响应模型。
防止内部字段(如internal_notes、cost_price等)泄露。"""
model_config = ConfigDict(extra='forbid')
id: str
name: str
price: float
category: str
tags: List[str] = []
created_at: str
class ResponseValidationMiddleware(BaseHTTPMiddleware):
"""用于验证响应负载是否符合Schema的中间件。
通过检查响应内容防止意外数据泄露。"""
SCHEMA_MAP = {
'/api/v2/products': {
'POST': {'response_model': ProductResponse},
'GET': {'response_model': ProductResponse},
}
}
async def dispatch(self, request: Request, call_next):
response = await call_next(request)
# 仅验证JSON响应
content_type = response.headers.get('content-type', '')
if 'application/json' not in content_type:
return response
# 检查端点是否有注册的响应Schema
path = request.url.path
method = request.method
route_config = self.SCHEMA_MAP.get(path, {}).get(method)
if not route_config:
return response
# 读取并验证响应体
body = b""
async for chunk in response.body_iterator:
body += chunk
try:
data = json.loads(body)
model = route_config['response_model']
if isinstance(data, list):
for item in data:
model.model_validate(item)
else:
model.model_validate(data)
except Exception as e:
# 记录安全监控的验证失败
print(f"安全告警: 响应Schema违规 {method} {path}: {e}")
# 返回安全错误而非可能泄露的数据
return Response(
content=json.dumps({"error": "Internal server error"}),
status_code=500,
media_type="application/json"
)
return Response(
content=body,
status_code=response.status_code,
headers=dict(response.headers),
media_type=response.media_type
)
app.add_middleware(ResponseValidationMiddleware)
@app.post("/api/v2/products", response_model=ProductResponse, status_code=201)
async def create_product(product: ProductCreate):
# 带extra='forbid'的ProductCreate模型自动拒绝
# 任何未知字段,防止批量赋值攻击
# (如攻击者尝试设置is_admin=true或price=0)
pass
```
### Cloudflare API Shield Schema验证
```bash
# 上传OpenAPI Schema到Cloudflare API Shield
curl -X POST "https://api.cloudflare.com/client/v4/zones/{zone_id}/api_gateway/user_schemas" \
-H "Authorization: Bearer ${CF_API_TOKEN}" \
-H "Content-Type: multipart/form-data" \
-F "file=@openapi.yaml" \
-F "kind=openapi_v3"
# 以拦截模式启用Schema验证
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/{zone_id}/api_gateway/settings/schema_validation" \
-H "Authorization: Bearer ${CF_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"validation_default_mitigation_action": "block",
"validation_override_mitigation_action": null
}'
```
### CI/CD Schema合规测试
```yaml
# GitHub Actions工作流 - CI中的Schema验证
name: API Schema Security Check
on:
pull_request:
paths: ['api/**', 'openapi/**']
jobs:
schema-security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 验证OpenAPI Schema
run: |
npm install -g @stoplight/spectral-cli
spectral lint openapi.yaml --ruleset .spectral-security.yaml
- name: 检查安全反模式
run: |
python3 scripts/schema_security_check.py openapi.yaml
- name: 运行契约测试
run: |
npm install -g dredd
dredd openapi.yaml http://localhost:3000 --hookfiles=./test/hooks.js
```
## 需要检测的安全反模式
| 反模式 | 风险 | 修复方案 |
|--------|------|----------|
| `additionalProperties: true` 或缺失 | 批量赋值 | 设置 `additionalProperties: false` |
| 字符串字段无 `maxLength` | 缓冲区溢出、DoS | 添加适当的 `maxLength` 约束 |
| 字符串字段无 `pattern` | 注入攻击 | 添加正则模式限制输入 |
| 固定值字段无 `enum` | 处理意外输入 | 对已知值字段使用 `enum` |
| `format: password` 无TLS | 凭据暴露 | 强制仅使用HTTPS服务器URL |
| 缺少错误响应Schema | 信息泄露 | 定义所有4xx/5xx响应Schema |
| 请求体中包含 `readOnly` 字段 | 数据篡改 | 服务端强制执行 `readOnly` |
## 参考资料
- OpenAPI规范v3.1: https://spec.openapis.org/oas/v3.1.0
- Cloudflare API Shield Schema验证: https://developers.cloudflare.com/api-shield/security/schema-validation/
- Redocly API安全设计: https://redocly.com/learn/security
- Impart Security API验证: https://www.impart.ai/blog/detect-and-fix-api-vulnerabilities-using-validation-secure-principles-and-real-time-response
- OWASP API安全Top 10 2023: https://owasp.org/API-Security/editions/2023/en/0x00-header/Related Skills
triaging-security-incident
使用 NIST SP 800-61r3 和 SANS PICERL 框架对安全事件进行初始分类,确定严重性、范围和所需响应行动。 按类型对事件分类,根据业务影响分配优先级,并路由到相应的响应团队。适用于事件分类、 安全告警分类、严重性评估、事件优先级排序或初始事件分析等请求场景。
triaging-security-incident-with-ir-playbook
使用结构化 IR Playbook 对安全事件进行分类和优先排序,确定严重性、分配响应团队并启动适当的响应程序。
triaging-security-alerts-in-splunk
在 Splunk Enterprise Security 中对安全告警进行分类,通过 SPL 查询和事件审查(Incident Review) 仪表板对重要事件进行严重性分类、调查、关联相关遥测并做出升级或关闭决策。 适用于 SOC 分析师需要处理关联搜索产生的告警队列、确定调查优先级, 或需要为交接给二/三级分析师记录分类决策时。
testing-websocket-api-security
测试 WebSocket API 实现中的安全漏洞,包括 WebSocket 升级时缺少身份认证、跨站 WebSocket 劫持(Cross-Site WebSocket Hijacking,CSWSH)、通过 WebSocket 消息进行的注入攻击、输入校验不足、通过消息泛洪实施拒绝服务,以及通过 WebSocket 帧造成的信息泄露。测试人员使用 Burp Suite 拦截 WebSocket 握手和消息,构造恶意 payload,并测试 WebSocket 通道上的授权绕过。适用于 WebSocket 安全测试、WS 渗透测试、CSWSH 攻击或实时 API 安全评估相关请求。
testing-jwt-token-security
在安全测试活动中,评估 JSON Web Token(JWT)实现中的密码学弱点、算法混淆攻击和授权绕过漏洞。
testing-api-security-with-owasp-top-10
使用自动化和手工测试技术,针对 OWASP API 安全 Top 10 风险对 REST 和 GraphQL API 端点进行系统性评估。
performing-wireless-security-assessment-with-kismet
使用 Kismet 通过被动射频监控进行无线网络安全评估,检测流氓接入点(Rogue AP)、隐藏 SSID、弱加密和未授权客户端。
performing-ssl-tls-security-assessment
使用 sslyze Python 库评估 SSL/TLS 服务器配置,评估加密套件、证书链、协议版本、HSTS 头部,以及 Heartbleed 和 ROBOT 等已知漏洞。
performing-soap-web-service-security-testing
通过分析 WSDL 定义,测试 XML 注入(XML Injection)、XXE、WS-Security 绕过和 SOAPAction 欺骗,对 SOAP Web 服务执行安全测试。
performing-serverless-function-security-review
对 AWS Lambda、Azure Functions 和 GCP Cloud Functions 中的无服务器函数(Serverless Function)执行安全审查,识别过度宽松的执行角色(Execution Role)、不安全的环境变量、注入漏洞和缺失的运行时保护措施。
performing-scada-hmi-security-assessment
对 SCADA 人机界面(HMI, Human-Machine Interface)系统进行安全评估,识别基于 Web 的 HMI、瘦客户端配置、认证机制以及 HMI 与 PLC 之间通信信道中的漏洞,符合 IEC 62443 和 NIST SP 800-82 指南要求。
performing-s7comm-protocol-security-analysis
对西门子SIMATIC S7 PLC使用的S7comm和S7CommPlus协议进行安全分析,识别漏洞,包括重放攻击、完整性绕过、未授权的CPU停止命令以及针对S7-300、S7-400、S7-1200和S7-1500控制器弱点的程序下载操控。