You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

无OpenAPI/Swagger规范时,OWASP ZAP的API认证、JWT复用及自动化扫描问题求助

我之前在纯API场景下用ZAP 2.9.0扫的时候,也踩过一模一样的坑——认证配置不对导致扫描没反应,JWT不会自动带,甚至连入口点都找不到。咱们一步步拆解解决:

一、先搞定API认证与JWT Token复用

你的核心问题是选错了认证方式,ZAP默认的表单认证是给带登录页面的Web应用设计的,纯API得用脚本式认证来主动调用登录接口拿Token:

  1. 精准配置Context范围
    先确认Session > Contexts > Default Context里的Include in Context规则是准确的,比如https?://your-real-host/.*,一定要勾选激活这个Context(左侧Contexts面板里打勾),不然ZAP不会识别目标API。

  2. 编写认证脚本获取JWT
    打开ZAP顶部菜单Tools > Scripts,右键ScriptsNew Script

    • 类型选Authentication Script,语言选ECMAScript
    • 粘贴下面的脚本(根据你的登录API格式调整请求体和Token提取逻辑):
      function authenticate(helper, paramsValues, credentials) {
          // 构造登录请求
          const loginReq = helper.prepareRequest();
          loginReq.setMethod("POST");
          loginReq.setHeader("Content-Type", "application/json");
          loginReq.setURI("https://your-real-host/login"); // 替换成你的登录接口路径
          
          // 用已添加的用户凭证构造请求体
          const loginBody = JSON.stringify({
              username: credentials.getParam("username"),
              password: credentials.getParam("password")
          });
          loginReq.setRequestBody(loginBody);
          
          // 发送请求并提取JWT
          const loginRes = helper.sendAndReceive(loginReq);
          const resBody = JSON.parse(loginRes.getResponseBody().toString());
          const jwtToken = resBody.token; // 假设返回的JSON里token字段是JWT
          
          // 把Token设为全局请求头,后续所有请求都会自动带上
          helper.getHttpSender().addGlobalHeader("Authorization", `Bearer ${jwtToken}`);
          
          return true; // 返回true表示认证成功
      }
      
    • 保存脚本,比如命名为api-jwt-auth.js
  3. 关联脚本到Context认证
    回到Session > Contexts > Default Context > Authentication

    • 认证方式选择刚才创建的脚本
    • 确保Users里添加的用户名密码是正确的,右键该用户选Set as Forced User
    • 确认Forced User Mode enabled是开启状态
  4. 测试认证有效性
    在ZAP的History面板里手动发送一个登录请求,或者用Quick Start栏输入登录API URL点击Attack,检查请求头里是否自动带上了Authorization: Bearer xxx

二、解决Active Scan无反应的问题

扫描没动静大概率是没有可扫描的入口点,纯API不像Web应用能自动爬取,得手动喂给ZAP路径:

  1. 导入你的JS测试用例生成入口点
    把JS测试用例里的HTTP请求转换成HAR文件(比如用Chrome开发者工具录制测试流程,导出HAR),然后在ZAP里File > Import HAR,ZAP会自动解析出所有API路径、查询参数和请求格式,作为扫描的基础。

  2. 手动补充入口点(可选)
    如果没有HAR,就在左侧Sites面板里右键目标主机,Add to Context把已知的API路径(比如/api/users/api/orders)添加进去。

  3. 关于Active Scan的疑问解答

    • 预期作用:主动模拟攻击者对每个路径发送恶意Payload,检测SQL注入、路径遍历、未授权访问等漏洞
    • 不需要手动提供所有路径,但需要初始入口点让ZAP扩展(纯API爬取能力弱,所以导入HAR是最高效的方式)
    • 查询参数会被ZAP自动识别,扫描时会针对参数做模糊测试
三、被动扫描的配置

被动扫描是监听ZAP代理的所有请求并自动分析漏洞,适合复用你的JS测试用例:

  1. 设置你的测试环境HTTP代理为localhost:8080(ZAP默认代理端口)
  2. 运行JS测试用例,所有请求都会经过ZAP并被记录到History,同时自动完成被动扫描,生成告警
  3. 导入HAR文件后,ZAP也会对导入的请求自动做被动扫描
四、导出配置为命令行脚本

ZAP支持把UI配置导出成命令行参数,或者用脚本自动化:

  1. 导出Context配置
    在ZAP里File > Export Context,保存为api-scan.context文件

  2. 命令行扫描示例(snap版本)

    zaproxy -cmd \
      -importhar "/home/your-user/Documents/api-test-cases.har" \
      -contextfile "/home/your-user/Documents/api-scan.context" \
      -script "/home/your-user/Documents/api-jwt-auth.js" \
      -forceduser \
      -activeScan \
      -report "/home/your-user/Documents/scan-report.html"
    

    注意:snap安装的ZAP对文件路径权限有限制,尽量把文件放在~/Documents这类允许访问的目录

  3. Python脚本自动化(可选)
    用ZAP的Python API编写更灵活的扫描脚本:

    import time
    from zapv2 import ZAPv2
    
    # 连接本地ZAP实例
    zap = ZAPv2(proxies={'http': 'http://localhost:8080', 'https': 'http://localhost:8080'})
    
    # 加载Context和设置强制用户
    zap.context.load_context('/home/your-user/Documents/api-scan.context')
    zap.users.set_forced_user('Default Context', 'your-username')
    zap.forcedUser.set_forced_user_mode_enabled(True)
    
    # 导入HAR测试用例
    zap.import_har('/home/your-user/Documents/api-test-cases.har')
    
    # 启动主动扫描
    scan_id = zap.ascan.scan('https://your-real-host/')
    # 等待扫描完成
    while int(zap.ascan.status(scan_id)) < 100:
        print(f"扫描进度: {zap.ascan.status(scan_id)}%")
        time.sleep(5)
    
    # 生成HTML报告
    with open('/home/your-user/Documents/scan-report.html', 'w') as f:
        f.write(zap.core.htmlreport())
    
额外注意事项(针对ZAP 2.9.0 snap版本)
  • 如果JWT有过期时间,可以在认证脚本里添加Token过期检测逻辑,过期自动重新获取
  • 扫描前关闭其他代理工具,避免端口冲突
  • 若出现文件权限错误,检查snap的权限设置,或者把文件放在~/Documents目录下

内容的提问来源于stack exchange,提问作者TPPZ

火山引擎 最新活动