API安全Skill api-security

API安全技能专注于实现API认证、授权和保护,涵盖OAuth 2.0、OIDC、JWT、API密钥管理、速率限制及常见安全漏洞防护。关键词:API安全, 认证, 授权, OAuth, JWT, 安全漏洞, 速率限制, API密钥。

身份认证 0 次安装 0 次浏览 更新于 3/11/2026

名称: api-security 描述: 用于实现API认证、授权或安全模式时使用。涵盖OAuth 2.0、OIDC、JWT、API密钥、速率限制和常见API安全漏洞。 允许工具: Read, Glob, Grep

API安全

API安全的全面指南 - 认证、授权和常见漏洞防护。

何时使用此技能

  • 实现API认证(OAuth、OIDC、JWT)
  • 设计API授权模型
  • 保护API端点
  • 理解API安全漏洞
  • 实现速率限制和滥用防护
  • API密钥管理

认证模式

OAuth 2.0流程

OAuth 2.0授权类型:

1. 授权码(带PKCE)
   └── 最适合:Web应用、移动应用、SPA
   └── 用户认证最安全

   用户 ──► 认证服务器 ──► 授权码 ──► 令牌

2. 客户端凭证
   └── 最适合:服务到服务(M2M)
   └── 无用户上下文,服务器到服务器

   服务 ──► 认证服务器 ──► 访问令牌

3. 设备授权(设备流程)
   └── 最适合:智能电视、物联网、输入受限设备
   └── 用户在单独设备上授权

   设备 ──► 显示代码 ──► 用户在手机上输入 ──► 令牌

已弃用(避免使用):
- 隐式流程(安全问题)
- 资源所有者密码凭证(反模式)

授权码流程带PKCE

┌──────────┐                              ┌───────────────┐
│  客户端  │                              │  认证服务器  │
└────┬─────┘                              └───────┬───────┘
     │                                            │
     │  1. 生成code_verifier(随机)              │
     │  2. 计算code_challenge = SHA256(verifier)
     │                                            │
     │──3. 授权请求 ───────────────►│
     │     (client_id, redirect_uri,             │
     │      code_challenge, challenge_method)     │
     │                                            │
     │◄──4. 授权码 ──────────────────│
     │     (用户认证/同意后)         │
     │                                            │
     │──5. 令牌请求 ───────────────────────►│
     │     (code, code_verifier)                 │
     │                                            │
     │◄──6. 访问令牌 + 刷新令牌 ────────│
     │                                            │

为什么使用PKCE?
- 防止授权码拦截攻击
- 移动应用和SPA必需
- 推荐用于所有OAuth流程

OpenID Connect (OIDC)

OIDC = OAuth 2.0 + 身份层

OIDC添加:
├── ID令牌(带用户声明的JWT)
├── UserInfo端点
├── 标准化声明(sub, name, email等)
└── 发现和元数据

令牌类型:
┌─────────────────────────────────────────────────┐
│ ID令牌                                        │
│ - 用户身份(他们是谁)                  │
│ - 包含认证相关的声明                  │
│ - 供客户端消费                     │
├─────────────────────────────────────────────────┤
│ 访问令牌                                    │
│ - 授权(他们能做什么)              │
│ - 供API/资源服务器验证       │
│ - 不应由客户端解析                │
├─────────────────────────────────────────────────┤
│ 刷新令牌                                   │
│ - 长期凭证                         │
│ - 用于获取新访问令牌              │
│ - 安全存储,绝不暴露到浏览器       │
└─────────────────────────────────────────────────┘

JWT(JSON Web令牌)

JWT结构:

头部.载荷.签名

头部(Base64URL):
{
  "alg": "RS256",     // 算法
  "typ": "JWT",       // 类型
  "kid": "key-123"    // 密钥ID用于轮换
}

载荷(Base64URL):
{
  "iss": "https://auth.example.com",  // 颁发者
  "sub": "user-12345",                 // 主体
  "aud": "https://api.example.com",   // 受众
  "exp": 1735689600,                   // 过期时间
  "iat": 1735686000,                   // 颁发时间
  "scope": "read write"                // 范围/权限
}

签名:
RSASHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  私钥
)

JWT验证

JWT验证清单:

1. 签名验证
   □ 使用正确公钥验证(来自JWKS)
   □ 如果签名无效则拒绝

2. 声明验证
   □ iss(颁发者):匹配预期颁发者
   □ aud(受众):包含你的API标识符
   □ exp(过期时间):令牌未过期
   □ iat(颁发时间):未在未来颁发
   □ nbf(不早于):令牌已激活

3. 额外检查
   □ 令牌不在撤销列表中(如适用)
   □ 必需范围存在
   □ 令牌类型是access_token(非id_token)

常见错误:
❌ 信任"alg": "none"
❌ 未验证受众
❌ 对公共API使用对称密钥
❌ 在JWT载荷中存储敏感数据

授权模式

基于角色的访问控制(RBAC)

RBAC模型:

用户 ──► 角色 ──► 权限

示例:
┌──────────────────────────────────────┐
│ 角色:编辑器                         │
├──────────────────────────────────────┤
│ 权限:                         │
│ - articles:read                      │
│ - articles:create                    │
│ - articles:update                    │
│ - comments:moderate                  │
└──────────────────────────────────────┘

API实现:
GET /articles        ← 需要:articles:read
POST /articles       ← 需要:articles:create
PUT /articles/{id}   ← 需要:articles:update
DELETE /articles/{id} ← 需要:articles:delete

令牌包含:
{
  "scope": "articles:read articles:create articles:update"
}

基于属性的访问控制(ABAC)

ABAC模型:

访问 = f(主体, 资源, 操作, 环境)

主体属性:
- 角色、部门、安全级别
- 用户ID、组成员资格

资源属性:
- 所有者、分类、类型
- 创建日期、敏感性

操作属性:
- 读、写、删除、批准

环境属性:
- 时间、IP地址、设备类型

示例策略:
"允许如果 user.department == resource.department
 AND user.role == 'manager'
 AND action == 'approve'
 AND environment.time.isBusinessHours"

基于资源的授权

在资源级别检查所有权/访问:

GET /documents/{id}

授权检查:
1. 验证令牌(认证)
2. 从令牌提取用户
3. 查询:此用户可以访问此文档吗?
   - 用户是所有者吗?
   - 用户有显式权限吗?
   - 文档在用户可访问的共享文件夹中吗?
   - 用户在有权访问的组中吗?
4. 如果未授权返回403

实现模式:
async function authorize(userId, resourceId, action) {
  // 检查直接所有权
  if (await isOwner(userId, resourceId)) return true;

  // 检查显式权限
  if (await hasPermission(userId, resourceId, action)) return true;

  // 检查组权限
  if (await hasGroupPermission(userId, resourceId, action)) return true;

  return false;
}

API密钥安全

API密钥最佳实践

API密钥设计:

格式:前缀_随机字节
示例:sk_live_a1b2c3d4e5f6...

前缀好处:
- sk_ = 秘密密钥(仅服务器端)
- pk_ = 公共密钥(可暴露)
- test_ = 测试环境
- live_ = 生产环境

安全要求:
□ 足够熵(32+字节随机)
□ 安全存储(哈希化,非明文)
□ 范围化权限(非全有或全无)
□ 轮换能力
□ 审计日志
□ 每密钥速率限制

API密钥 vs OAuth

何时使用各自:

API密钥:
✓ 服务到服务集成
✓ 简单用例
✓ 面向开发者的API
✓ 无状态、简单认证
✗ 不适合用户上下文
✗ 难以实时撤销

OAuth 2.0:
✓ 用户委派访问
✓ 细粒度范围
✓ 短期令牌
✓ 撤销支持
✓ 标准合规
✗ 实现更复杂
✗ 需要认证服务器

常见漏洞

OWASP API安全前10

1. 对象级别授权破坏(BOLA)
   问题:通过更改ID访问其他用户资源
   修复:始终验证用户对特定资源的访问权限

   ❌ GET /users/123/orders(任何用户可更改123)
   ✓ 验证请求用户能访问用户123的订单

2. 认证破坏
   问题:弱认证机制
   修复:使用成熟认证协议,正确实现

   ❌ 自定义令牌方案、弱密码
   ✓ OAuth 2.0/OIDC带MFA

3. 对象属性级别授权破坏
   问题:暴露敏感属性
   修复:基于授权过滤响应

   ❌ 在API响应中返回user.password_hash
   ✓ 显式选择返回字段

4. 无限制资源消耗
   问题:对请求/数据无限制
   修复:速率限制、分页、资源配额

   ❌ GET /users返回1000万条记录
   ✓ 分页、查询限制、速率限制

5. 功能级别授权破坏
   问题:端点缺少授权
   修复:验证每个功能的授权

   ❌ 管理端点对普通用户可访问
   ✓ 所有端点进行角色检查

6. 对敏感业务流程无限制访问
   问题:业务逻辑滥用
   修复:检测和限制滥用模式

   ❌ 无限制密码重置尝试
   ✓ 敏感流程速率限制 + CAPTCHA

7. 服务器端请求伪造(SSRF)
   问题:API获取攻击者控制URL
   修复:验证和清理URL,允许列表

   ❌ POST /fetch { "url": "http://internal-service" }
   ✓ 根据允许列表验证,阻止内部IP

8. 安全配置错误
   问题:默认配置、暴露错误
   修复:强化配置、最小化错误

   ❌ 生产环境中详细堆栈跟踪
   ✓ 通用错误消息、正确头信息

9. 不当库存管理
   问题:未跟踪API版本、影子API
   修复:API库存、版本管理

   ❌ 旧API版本仍可访问
   ✓ 库存、生命周期管理、弃用

10. API不安全消费
    问题:信任第三方API响应
    修复:验证所有外部数据

     ❌ 直接使用第三方响应数据
     ✓ 验证、清理、视为不可信

输入验证

验证层:

1. 语法验证
   - 是有效JSON/XML吗?
   - 必需字段存在吗?
   - 字段类型正确吗?

2. 语义验证
   - 邮箱格式有效吗?
   - 日期在有效范围吗?
   - ID引用存在吗?

3. 业务规则验证
   - 数量在限制内吗?
   - 用户对此操作授权吗?
   - 状态转换合理吗?

验证模式:
- 允许列表优于阻止列表
- 在输入和输出上验证
- 安全失败并清晰错误
- 记录验证失败用于监控

传输安全

TLS要求

TLS配置:

最低:TLS 1.2
优选:TLS 1.3

必需设置:
□ 仅强密码套件
□ 完美前向保密(ECDHE)
□ 来自可信CA的有效证书
□ 启用HSTS头
□ 证书透明度

头信息:
Strict-Transport-Security: max-age=31536000; includeSubDomains

证书固定

证书固定(移动/嵌入式):

目的:即使CA受损也能防止MITM攻击

选项:
1. 固定证书
   - 证书轮换需要更新

2. 固定公钥
   - 证书续订后仍有效
   - 更灵活

3. 固定中间CA
   - 安全性和灵活性的平衡

考虑:
- 总有备用固定
- 计划轮换
- 优雅处理失败
- 考虑使用动态固定

速率限制和滥用防护

速率限制策略:

按身份:
- 每API密钥
- 每用户ID
- 每客户端ID

按资源:
- 每端点
- 每操作类型
- 每资源ID

头信息(草案标准):
RateLimit-Limit: 100
RateLimit-Remaining: 95
RateLimit-Reset: 1735689600
Retry-After: 60

响应码:
429 请求过多 - 速率限制超出
503 服务不可用 - 服务器过载

滥用防护:
□ 速率限制
□ 请求大小限制
□ 敏感操作CAPTCHA
□ 行为分析
□ IP声誉
□ 异常检测

安全头信息

基本API安全头信息:

# 防止MIME类型嗅探
X-Content-Type-Options: nosniff

# 控制敏感数据缓存
Cache-Control: no-store, private

# CORS配置(限制性)
Access-Control-Allow-Origin: https://trusted.example.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: Authorization, Content-Type

# 框架保护(如提供HTML)
X-Frame-Options: DENY

# 内容安全策略(如提供HTML)
Content-Security-Policy: default-src 'none'

相关技能

  • zero-trust-architecture - 整体安全架构
  • mtls-service-mesh - 服务到服务安全
  • rate-limiting-patterns - 详细速率限制策略
  • secrets-management - 管理API密钥和秘密