007 - api-security-patterns
API 安全模式与反模式保护 REST API、webhook 和服务间通信的参考。在007 audit、007 threat-model和 API 代码审查时使用。1. 认证模式API 密钥# 正确API 密钥在请求头中Authorization:ApiKey sk-live-abc123def456# 错误API 密钥在 URL 中会记录在服务器日志、浏览器历史、referrer 头中GET /api/data?api_keysk-live-abc123def456# 最佳实践api_keys:-使用前缀识别密钥sk-live-、sk-test-、pk--哈希存储SHA-256而非明文-定期轮换最长 90 天-限定到特定权限/资源-按密钥进行速率限制-一旦泄露立即撤销-不同环境使用不同密钥开发/预发布/生产OAuth 2.0# 按客户端类型推荐的流程oauth2_flows:server_to_server:client_credentialsweb_app_with_backend:authorization_code PKCEsingle_page_app:authorization_code PKCE无客户端密钥mobile_app:authorization_code PKCENEVER_USE:implicit_grant# 已弃用令牌暴露在 URL 中# 令牌最佳实践tokens:access_token_lifetime:15_minutes# 短寿命refresh_token_lifetime:7_days# 使用时轮换refresh_token_rotation:true# 每次刷新令牌store_tokens:httponly_secure_cookie# 非 localStoragerevocation:implement_revocation_endpointJWT 最佳实践# 正确正确的 JWT 配置jwt_config{algorithm:RS256,# 非对称而非使用弱密钥的 HS256expiration:900,# 最长 15 分钟issuer:auth.example.com,# 始终验证audience:api.example.com,# 始终验证required_claims:[sub,exp,iat,iss,aud],}# 需要检测的错误模式jwt_antipatterns[algorithm: none,# 无签名验证algorithm: HS256,# 使用弱/共享密钥exp: far_future,# 永不过期的令牌no audience check,# 跨服务重复使用令牌secret in code,# 硬编码的签名密钥JWT in URL parameter,# 被记录、缓存、通过 referrer 泄露]# 关键始终验证defvalidate_jwt(token:str)-dict:returnjwt.decode(token,keyPUBLIC_KEY,# 非弱共享密钥algorithms[RS256],# 显式指定不从令牌头读取audienceapi.example.com,issuerauth.example.com,options{require:[exp,iat,sub]},)2. 速率限制策略令牌桶# 最适合允许突发流量同时维持平均速率classTokenBucket: capacity100, refill_rate10/sec 允许 100 个请求的突发然后每秒 10 个持续。 def__init__(self,capacity:int,refill_rate:float):self.capacitycapacity self.tokenscapacity self.refill_raterefill_rate self.last_refilltime.time()defallow_request(self)-bool:self._refill()ifself.tokens1:self.tokens-1returnTruereturnFalse滑动窗口# 最适合平滑的速率限制无突发许可# 在时间窗口中跟踪请求统计最近 N 秒内的请求数# Redis 实现ZADD ZRANGEBYSCORE ZCARD按用户速率限制rate_limits:unauthenticated:requests_per_minute:20requests_per_hour:100authenticated_free:requests_per_minute:60requests_per_hour:1000authenticated_paid:requests_per_minute:300requests_per_hour:10000# 始终包含响应头headers:X-RateLimit-Limit:60X-RateLimit-Remaining:45X-RateLimit-Reset:1620000060# Unix 时间戳Retry-After:30# 在 429 响应中3. 输入验证模式验证frompydanticimportBaseModel,Field,validatorclassCreateUserRequest(BaseModel):name:strField(min_length1,max_length100)email:strField(regexr^[a-zA-Z0-9_.-][a-zA-Z0-9-]\.[a-zA-Z0-9-.]$)age:intField(ge13,le150)role:strField(defaultuser)# 如果用户尝试设置admin则忽略validator(role)defrestrict_role(cls,v):ifvnotin(user,viewer):# 仅允许安全角色returnuserreturnvclassConfig:extraforbid# 拒绝未知字段防止批量赋值类型检查和大小限制validation_rules:string_fields:max_length:10_000# 无无界字符串strip_whitespace:truereject_null_bytes:true# \x00 可能导致问题numeric_fields:define_min_max:true# 始终设置边界reject_nan_infinity:true# 可能破坏数学运算array_fields:max_items:100# 无无界数组validate_each_item:truefile_uploads:max_size:10MBallowed_types:[image/jpeg,image/png,application/pdf]validate_magic_bytes:true# 不要仅信任 Content-Type 头scan_for_malware:truequery_parameters:max_page_size:100default_page_size:20max_query_length:5004. Webhook 安全HMAC 签名验证importhmacimporthashlibimporttimedefverify_webhook(payload:bytes,headers:dict,secret:str)-bool:完整的 webhook 验证签名 时间戳。signatureheaders.get(X-Webhook-Signature)timestampheaders.get(X-Webhook-Timestamp)ifnotsignatureornottimestamp:returnFalse# 1. 防止重放攻击5 分钟窗口ifabs(time.time()-int(timestamp))300:returnFalse# 2. 计算预期签名signed_payloadf{timestamp}.{payload.decode()}expectedhmac.new(secret.encode(),signed_payload.encode(),hashlib.sha256).hexdigest()# 3. 常量时间比较防止时序攻击returnhmac.compare_digest(fsha256{expected},signature)Webhook 最佳实践webhook_security:sending:-使用 HMAC-SHA256 签名每个有效载荷-在签名中包含时间戳-发送唯一事件 ID 以实现幂等性-仅使用 HTTPS-实施指数退避重试-定期轮换签名密钥receiving:-在任何处理之前验证签名-拒绝超过 5 分钟的请求重放保护-实施幂等性存储已处理的事件 ID-快速返回 200异步处理-不要盲目信任有效载荷数据验证模式-对传入 webhook 进行速率限制-记录所有 webhook 事件以供审计5. CORS 配置# 危险允许一切# Access-Control-Allow-Origin: *# Access-Control-Allow-Credentials: true # 对 * 来源无效# 安全显式白名单CORS_CONFIG{allowed_origins:[https://app.example.com,https://admin.example.com,],allowed_methods:[GET,POST,PUT,DELETE],allowed_headers:[Authorization,Content-Type],allow_credentials:True,max_age:3600,# 预检缓存1 小时expose_headers:[X-RateLimit-Remaining],}# 需要检测的反模式cors_antipatterns[Access-Control-Allow-Origin: *,# 过于宽松reflect Origin header as Allow-Origin,# 实际上等于带凭证的 *Access-Control-Allow-Origin: null,# 可被利用Allow-Origin without credentials but with auth,# 不一致]6. 安全头检查清单# 所有 API 响应必需的安全头security_headers:# 防止 MIME 嗅探X-Content-Type-Options:nosniff# 防止点击劫持针对 HTML 响应X-Frame-Options:DENY# XSS 保护旧浏览器X-XSS-Protection:0# 禁用改用 CSP# HTTPS 强制Strict-Transport-Security:max-age31536000; includeSubDomains; preload# 内容安全策略针对 HTML 响应Content-Security-Policy:default-src self; script-src self; style-src self# Referrer 策略Referrer-Policy:strict-origin-when-cross-origin# 权限策略Permissions-Policy:camera(), microphone(), geolocation()# 移除服务器信息头Server:REMOVE_THIS_HEADERX-Powered-By:REMOVE_THIS_HEADER# 敏感数据的缓存控制Cache-Control:no-store, no-cache, must-revalidate, privatePragma:no-cache7. 常见 API 漏洞BOLA / IDOR对象级授权失效# 有漏洞无所有权检查app.get(/api/users/{user_id}/orders)defget_orders(user_id:int):returndb.query(Order).filter(Order.user_iduser_id).all()# 任何已认证用户都可以访问其他用户的订单# 安全强制所有权检查app.get(/api/users/{user_id}/orders)defget_orders(user_id:int,current_user:UserDepends(get_current_user)):ifcurrent_user.id!user_idandnotcurrent_user.is_admin:raiseHTTPException(403,禁止访问)returndb.query(Order).filter(Order.user_iduser_id).all()批量赋值# 有漏洞接受请求中的所有字段app.put(/api/users/{user_id})defupdate_user(user_id:int,data:dict):db.query(User).filter(User.iduser_id).update(data)# 攻击者发送 {role: admin, is_verified: true}# 安全可更新字段的显式白名单classUserUpdateRequest(BaseModel):name:str|NoneNoneemail:str|NoneNone# role 和 is_verified 不包含在内app.put(/api/users/{user_id})defupdate_user(user_id:int,data:UserUpdateRequest):db.query(User).filter(User.iduser_id).update(data.dict(exclude_unsetTrue))数据过度暴露# 有漏洞返回整个数据库模型app.get(/api/users/{user_id})defget_user(user_id:int):returndb.query(User).get(user_id).__dict__# 返回id, name, email, password_hash, ssn, internal_notes, ...# 安全显式响应模式classUserResponse(BaseModel):id:intname:stremail:str# 仅公开字段app.get(/api/users/{user_id},response_modelUserResponse)defget_user(user_id:int):returndb.query(User).get(user_id)8. 幂等性模式# 防止重复处理同一请求# 对以下操作至关重要支付、webhook、任何非幂等操作classIdempotencyMiddleware: 客户端发送Idempotency-Key: unique-uuid-here 服务器存储结果重试时返回缓存响应。 def__init__(self,cache):self.cachecache# Redis 或类似asyncdefprocess(self,idempotency_key:str,handler):# 1. 检查是否已处理cachedawaitself.cache.get(fidempotency:{idempotency_key})ifcached:returncached# 返回与首次相同的响应# 2. 加锁防止并发重复处理lockawaitself.cache.lock(flock:{idempotency_key},timeout30)ifnotlock:raiseHTTPException(409,请求已在处理中)try:# 3. 处理请求resultawaithandler()# 4. 缓存结果24 小时 TTLawaitself.cache.set(fidempotency:{idempotency_key},result,ttl86400,)returnresultfinally:awaitlock.release()何时需要幂等性密钥require_idempotency_key:-POST /payments-POST /transfers-POST /orders-POST /webhooks/*# 使用事件 ID 作为密钥-任何非幂等变更操作naturally_idempotent:# 无需密钥-GET所有-PUT完整替换-DELETE按 ID快速安全审查检查清单认证 [ ] 所有端点需要认证除非明确公开 [ ] API 密钥在请求头中而非 URL 中 [ ] JWT 使用 RS256 和短有效期 [ ] 公开客户端使用 OAuth 2.0 PKCE [ ] 实施了令牌轮换 授权 [ ] 每次数据访问有所有权检查BOLA 预防 [ ] 每个特权操作有角色检查 [ ] 批量赋值保护显式字段白名单 [ ] 响应模式过滤敏感字段 输入/输出 [ ] 所有输入有模式验证 [ ] 所有字段、数组和文件有大小限制 [ ] 参数化查询无字符串拼接 [ ] 通用错误消息无堆栈跟踪 传输 [ ] 所有地方使用 HTTPSTLS 1.2 [ ] 设置了安全头 [ ] CORS 已显式配置 [ ] 已启用 HSTS 运维 [ ] 每用户/IP 的速率限制 [ ] 带有关联 ID 的请求日志 [ ] webhook 签名已验证 [ ] 变更操作的幂等性密钥 [ ] 依赖项已扫描 CVE

相关新闻

【Bonjour】从《我的女友景甜》小作文到实现一个简易区块链:原理与Python代码详解

【Bonjour】从《我的女友景甜》小作文到实现一个简易区块链:原理与Python代码详解

我沉默了 他以为我不想来~~~~一、一场精心策划的流量收割 2026年8月27日晚,波场TRON创始人孙宇晨(币圈人送外号"孙割")在外网发了一篇六千字长文《我的女友景甜》。同一天,他的律师已向法院递交诉状,起诉景甜…

2026/11/14 2:05:21 阅读更多 →
老款英特尔Mac安装Windows驱动指南:BootCamp 6.1.7071.zip详解与避坑

老款英特尔Mac安装Windows驱动指南:BootCamp 6.1.7071.zip详解与避坑

简介:本资源是苹果官方Boot Camp 6.1.7071驱动与辅助软件安装包,专为2018–2019年款带Touch Bar的MacBook Pro机型设计,覆盖13英寸四端口、13英寸及15英寸带触控条等主流型号,解决Windows系统在新款Mac硬件上无法识别键盘背光、触…

2026/11/10 11:08:59 阅读更多 →
Delphi EhLib控件库深度解析:无源码版本集成与实战应用指南

Delphi EhLib控件库深度解析:无源码版本集成与实战应用指南

简介:本资源是专为Delphi 13.1开发者打造的EhLib.VclFmx 13.0.015增强控件库,面向中高级Windows桌面与跨平台应用开发者,解决VCL/FMX项目中数据感知、界面美化及快速集成等核心开发痛点。压缩包含2000个文件,总计349.63MB&#xf…

2026/11/10 22:58:20 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/13 5:13:25 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/13 5:13:25 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/13 5:13:25 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/13 22:08:41 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/12 18:22:25 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/13 5:13:25 阅读更多 →

日新闻

周新闻

月新闻