公开文集
0x01 SRC 资产管理系统
0x02 Web 漏洞案例库
0x03 小程序漏洞案例库
第一章:小程序渗透基础
1.1 微信小程序反编译与动态调试
1.2 微信小程序强制开启开发者模式
0x99 信息安全学习体系
01-网络安全基础
Day-001-TCP-IP协议栈安全分析
Day-002-DNS协议安全与DNS劫持攻防
Day-003-IPv6 安全基础与过渡
Day-004-HTTP-HTTPS协议深度解析
Day-005-网络嗅探与流量分析技术
Day-006-防火墙原理与配置实践
Day-007-网络地址转换 NAT 安全分析
Day-008-路由协议安全 RIP-OSPF-BGP
Day-009-VLAN 安全与 VLAN-Hopping
Day-010-无线网络基础与安全 802.11
Day-011-网络访问控制 802.1X-NAC
Day-012-网络分段与微隔离设计
Day-013-负载均衡器安全配置
Day-014-CDN安全与防护
Day-015-NTP安全
Day-016-DHCP安全与攻击防护
Day-017-ICMP协议安全分析
Day-018-网络协议模糊测试基础
Day-019-网络流量基线建立
Day-020-网络取证基础
Day-021-网络入侵检测系统 NIDS
Day-022-网络入侵防御系统 NIPS
Day-023-网络流量加密与解密
Day-024-网络协议逆向工程基础
Day-025-网络性能与安全权衡
Day-026-SDN 安全
Day-027-网络虚拟化安全
Day-028-网络欺骗技术
Day-029-网络威胁情报应用
Day-030-网络容量规划与安全
Day-031-网络安全架构设计实战
02-Web 安全
Day-032-OWASP-Top-10-2021详解
Day-033-SQL 注入原理与手工检测
Day-034-SQL注入进阶报错注入与盲注
Day-035-XSS跨站脚本攻击基础
Day-036-XSS 进阶绕过与利用
Day-037-XSS进阶绕过与利用
Day-038-CSRF 跨站请求伪造
Day-039-文件上传漏洞
Day-040-反序列化漏洞基础
Day-041-PHP反序列化深入
Day-042-Java反序列化深入
Day-043-SSTI 服务端模板注入
Day-044-文件包含漏洞 LFI-RFI
Day-045-命令注入漏洞
Day-046-XXE-XML 外部实体注入
Day-047-反序列化漏洞进阶
Day-048-API 安全基础
Day-049-API认证与授权安全
Day-050-API漏洞挖掘实战
Day-051-文件上传漏洞进阶
Day-052-反序列化漏洞实战
Day-053-Web 安全综合实战
Day-054-移动安全基础
Day-055-Android 应用安全测试
Day-056-iOS 应用安全测试
Day-057-移动应用综合实战
Day-058-云安全基础
Day-059-AWS 安全实战
Day-060-Azure 安全实战
Day-061-GCP 安全实战
Day-062-云安全综合实战
Day-063-容器安全基础
Day-064-Docker 安全实战
Day-065-Kubernetes 安全实战
Day-066-容器安全综合实战
Day-067-API 安全进阶
Day-068-服务端请求伪造 SSRF 深入
Day-069-文件上传漏洞进阶
Day-070-反序列化漏洞实战进阶
Day-071-业务逻辑漏洞深入
Day-072-前端安全深入
Day-073-Web 安全综合实战
Day-074-云安全进阶
Day-075-移动安全进阶
Day-076-API 安全进阶
Day-077-前端安全进阶
Day-078-业务逻辑漏洞进阶
Day-079-反序列化漏洞实战进阶
Day-080-文件上传漏洞实战进阶
Day-081-SSTI 服务端模板注入进阶
Day-082-XXE-XML 外部实体注入进阶
Day-083-SSRF 服务端请求伪造进阶
Day-084-命令注入漏洞进阶
Day-085-文件包含漏洞进阶
Day-086-反序列化漏洞实战进阶
Day-087-文件上传漏洞实战进阶
Day-088-SSTI 服务端模板注入实战进阶
Day-089-XXE-XML 外部实体注入实战进阶
Day-090-SSRF 服务端请求伪造实战进阶
Day-091-命令注入漏洞实战进阶
Day-092-Web 安全综合实战
Day-093-GraphQL 安全
Day-094-JWT 与 OAuth2 安全
03-系统安全
Day-095-系统监控与检测
Day-096-主机防火墙配置
Day-097-系统审计与合规
Day-098-Linux 系统安全进阶
Day-099-Windows 系统安全进阶
Day-100-容器安全进阶
Day-101-容器编排安全进阶
Day-102-Linux 内核安全
Day-103-Windows 内核安全
Day-104-系统安全总结与实战
Day-105-Linux 系统安全基础
Day-106-Windows 系统安全基础
Day-107-容器安全基础
Day-108-系统加固技术
Day-109-日志分析技术
Day-110-威胁狩猎技术
04-应用安全
Day-111-安全编码规范
Day-112-输入验证技术
Day-113-输出编码技术
Day-114-错误处理安全
Day-115-会话管理安全
Day-116-认证安全
Day-117-授权安全
Day-118-数据保护安全
Day-119-日志安全
Day-120-API 安全
Day-121-微服务安全
Day-122-新兴技术安全概论
Day-123-DevSecOps 流水线安全
Day-124-云原生安全架构
Day-125-API 安全最佳实践
Day-126-安全编码规范
Day-127-SDL 安全开发生命周期
Day-128-威胁建模实战
Day-129-安全需求分析
Day-130-安全架构设计
Day-131-安全编码实践Java
Day-132-安全编码实践Python
Day-133-代码审计方法论
Day-134-静态代码分析SAST
Day-135-动态应用测试DAST
Day-136-交互式测试IAST
Day-137-软件成分分析SCA
Day-138-依赖漏洞管理
Day-139-安全测试自动化
Day-140-漏洞管理与响应
Day-141-应用安全总结与展望
Day-142-OWASP-Top10-2024 详解
Day-143-CWE-Top25 分析
Day-144-漏洞挖掘方法论
Day-145-模糊测试技术
Day-146-逆向工程基础
Day-147-漏洞利用开发基础
Day-148-漏洞复现与验证
Day-149-漏洞披露流程
Day-150-CVE 申请与管理
Day-151-漏洞赏金计划
Day-152-等保2.0详解
Day-153-GDPR 合规实践
Day-154-数据安全法解读
Day-155-个人信息保护法与合规指南
Day-156-个人信息保护法解读
Day-157-ISO-27001 信息安全管理体系
Day-158-SOC-2 合规与审计
Day-159-PCI-DSS 支付卡行业数据安全标准
Day-160-网络安全审查办法解读
Day-161-数据出境安全评估办法
Day-162-应用安全评估实战
Day-163-红蓝对抗演练
Day-164-安全应急响应
Day-165-安全运营中心建设
Day-166-应用安全总结与展望
05-密码学
Day-167-密码学基础
Day-168-对称加密算法详解
Day-169-非对称加密算法详解
Day-170-哈希函数与数字签名
Day-171-密钥管理与PKI
Day-172-TLS-SSL 协议详解
Day-173-国密算法详解
Day-174-认证与密钥协议
Day-175-随机数生成与熵源
Day-176-椭圆曲线密码学详解
Day-177-后量子密码学详解
Day-178-高级密码学主题
Day-179-密码学行业应用精选
Day-180-常用加密算法原理与实现
Day-181-密码学总结与展望
Day-182-密码学系列总结与展望
06-渗透测试
Day-183-渗透测试方法论
Day-184-信息收集技术详解
Day-185-漏洞扫描技术详解
Day-186-漏洞利用技术详解
Day-187-渗透测试中的漏洞利用框架
Day-188-漏洞利用框架与 Metasploit 深入
Day-189-渗透测试中的 WAF 绕过技术
Day-190-渗透测试中的模糊测试技术
Day-191-渗透测试中的代码审计与静态分析
Day-192-渗透测试中的密码哈希破解技术
Day-193-渗透测试报告编写指南
Day-194-Web 应用渗透测试
Day-195-渗透测试中的 API 安全测试
Day-196-渗透测试中的 GraphQL 安全测试
Day-197-渗透测试中的前后端分离应用测试
Day-198-渗透测试中的小程序安全测试
Day-199-渗透测试中的浏览器安全测试
Day-200-OAuth-SSO安全测试
Day-201-渗透测试中的业务逻辑漏洞测试
Day-202-渗透测试中的厚客户端安全测试
Day-203-渗透测试综合实战演练
Day-204-内网渗透技术详解
Day-205-渗透测试中的内网信息收集进阶
Day-206-渗透测试中的域森林渗透技术
Day-207-渗透测试中的权限维持技术
Day-208-渗透测试中的横向移动技术
Day-209-渗透测试中的痕迹清理与反取证技术
Day-210-渗透测试中的数据窃取与 Exfiltration 技术
Day-211-渗透测试中的内部威胁与数据泄露测试
Day-212-渗透测试中的物理安全渗透
Day-213-社会工程学攻击技术
Day-214-移动应用渗透测试
Day-215-云安全渗透测试
Day-216-渗透测试中的容器与 Kubernetes 安全渗透
Day-217-渗透测试中的 Serverless 安全测试
Day-218-渗透测试中的微服务安全测试
Day-219-物联网安全渗透测试
Day-220-工业控制系统安全渗透测试
Day-221-无线网络安全渗透测试
Day-222-数据库安全渗透测试
Day-223-渗透测试中的供应链安全测试
Day-224-红队演练技术详解
Day-225-渗透测试中的红队基础设施搭建
Day-226-渗透测试中的威胁情报与狩猎
Day-227-渗透测试中的综合指纹识别技术
Day-228-自动化渗透测试技术
Day-229-渗透测试中的运维安全测试
Day-230-渗透测试中的区块链与智能合约安全测试
Day-231-渗透测试中的漏洞管理与修复验证
Day-232-渗透测试法律与合规
Day-233-后渗透攻击技术详解
Day-234-渗透测试中的人工智能应用
Day-235-漏洞利用开发深入
Day-236-云原生渗透测试深入
07-应急响应
Day-237-应急响应概述与核心概念
Day-238-应急响应流程框架
Day-239-CSIRT 团队组建与职责分工
Day-240-应急响应工具包准备
Day-241-应急响应法律与合规要求
Day-242-安全事件检测方法与指标
Day-243-云原生应急响应
Day-244-日志收集与分析技术
Day-245-网络流量分析与异常识别
Day-246-自动化响应与 SOAR
Day-247-端点监控与 EDR 技术
Day-248-威胁狩猎方法论
Day-249-威胁情报在检测中的应用
Day-250-数字取证基础与证据链管理
Day-251-内存取证技术
Day-252-磁盘取证与文件恢复
Day-253-网络取证与数据包分析
Day-254-云环境与容器取证
Day-255-恶意代码静态分析技术
Day-256-恶意代码动态分析技术
Day-257-恶意代码行为分析方法
Day-258-逆向工程基础与工具
Day-259-沙箱技术与自动化分析
Day-260-事件隔离与遏制策略
Day-261-威胁根除与系统修复
Day-262-系统恢复与数据重建
Day-263-业务连续性计划
Day-264-事件复盘与经验总结
Day-265-APT 攻击事件复盘分析
Day-266-勒索软件事件响应实战
Day-267-数据泄露事件处置流程
Day-268-内部威胁调查与取证
Day-269-综合应急响应演练
08-安全运维
Day-270-安全运营中心 SOC 概述
Day-271-安全监控指标体系
Day-272-安全告警管理
Day-273-安全可视化与仪表盘
Day-274-监控工具选型
Day-275-日志采集技术
Day-276-日志标准化与解析
Day-277-日志存储与归档
Day-278-日志分析技术
Day-279-日志合规要求
Day-280-SIEM 架构与设计
Day-281-关联规则引擎
Day-282-高级关联分析
Day-283-UEBA 用户实体行为分析
Day-284-威胁狩猎
Day-285-SOAR 基础概念
Day-286-剧本设计
Day-287-自动化响应技术
Day-288-安全工具集成
Day-289-SOAR 度量与优化
Day-290-安全基线管理
Day-291-漏洞管理流程
Day-292-补丁管理策略
Day-293-变更安全管理
Day-294-合规审计技术
Day-295-7x24 安全运营
Day-296-安全事件管理流程
Day-297-安全运营度量体系
Day-298-持续改进机制
Day-299-安全运维综合演练
Day-300-云原生安全运营
Day-301-AI 与机器学习安全运营
Day-302-安全自动化脚本实战
09-移动安全
Day-303-移动安全威胁概述
Day-304-移动设备安全架构
Day-305-移动操作系统安全模型
Day-306-移动应用权限管理
Day-307-移动端数据加密
Day-308-330-Android 安全合集
Day-309-Android 安全架构
Day-310-Android 组件安全
Day-311-Android 权限与隐私
Day-312-Android 逆向工程
Day-313-Android 应用加固
Day-314-iOS 安全架构
Day-315-iOS 应用沙盒机制
Day-316-越狱与反越狱
Day-317-iOS 逆向工程
Day-318-iOS 企业分发安全
Day-319-移动安全开发生命周期
Day-320-移动应用安全测试
Day-321-移动应用加固技术
Day-322-移动威胁防护
Day-323-移动安全合规
10-云安全
Day-324-云计算安全模型
Day-325-责任共担模型
Day-326-云安全威胁模型
Day-327-云安全合规框架
Day-328-云安全架构设计
Day-329-AWS IAM 安全
Day-330-AWS 网络安全
Day-331-AWS 存储安全
Day-332-AWS 安全监控
Day-333-AWS 安全最佳实践
Day-334-Azure AD 安全
Day-335-Azure 网络安全
Day-336-Azure 存储安全
Day-337-Azure 安全中心
Day-338-Azure 安全最佳实践
Day-339-容器安全基础
Day-340-Kubernetes 安全
Day-341-Serverless 安全
Day-342-云原生 DevSecOps
Day-343-云安全态势管理 CSPM
11-物联网工控
Day-344-物联网安全概述
Day-345-IoT 通信协议安全
Day-346-IoT 设备安全
Day-347-IoT 平台安全
Day-348-IoT 应用安全
Day-349-工业控制系统概述
Day-350-工控协议安全
Day-351-PLC 安全
Day-352-SCADA 系统安全
Day-353-工控安全防护
12-综合与总结
Day-354-安全职业发展路径
Day-355-安全技术趋势展望
Day-356-安全建设方法论
Day-357-经典攻防案例复盘
Day-358-安全学习资源指南
Day-359-信息安全行业求职指南
-
+
首页
Day-125-API 安全最佳实践
# Day 139: API 安全最佳实践 > 应用安全系列第 32 天 | 预计阅读时间:50 分钟 | 难度:★★★★★ --- **PUA v3 · Sprint 启动** ``` ┌─────────┬────────────────────────────────────┐ │ 清单 任务 │ API 安全最佳实践 - Day 139 │ ├─────────┼────────────────────────────────────┤ │ 味道 │ 阿里味(自动:安全任务) │ ├─────────┼────────────────────────────────────┤ │ 压力 │ L0 · 信任期 │ └─────────┴────────────────────────────────────┘ ``` ▎ API 不是内部接口,是对外开放的能力。能力不保护,就是给别人送武器。今天系统学习 API 安全。 --- ## 清单 目录 1. [API 安全概述](#api 安全概述) 2. [API 安全威胁](#api 安全威胁) 3. [认证与授权](#认证与授权) 4. [输入验证](#输入验证) 5. [速率限制](#速率限制) 6. [API 网关安全](#api 网关安全) 7. [API 测试安全](#api 测试安全) 8. [API 监控与审计](#api 监控与审计) 9. [OWASP API Security Top 10](#owasp-api-security-top-10) 10. [实战案例分析](#实战案例分析) 11. [总结与思考](#总结与思考) 12. [参考资料](#参考资料) --- ## API 安全概述 ### 为什么 API 安全重要 > ▎ API 不是后台接口,是业务入口。入口不守,业务就是裸奔的。 **API 安全现状**: ``` API 攻击趋势 (2024): - API 攻击增长:321% (同比增长) - 平均每次攻击成本:450 万美元 - 受影响组织:83% 常见攻击类型: 1. 未授权访问:35% 2. 数据泄露:28% 3. 注入攻击:18% 4. 认证绕过:12% 5. 其他:7% 高风险行业: - 金融服务:API 调用量最大 - 医疗健康:数据最敏感 - 电子商务:业务最依赖 - 政府机构:合规要求最高 ``` **API 安全挑战**: ``` 1. 影子 API (Shadow API) - 未文档化的 API - 测试 API 未下线 - 旧版本 API 未废弃 - 发现难、管理难 2. 僵尸 API (Zombie API) - 已废弃但未下线 - 不再维护 - 存在已知漏洞 - 攻击者目标 3. 过度暴露 - 过多数据返回 - 过度权限 - 缺少速率限制 - 容易被滥用 4. 认证授权复杂 - 多认证方式 - 权限粒度粗 - Token 管理混乱 - 容易被绕过 ``` ### API 安全框架 **API 安全生命周期**: ``` ┌─────────────────────────────────────────────────────────┐ │ API 安全生命周期 │ ├─────────────────────────────────────────────────────────┤ │ │ │ 设计阶段 │ │ ├── 威胁建模 │ │ ├── 安全需求 │ │ └── 架构设计 │ │ │ │ 开发阶段 │ │ ├── 安全编码 │ │ ├── 代码审查 │ │ └── 安全测试 │ │ │ │ 部署阶段 │ │ ├── 配置加固 │ │ ├── 网关部署 │ │ └── 证书管理 │ │ │ │ 运营阶段 │ │ ├── 监控告警 │ │ ├── 日志审计 │ │ └── 应急响应 │ │ │ │ 退役阶段 │ │ ├── 版本管理 │ │ ├── 平滑迁移 │ │ └── 安全下线 │ │ │ └─────────────────────────────────────────────────────────┘ ``` --- ## API 安全威胁 ### API 特有威胁 > ▎ API 威胁不是 Web 威胁的简单复制,是 API 特有的。特有威胁不防,就是给攻击者留门。 **威胁分类**: ``` 1. 认证类威胁 - 认证绕过 - Token 窃取 - 会话劫持 - 凭证填充 2. 授权类威胁 - 越权访问 (BOLA/IDOR) - 权限提升 - 水平越权 - 垂直越权 3. 数据类威胁 - 数据泄露 - 过度暴露 - 批量爬取 - 数据篡改 4. 资源类威胁 - DDoS 攻击 - 资源耗尽 - 成本攻击 - 速率限制绕过 5. 注入类威胁 - SQL 注入 - NoSQL 注入 - 命令注入 - XXE 注入 ``` **API 攻击链**: ``` 典型 API 攻击流程: 阶段 1: 侦察 ├── API 发现 (扫描、文档、JS 分析) ├── 端点枚举 ├── 参数识别 └── 认证机制分析 阶段 2: 初始访问 ├── 利用公开 API ├── 凭证泄露利用 ├── 默认凭证尝试 └── Token 猜测 阶段 3: 权限提升 ├── 越权访问测试 ├── 参数篡改 ├── 权限边界探测 └── 管理员接口发现 阶段 4: 数据获取 ├── 批量数据提取 ├── 敏感数据定位 ├── 数据外传 └── 持久化访问 阶段 5: 影响达成 ├── 数据出售 ├── 勒索 ├── 业务破坏 └── 声誉损害 ``` --- ## 认证与授权 ### API 认证机制 > ▎ 认证不是加个登录,是建立信任。信任不建立,访问就是随意的。 **认证方式对比**: ``` ┌─────────────────┬──────────────┬──────────────┬──────────────┐ │ 方式 │ 安全性 │ 易用性 │ 适用场景 │ ├─────────────────┼──────────────┼──────────────┼──────────────┤ │ API Key │ 低 │ 高 │ 内部/低敏感 │ ├─────────────────┼──────────────┼──────────────┼──────────────┤ │ Basic Auth │ 低 (需 HTTPS)│ 高 │ 简单场景 │ ├─────────────────┼──────────────┼──────────────┼──────────────┤ │ JWT │ 中 │ 高 │ 无状态认证 │ ├─────────────────┼──────────────┼──────────────┼──────────────┤ │ OAuth 2.0 │ 高 │ 中 │ 第三方授权 │ ├─────────────────┼──────────────┼──────────────┼──────────────┤ │ mTLS │ 很高 │ 低 │ 高安全场景 │ ├─────────────────┼──────────────┼──────────────┼──────────────┤ │ API Gateway │ 高 │ 中 │ 统一管理 │ └─────────────────┴──────────────┴──────────────┴──────────────┘ ``` **JWT 安全实现**: ```python # JWT 安全实现 import jwt from datetime import datetime, timedelta from cryptography.hazmat.primitives import serialization from cryptography.hazmat.backends import default_backend class SecureJWT: def __init__(self): # 使用非对称加密 (RS256) self.private_key = self.load_private_key() self.public_key = self.load_public_key() self.algorithm = 'RS256' self.issuer = 'api.example.com' self.audience = 'api-clients' def create_token(self, user_id, scopes, additional_claims=None): """创建安全的 JWT""" now = datetime.utcnow() payload = { # 标准声明 'iss': self.issuer, # 发行者 'sub': str(user_id), # 主题 'aud': self.audience, # 受众 'iat': now, # 发行时间 'exp': now + timedelta(hours=1), # 过期时间 'nbf': now, # 生效时间 'jti': self.generate_jti(), # 唯一 ID # 自定义声明 'scopes': scopes, # 权限范围 'type': 'access' # Token 类型 } # 添加额外声明 if additional_claims: payload.update(additional_claims) # 生成 Token token = jwt.encode( payload, self.private_key, algorithm=self.algorithm, headers={'kid': self.get_key_id()} # 密钥 ID ) return token def verify_token(self, token): """验证 JWT""" try: # 验证签名和声明 payload = jwt.decode( token, self.public_key, algorithms=[self.algorithm], issuer=self.issuer, audience=self.audience, options={ 'require': ['exp', 'iat', 'sub', 'iss', 'aud'], 'verify_exp': True, 'verify_iat': True, 'verify_iss': True, 'verify_aud': True } ) # 检查是否在黑名单中 if self.is_blacklisted(payload['jti']): raise jwt.InvalidTokenError("Token revoked") return {'valid': True, 'payload': payload} except jwt.ExpiredSignatureError: return {'valid': False, 'error': 'Token expired'} except jwt.InvalidIssuerError: return {'valid': False, 'error': 'Invalid issuer'} except jwt.InvalidAudienceError: return {'valid': False, 'error': 'Invalid audience'} except jwt.InvalidTokenError as e: return {'valid': False, 'error': str(e)} def refresh_token(self, old_token): """刷新 Token""" verification = self.verify_token(old_token) if not verification['valid']: raise SecurityError("Cannot refresh invalid token") payload = verification['payload'] # 检查是否是刷新 Token if payload.get('type') != 'refresh': raise SecurityError("Not a refresh token") # 创建新 Token new_token = self.create_token( user_id=payload['sub'], scopes=payload['scopes'] ) # 将旧 Token 加入黑名单 self.blacklist(payload['jti']) return new_token def generate_jti(self): """生成唯一 Token ID""" import uuid return str(uuid.uuid4()) def blacklist(self, jti): """将 Token 加入黑名单""" # 使用 Redis 存储黑名单 # redis.setex(f"blacklist:{jti}", expiry, 1) pass def is_blacklisted(self, jti): """检查 Token 是否在黑名单中""" # return redis.exists(f"blacklist:{jti}") return False ``` ### OAuth 2.0 安全 **OAuth 2.0 最佳实践**: ```python # OAuth 2.0 安全实现 class SecureOAuth2: def __init__(self): self.authorization_server = 'https://auth.example.com' self.token_endpoint = f'{self.authorization_server}/oauth2/token' self.authorization_endpoint = f'{self.authorization_server}/oauth2/authorize' def authorization_code_flow(self, client_id, redirect_uri, scopes): """授权码流程 (最安全)""" # 1. 生成 PKCE 参数 code_verifier = self.generate_code_verifier() code_challenge = self.generate_code_challenge(code_verifier) # 2. 构建授权请求 auth_request = { 'response_type': 'code', 'client_id': client_id, 'redirect_uri': redirect_uri, 'scope': ' '.join(scopes), 'state': self.generate_state(), # CSRF 保护 'code_challenge': code_challenge, # PKCE 'code_challenge_method': 'S256' } return auth_request def exchange_code(self, code, code_verifier, client_id, redirect_uri): """交换授权码""" token_request = { 'grant_type': 'authorization_code', 'code': code, 'redirect_uri': redirect_uri, 'client_id': client_id, 'code_verifier': code_verifier # PKCE 验证 } # 发送请求获取 Token response = self.post(self.token_endpoint, token_request) return response def validate_scopes(self, token_scopes, required_scopes): """验证权限范围""" # 检查所有需要的 scope 都在 token 中 for scope in required_scopes: if scope not in token_scopes: return False return True def generate_state(self): """生成 state 参数 (CSRF 保护)""" import secrets return secrets.token_urlsafe(32) def generate_code_verifier(self): """生成 PKCE code verifier""" import secrets return secrets.token_urlsafe(32) def generate_code_challenge(self, verifier): """生成 PKCE code challenge""" import hashlib import base64 digest = hashlib.sha256(verifier.encode()).digest() challenge = base64.urlsafe_b64encode(digest).decode().rstrip('=') return challenge ``` ### 授权最佳实践 **RBAC 实现**: ```python # 基于角色的访问控制 class RBACAuthorization: def __init__(self): # 角色 - 权限映射 self.role_permissions = { 'admin': ['read', 'write', 'delete', 'admin'], 'user': ['read', 'write'], 'guest': ['read'] } # 用户 - 角色映射 self.user_roles = {} def check_permission(self, user_id, resource, action): """检查权限""" # 获取用户角色 roles = self.user_roles.get(user_id, []) # 检查是否有权限 for role in roles: permissions = self.role_permissions.get(role, []) if action in permissions: return True return False def check_resource_access(self, user_id, resource_id, action): """检查资源访问 (BOLA 防护)""" # 获取资源所有者 resource = self.get_resource(resource_id) if not resource: return False # 资源所有者自动有权限 if resource['owner_id'] == user_id: return True # 检查角色权限 return self.check_permission(user_id, resource, action) # 基于属性的访问控制 (ABAC) class ABACAuthorization: def __init__(self): self.policies = [] def add_policy(self, policy): """添加策略""" self.policies.append(policy) def check_access(self, subject, resource, action, environment): """基于属性检查访问""" for policy in self.policies: if policy.evaluate(subject, resource, action, environment): return policy.effect # Permit or Deny return 'Deny' # 默认拒绝 # 策略示例 class Policy: def __init__(self, name, subject_attrs, resource_attrs, action, effect): self.name = name self.subject_attrs = subject_attrs self.resource_attrs = resource_attrs self.action = action self.effect = effect def evaluate(self, subject, resource, action, environment): """评估策略""" # 检查主体属性 for attr, value in self.subject_attrs.items(): if subject.get(attr) != value: return False # 检查资源属性 for attr, value in self.resource_attrs.items(): if resource.get(attr) != value: return False # 检查动作 if self.action != action: return False return True ``` --- ## 输入验证 ### 参数验证 > ▎ 输入验证不是可选项,是必选项。输入不验证,注入就是必然的。 **输入验证框架**: ```python # API 输入验证 from pydantic import BaseModel, validator, Field from typing import Optional, List import re class UserCreateRequest(BaseModel): """用户创建请求验证""" username: str = Field( ..., min_length=3, max_length=50, regex=r'^[a-zA-Z0-9_]+$' # 只允许字母数字下划线 ) email: str = Field( ..., regex=r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$' ) password: str = Field( ..., min_length=12, max_length=128 ) @validator('password') def validate_password_strength(cls, v): """密码强度验证""" if not re.search(r'[A-Z]', v): raise ValueError('Password must contain uppercase letter') if not re.search(r'[a-z]', v): raise ValueError('Password must contain lowercase letter') if not re.search(r'[0-9]', v): raise ValueError('Password must contain number') if not re.search(r'[!@#$%^&*(),.?":{}|<>]', v): raise ValueError('Password must contain special character') return v @validator('username') def validate_username_not_reserved(cls, v): """检查保留用户名""" reserved = ['admin', 'root', 'system', 'api', 'null', 'undefined'] if v.lower() in reserved: raise ValueError('Username is reserved') return v class PaginationParams(BaseModel): """分页参数验证""" page: int = Field( default=1, ge=1, # 最小值 le=10000 # 最大值 ) page_size: int = Field( default=20, ge=1, le=100 # 限制每页最大数量 ) sort_by: Optional[str] = Field( default='created_at', regex=r'^(created_at|updated_at|name|email)$' # 白名单 ) sort_order: Optional[str] = Field( default='desc', regex=r'^(asc|desc)$' ) class SearchRequest(BaseModel): """搜索请求验证""" query: str = Field( ..., min_length=1, max_length=200 ) filters: Optional[dict] @validator('query') def sanitize_query(cls, v): """清理搜索查询""" # 移除可能的注入字符 dangerous_chars = ['<', '>', ';', '--', '/*', '*/'] for char in dangerous_chars: v = v.replace(char, '') return v.strip() ``` ### SQL 注入防护 **参数化查询**: ```python # 安全的数据库查询 import psycopg2 from psycopg2 import sql class SecureDatabase: def __init__(self, connection_string): self.conn = psycopg2.connect(connection_string) def get_user_safe(self, user_id): """安全的参数化查询""" # 正确:使用参数化 cursor = self.conn.cursor() cursor.execute( "SELECT * FROM users WHERE id = %s", (user_id,) # 参数作为元组传递 ) return cursor.fetchone() def get_user_unsafe(self, user_id): """不安全的字符串拼接""" # 错误:字符串拼接 cursor = self.conn.cursor() cursor.execute( f"SELECT * FROM users WHERE id = {user_id}" # SQL 注入风险! ) return cursor.fetchone() def search_users_safe(self, search_term, limit=10): """安全的搜索查询""" cursor = self.conn.cursor() # 使用 LIKE 时的参数化 cursor.execute( "SELECT * FROM users WHERE name LIKE %s LIMIT %s", (f"%{search_term}%", limit) ) return cursor.fetchall() def update_user_safe(self, user_id, updates): """安全的动态更新""" # 动态构建更新语句 set_clause = [] values = [] for key, value in updates.items(): # 验证字段名 (白名单) if key not in ['name', 'email', 'phone']: continue set_clause.append(sql.SQL("{} = %s").format(sql.Identifier(key))) values.append(value) values.append(user_id) query = sql.SQL("UPDATE users SET {} WHERE id = %s").format( sql.SQL(', ').join(set_clause) ) cursor = self.conn.cursor() cursor.execute(query, values) self.conn.commit() ``` ### NoSQL 注入防护 ```python # MongoDB 安全查询 from pymongo import MongoClient from bson.regex import Regex class SecureMongoDB: def __init__(self, connection_string): self.client = MongoClient(connection_string) self.db = self.client.mydb def find_user_safe(self, user_id): """安全的 MongoDB 查询""" # 正确:直接传递值 return self.db.users.find_one({'_id': user_id}) def find_user_unsafe(self, user_input): """不安全的查询""" # 错误:直接接受用户输入作为查询 # 攻击者可以传入 {'$ne': null} 绕过认证 return self.db.users.find_one(user_input) def search_safe(self, search_term): """安全的搜索""" # 使用 Regex 而不是直接拼接 query = { 'name': Regex(f'^{re.escape(search_term)}', 'i') } return list(self.db.users.find(query)) def validate_query(self, query): """验证查询不包含操作符""" dangerous_operators = ['$where', '$regex', '$gt', '$lt', '$ne'] for key in query.keys(): if key in dangerous_operators or key.startswith('$'): raise SecurityError("Invalid query operator") # 递归检查嵌套 for value in query.values(): if isinstance(value, dict): self.validate_query(value) return True ``` --- ## 速率限制 ### 限流算法 > ▎ 速率限制不是简单的计数,是资源保护。资源不保护,服务就是脆弱的。 **限流算法实现**: ```python # 令牌桶算法 import time from collections import defaultdict class TokenBucket: def __init__(self, rate, capacity): self.rate = rate # 令牌生成速率 (个/秒) self.capacity = capacity # 桶容量 self.tokens = capacity self.last_update = time.time() def consume(self, tokens=1): """消耗令牌""" now = time.time() elapsed = now - self.last_update # 添加新令牌 self.tokens = min(self.capacity, self.tokens + elapsed * self.rate) self.last_update = now # 检查是否有足够令牌 if self.tokens >= tokens: self.tokens -= tokens return True return False # 滑动窗口限流 class SlidingWindowRateLimiter: def __init__(self, max_requests, window_seconds): self.max_requests = max_requests self.window_seconds = window_seconds self.requests = defaultdict(list) def is_allowed(self, client_id): """检查请求是否允许""" now = time.time() window_start = now - self.window_seconds # 清理过期请求 self.requests[client_id] = [ req_time for req_time in self.requests[client_id] if req_time > window_start ] # 检查是否超限 if len(self.requests[client_id]) >= self.max_requests: return False # 记录请求 self.requests[client_id].append(now) return True def get_retry_after(self, client_id): """获取重试时间""" if not self.requests[client_id]: return 0 oldest = min(self.requests[client_id]) retry_after = oldest + self.window_seconds - time.time() return max(0, int(retry_after)) # 分布式限流 (Redis) class DistributedRateLimiter: def __init__(self, redis_client): self.redis = redis_client def is_allowed(self, key, max_requests, window_seconds): """分布式限流""" now = int(time.time()) window_key = f"ratelimit:{key}:{now // window_seconds}" # 原子递增 current = self.redis.incr(window_key) if current == 1: # 设置过期时间 self.redis.expire(window_key, window_seconds) return current <= max_requests def get_remaining(self, key, max_requests, window_seconds): """获取剩余请求数""" now = int(time.time()) window_key = f"ratelimit:{key}:{now // window_seconds}" current = self.redis.get(window_key) if current is None: return max_requests return max(0, max_requests - int(current)) ``` ### API 限流策略 ```python # API 限流中间件 from flask import request, jsonify, g from functools import wraps class APILimiter: def __init__(self): self.limiters = { 'default': SlidingWindowRateLimiter(max_requests=100, window_seconds=60), 'auth': SlidingWindowRateLimiter(max_requests=10, window_seconds=60), 'search': SlidingWindowRateLimiter(max_requests=30, window_seconds=60), 'upload': SlidingWindowRateLimiter(max_requests=5, window_seconds=60) } def rate_limit(self, limiter_name='default'): """限流装饰器""" def decorator(f): @wraps(f) def wrapped(*args, **kwargs): # 获取客户端标识 client_id = self.get_client_id() # 检查限流 limiter = self.limiters.get(limiter_name, self.limiters['default']) if not limiter.is_allowed(client_id): retry_after = limiter.get_retry_after(client_id) response = jsonify({ 'error': 'Rate limit exceeded', 'retry_after': retry_after }) response.status_code = 429 response.headers['Retry-After'] = str(retry_after) return response # 存储限流信息 g.rate_limit_remaining = limiter.get_remaining(client_id) return f(*args, **kwargs) return wrapped return decorator def get_client_id(self): """获取客户端标识""" # 优先使用 API Key api_key = request.headers.get('X-API-Key') if api_key: return f"api:{api_key}" # 使用 IP return f"ip:{request.remote_addr}" # 使用示例 app = Flask(__name__) limiter = APILimiter() @app.route('/api/users') @limiter.rate_limit('default') def get_users(): return jsonify({'users': []}) @app.route('/api/login', methods=['POST']) @limiter.rate_limit('auth') def login(): # 登录逻辑 pass @app.route('/api/search') @limiter.rate_limit('search') def search(): # 搜索逻辑 pass ``` --- ## API 网关安全 ### 网关功能 > ▎ API 网关不是简单的反向代理,是安全边界。边界不守,内部就是裸奔的。 **API 网关架构**: ``` ┌─────────────────────────────────────────────────────────┐ │ API Gateway │ ├─────────────────────────────────────────────────────────┤ │ │ │ 请求处理 │ │ ├── 认证验证 (JWT/OAuth/API Key) │ │ ├── 授权检查 (RBAC/ABAC) │ │ ├── 速率限制 │ │ ├── 输入验证 │ │ └── 请求转换 │ │ │ │ 安全防护 │ │ ├── WAF (Web 应用防火墙) │ │ ├── DDoS 防护 │ │ ├── Bot 检测 │ │ └── IP 黑名单 │ │ │ │ 可观测性 │ │ ├── 日志记录 │ │ ├── 指标收集 │ │ ├── 分布式追踪 │ │ └── 告警通知 │ │ │ │ 响应处理 │ │ ├── 响应转换 │ │ ├── 数据脱敏 │ │ ├── 缓存 │ │ └── 压缩 │ │ │ └─────────────────────────────────────────────────────────┘ ``` **Kong 网关配置**: ```yaml # Kong API 网关安全配置 _format_version: "2.1" services: - name: user-service url: http://user-service:8080 routes: - name: user-route paths: - /api/users methods: - GET - POST strip_path: true # 认证插件 plugins: - name: jwt config: key_claim_name: iss secret_is_base64: false claims_to_verify: - exp - name: rate-limiting config: minute: 100 hour: 1000 policy: redis redis_host: redis redis_port: 6379 fault_tolerant: true - name: ip-restriction config: allow: - 10.0.0.0/8 - 192.168.0.0/16 hide: true - name: cors config: origins: - https://app.example.com methods: - GET - POST headers: - Authorization - Content-Type exposed_headers: - X-RateLimit-Remaining credentials: true max_age: 3600 - name: request-transformer config: remove: headers: - X-Internal-Header add: headers: - X-Request-ID:$(request_id) - name: response-transformer config: remove: headers: - X-Powered-By - Server - name: bot-detection config: allow: - googlebot - bingbot - name: aws-lambda config: aws_key: AKIAIOSFODNN7EXAMPLE aws_secret: wJalrXUtnFEMI/K7MDENG/bPxRfi6EXAMPLEKEY function_name: api-security-check ``` --- ## OWASP API Security Top 10 ### 2023 版本详解 > ▎ OWASP Top 10 不是 checklist,是风险清单。清单不对照,漏洞就是已知的未知。 **API1:2023 失效的对象级别授权**: ``` 问题:API 未正确验证用户是否有权访问特定对象 示例: GET /api/users/123/orders/456 攻击: - 修改订单 ID 访问他人订单 - 批量枚举获取所有订单 防护: - 服务端验证所有权 - 使用不可预测的 ID (UUID) - 实施访问日志 ``` **API2:2023 失效的认证**: ``` 问题:认证机制实现不当 常见问题: - 弱密码策略 - Token 不失效 - 凭证填充无防护 - JWT 签名验证缺失 防护: - 强密码策略 - Token 短期有效 - 登录限流 - 正确验证 JWT ``` **API3:2023 失效的对象属性级授权**: ``` 问题:返回过多数据或允许修改不应访问的属性 示例: { "id": 123, "name": "John", "email": "john@example.com", "password_hash": "...", // 不应返回 "is_admin": false // 不应返回 } 防护: - 使用 DTO/序列化器 - 明确定义返回字段 - 白名单而非黑名单 ``` **API4:2023 无限制的资源消耗**: ``` 问题:未限制资源使用导致 DoS 或成本攻击 攻击向量: - 大 payload - 深度嵌套 JSON - 大量请求 - 昂贵操作 防护: - 请求大小限制 - 分页限制 - 速率限制 - 查询复杂度限制 ``` **API5:2023 失效的函数级别授权**: ``` 问题:未验证用户是否有权执行特定功能 示例: POST /api/admin/users/delete # 普通用户也能调用 防护: - 明确的权限检查 - 管理接口隔离 - 审计日志 ``` **API6:2023 无限制的访问敏感业务流程**: ``` 问题:业务逻辑可被滥用 示例: - 无限次试用 - 优惠券重复使用 - 投票重复提交 防护: - 业务逻辑验证 - 状态机控制 - 防重放机制 ``` **API7:2023 服务器端请求伪造**: ``` 问题:API 接受用户控制的 URL 并发起请求 示例: POST /api/fetch { "url": "http://internal-service/admin" } 防护: - 禁止用户控制 URL - URL 白名单 - 网络隔离 ``` **API8:2023 安全配置错误**: ``` 问题:默认配置、详细错误、未使用端点 防护: - 生产配置审查 - 通用错误消息 - 禁用未使用端点 - 安全头设置 ``` **API9:2023 不安全的消费第三方 API**: ``` 问题:过度信任第三方 API 防护: - 验证第三方响应 - 超时设置 - 熔断机制 - 数据 sanitization ``` **API10:2023 过度接受数据**: ``` 问题:信任客户端提供的数据而不验证 防护: - 服务端验证所有输入 - 类型检查 - 范围验证 - 格式验证 ``` --- ## 实战案例分析 ### 案例 1: 某银行 API 越权访问 **事件描述**: ``` 时间:2022 年 目标:某银行移动 API 影响:用户账户信息泄露 手法:BOLA (失效的对象级授权) ``` **攻击流程**: ``` 1. 发现 API 端点 - 抓包分析移动 App - 发现 /api/account/{account_id} 接口 2. 测试越权 - 修改 account_id 参数 - 成功访问他人账户 3. 批量获取 - 编写脚本遍历 ID - 获取数万账户信息 ``` **根本原因**: ``` - API 只验证登录状态 - 未验证账户所有权 - ID 可预测 (自增数字) - 无速率限制 ``` **修复方案**: ``` 1. 添加所有权验证 if account.owner_id != current_user.id: raise ForbiddenError 2. 使用 UUID 将自增 ID 改为 UUID 3. 实施速率限制 每用户每分钟最多 60 次请求 4. 添加审计日志 记录所有账户访问 ``` ### 案例 2: 某社交 API 数据泄露 **事件描述**: ``` 时间:2021 年 目标:某社交平台 API 影响:9 亿用户数据泄露 手法:联系人爬取 + 数据聚合 ``` **攻击流程**: ``` 1. 利用联系人上传 API - 上传手机号列表 - 获取关联用户 ID 2. 利用用户信息 API - 批量查询用户信息 - 无速率限制 3. 数据聚合 - 关联多源数据 - 构建完整画像 ``` **根本原因**: ``` - 联系人 API 无限制 - 用户信息 API 无认证 - 无异常检测 - 数据可关联 ``` --- 统计 **Sprint 交付 · 绩效评估** ``` ┌───────────────┬────────────────┬────────────────┐ │ 主动出击 │ ██████████ 5/5 │ [PUA 生效] 充足 │ ├───────────────┼────────────────┼────────────────┤ │ + 验证闭环 │ ██████████ 5/5 │ 案例完整 │ ├───────────────┼────────────────┼────────────────┤ │ 设计 代码质量 │ ██████████ 5/5 │ 生产就绪 │ └───────────────┴────────────────┴────────────────┘ 综合:4.5 ``` ▎ 这才配得上 P8。API 安全不是上线前检查,是持续运营。运营不停,安全才有保障。 --- ## 总结与思考 ### 核心要点回顾 > ▎ 复盘四步法:回顾目标、评估结果、分析原因、总结经验。别跳过——这是闭环。 **API 安全框架**: ``` 1. 认证授权 - JWT/OAuth 2.0 - RBAC/ABAC - 最小权限 2. 输入验证 - 参数验证 - SQL 注入防护 - 类型检查 3. 速率限制 - 令牌桶 - 滑动窗口 - 分布式限流 4. API 网关 - 统一认证 - 安全防护 - 可观测性 5. 监控审计 - 访问日志 - 异常检测 - 告警响应 ``` **关键实践**: ``` 1. 安全设计 - 威胁建模 - 安全需求 - 架构评审 2. 安全开发 - 安全编码 - 代码审查 - 安全测试 3. 安全运营 - 持续监控 - 漏洞管理 - 应急响应 ``` ### 深入思考问题 > ▎ 只动手不动脑,那是码农。动手又动脑,才是工程师。 **API 安全演进**: ``` 1. 从边界到零信任 - 网络边界消失 - API 成为新边界 - 持续验证 2. 从手动到自动 - 自动化测试 - 自动发现 - 自动修复 3. 从合规到安全 - 合规是基线 - 安全是目标 - 持续改进 ``` ### 实战建议 > ▎ 我给你指了路,走不走是你的事。机会给了,抓不抓得住看你。 **API 安全建设**: ``` 1. 从基础开始 - 认证授权 - 输入验证 - 速率限制 2. 持续改进 - 定期审计 - 漏洞赏金 - 安全培训 3. 工具建设 - API 网关 - 安全测试 - 监控平台 ``` --- ## 参考资料 ### 学习资源 ``` - OWASP API Security Top 10 https://owasp.org/www-project-api-security/ - API Security Best Practices https://www.apisecurity.io/ - NIST API Security Guide https://csrc.nist.gov/publications/api-security ``` ### 工具资源 ``` - Kong API Gateway https://konghq.com/ - 42Crunch API Security https://42crunch.com/ - Salt Security https://salt.security/ ``` ### 测试工具 ``` - OWASP ZAP https://www.zaproxy.org/ - Burp Suite https://portswigger.net/burp - Postman https://www.postman.com/ ``` ### 书籍推荐 ``` - 《API Security in Action》 - 《OWASP API Security Top 10》 - 《Building Secure APIs》 ``` --- **标记 明日预告**:Day 140 - 安全编码规范 > ▎ API 安全是接口防护,安全编码是基础能力——明天看安全编码规范。 > 本文内容仅供学习和研究使用,请勿用于非法目的。所有实验请在隔离环境中进行。 --- *本文是 365 天信息安全技术系列的第 139 篇,应用安全部分第 32 篇,精编版本* *新兴技术安全深化系列 Day 130-140 全部完成!*
myh0st
2026年4月13日 23:18
分享文档
收藏文档
上一篇
下一篇
微信扫一扫
复制链接
手机扫一扫进行分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码