SuperAPI AI 工具集

mishandling-exceptional-conditions

安全与审计

查看项目

更新于 10-16 02:25

技能介绍

用途

本技能用于检测、分析和修复 OWASP A10:2025「异常条件处理不当」(Mishandling of Exceptional Conditions),主要面向 Python Web 应用,覆盖 FastAPI 与 Flask 两个框架。该类别是 2025 年新增分类,取代了 SSRF(后者被并入 A01)。它包含 24 个 CWE,共记录 769,581 次出现。其针对的是那些未能预防、检测和响应异常情况的程序,这类问题会导致崩溃、意外行为、信息泄露以及可被利用的状态。

主要能力

技能围绕以下弱点与风险展开:

  • 错误处理不当:未处理的异常会使应用崩溃或暴露内部信息。
  • 失败开放(CWE-636):认证/授权检查在抛出异常时反而通过。
  • 错误消息中的敏感数据(CWE-209):堆栈跟踪、数据库细节、文件路径泄露给客户端。
  • 未捕获异常(CWE-248):没有全局安全网,导致带调试输出的 500 响应。
  • 异常路径中的资源耗尽:数据库连接、文件句柄在出错时从未关闭。
  • 状态损坏:异常时部分事务被提交。
  • NULL 指针 / None 解引用(CWE-476):在访问属性前缺少对 None 的防护。
  • 缺少默认分支(CWE-754):if/elif 链没有 else;match 没有通配分支。
  • 错误恢复中的竞态条件:清理逻辑本身可能被中断。

预防原则

  • 在错误发生处捕获:在能够处理它的函数处捕获,而不是向上三层。
  • 失败关闭:当认证/授权逻辑抛出异常时,拒绝访问,绝不放行。
  • 完整回滚:部分数据库事务必须回滚,绝不提交。
  • 用户消息与技术细节分离:在服务端记录堆栈跟踪,向客户端返回安全、通用的消息。
  • 全局异常处理器作为安全网:每个应用都需要一个,但它不能替代本地处理。
  • 限流与配额:防止异常情况(如资源耗尽)被有意触发。

使用方式

FastAPI 测试清单

  1. 全局异常处理器:注册 @app.exception_handler(Exception),记录日志并返回通用 500 消息。若缺失则标记。FastAPI 默认 500 响应在开发模式下可能包含 traceback。

  2. 失败关闭的认证中间件(CWE-636):在中间件中,若 verify_token 抛异常,BAD 写法是 except Exception: pass(失败开放),GOOD 写法是记录警告并返回 401(失败关闭)。

  3. 自定义 HTTP 错误响应(CWE-756 / CWE-209):为 404、422 等常见错误码注册处理器,返回通用消息。标记任何在响应体中返回 str(exc)、repr(exc) 或 traceback.format_exc() 的处理器。

  4. 异常路径中的资源清理:BAD 写法是 conn = db.connect() 后直接执行查询,异常时连接永不关闭;GOOD 写法是使用 with db.connect() as conn: 上下文管理器保证清理。扫描不在 with 块或 try/finally 中的 db.connect()、open(file)、socket.socket()。

  5. SQLAlchemy 事务回滚:BAD 写法是 session.add(obj) 后执行风险操作再 session.commit(),异常时部分写入被提交;GOOD 写法是在 try 中提交,在 except 中 session.rollback() 并重新抛出。标记任何未在 except 分支中配对 session.rollback() 的 session.commit()。

Flask 测试清单

  1. 全局异常处理器:注册 @app.errorhandler(Exception),记录日志并返回通用 500。同时注册 404、500 等具体处理器。

  2. Flask 调试模式(同时属于 A02 + A10 问题):debug=True 或 FLASK_DEBUG=1 会启用 Werkzeug 交互式调试器,向浏览器暴露完整 traceback,并允许通过调试器控制台执行任意代码。若在生产配置或环境变量中发现,立即标记。

  3. request.args.get() 静默返回 None:BAD 写法是直接使用可能为 None 的 user_id 查询,导致错误查询;GOOD 写法是显式校验,若为 None 则 abort(400)。FastAPI 的 Pydantic 模型可自动防止此问题,Flask 需要手动防护。

  4. 失败关闭的 before_request 钩子:BAD 写法是在认证检查中 except: pass,绕过保护;GOOD 写法是记录警告并 abort(401)。

自动化扫描方法

静态分析(Bandit):

bandit -r . -t B110,B112   # try-except-pass and try-except-continue
bandit -r . --severity-level medium

关键 Bandit 测试 ID:B110(try/except pass,吞掉异常)、B112(try/except continue,循环中吞掉异常)。

模式搜索(grep / ripgrep):

# Fail-open patterns
rg "except.*:\s*(pass|continue|return True)" --type py

# Stack traces leaking to response
rg "traceback\.format_exc\(\)|str\(exc\)|repr\(exc\)" --type py

# Missing context managers
rg "open\(|\.connect\(\)" --type py   # review each hit for 'with'

# Missing rollback
rg "session\.commit\(\)" --type py    # check each for paired rollback

运行时 / DAST:触发故意的 404、500 和校验错误(FastAPI 上为 422);检查 HTTP 响应中是否出现文件路径、堆栈帧、SQL 查询字符串、异常类名;发送格式错误的 Authorization 头探测中间件,验证响应是 401 而非 200。

关键 CWE(A10:2025)

  • CWE-209 错误消息中的敏感信息:Python 表现为 JSON 响应中的 str(exc)、调试 traceback。
  • CWE-248 未捕获异常:无全局处理器;未处理的 raise 使应用崩溃。
  • CWE-636 失败开放:认证检查中的 except: pass。
  • CWE-703 异常条件处理不当:宽泛的 except 隐藏错误。
  • CWE-754 异常条件检查不当:对外部输入缺少 None/空值检查。
  • CWE-476 NULL 指针解引用:对可能为 None 的对象访问属性。
  • CWE-756 缺少自定义错误页:带调试信息的默认框架错误页。

适用场景

适用于对 FastAPI 或 Flask 编写的 Python Web 应用进行安全审计、代码审查、静态扫描与运行时测试,尤其关注认证/授权逻辑、错误响应、事务处理、资源管理与调试配置。

限制

技能内容仅覆盖 FastAPI 与 Flask 的 Python 场景,未提供其他语言或框架的指导。资料未说明该技能的安装方式、收费模式、价格或平台信息,这些事实暂未提供。