Phy Session Audit

扫描源码中的10类会话管理漏洞,支持多框架,零依赖。

已扫描
适合谁
前端/后端开发工程师、安全测试人员
不适合谁
无代码或非技术用户、无需进行安全审计的简单静态项目
国内可用性
需网络配置。可能需要网络配置或第三方服务可访问。
安装难度
新手友好(★☆☆)。基于终端操作、依赖、API Key 和本地环境要求的初步判断。

安装与下载

openclaw skills install @phy041/phy-session-audit

Skill 说明

命令、参数、文件名以原文为准

phy-session-audit — 会话与 Cookie 安全审计工具

扫描源代码中的 10 种会话管理漏洞,这些漏洞可能导致会话劫持、CSRF 攻击、会话固定和账户接管。对应 OWASP A07:2021 — 身份识别与认证失败

快速开始

# 扫描目录
python session_audit.py ./src

# 单个文件
python session_audit.py src/middleware/session.js

# CI 模式 — 遇到 CRITICAL 或 HIGH 级别问题时退出码为 1
python session_audit.py ./src --ci

# 仅显示 CRITICAL 级别发现
python session_audit.py ./src --only-severity CRITICAL

10 项检查

ID严重性检查项CWE
SS001CRITICAL会话 Cookie 缺少 HttpOnly 标志CWE-1004
SS002HIGH会话 Cookie 缺少 Secure 标志CWE-614
SS003HIGH会话 Cookie 缺少 SameSite 属性CWE-352
SS004CRITICAL会话令牌 / 认证令牌出现在 URL 查询字符串中CWE-598
SS005CRITICAL登录后未重新生成会话 ID(会话固定)CWE-384
SS006HIGH状态变更路由缺少 CSRF 保护CWE-352
SS007HIGH会话/认证数据存储在 localStorage 中CWE-922
SS008MEDIUM未配置会话超时时间(会话无限期有效)CWE-613
SS009MEDIUM会话 ID 弱 — 未使用加密安全的生成源CWE-330
SS010MEDIUM会话 Cookie 的域名范围过广(如 domain=.example.com)CWE-565

SS001 — 缺少 HttpOnly 标志(CRITICAL)

检测 Set-Cookie 头部及会话配置中缺少 httpOnly: trueHttpOnly 标志的情况。若缺少 HttpOnly,任何页面上的 XSS 漏洞都可能通过 document.cookie 盗取会话 Cookie。

检测模式: res.cookie(name, val, {}) 未设置 httpOnly: true,Django 中的 cookie_secure=FalseSESSION_COOKIE_HTTPONLY = Falseset_cookie(key, value) 未设置 httponly=True

SS002 — 缺少 Secure 标志(HIGH)

缺少 Secure 标志的会话 Cookie 可能在非 HTTPS 连接下发送(例如浏览器重定向或用户手动输入 http://)。攻击者在同一网络中可通过被动中间人攻击截获。

SS003 — 缺少 SameSite 标志(HIGH)

若未设置 SameSite=StrictSameSite=Lax,浏览器会在跨域请求中发送会话 Cookie,即使使用了 CSRF 令牌库但配置错误,仍可能遭受 CSRF 攻击。Chrome 80 之前默认值为 SameSite=None

SS004 — 会话令牌出现在 URL 中(CRITICAL)

检测 req.query.tokenrequest.args.get('session_id')?auth=?session=?token= 等作为认证方式的使用情况。URL 中的令牌会出现在服务器日志、浏览器历史记录、Referer 头部和 CDN 访问日志中,存在泄露风险。

SS005 — 会话固定(CRITICAL)

在成功登录后(如 password.check()authenticate()login(user)bcrypt.compare()),必须重新生成会话 ID。检测登录成功路径中缺少 req.session.regenerate()session.cycle_key()request.session.flush()session.save() 等操作。会话固定攻击允许攻击者预先设定一个已知的会话 ID,在用户登录后劫持其会话。

SS006 — 缺少 CSRF 保护(HIGH)

检测 POST/PUT/PATCH/DELETE 请求路由定义中缺少 CSRF 中间件或令牌验证。识别框架特定的 CSRF 模式:csurfcsrf_tokenCsrfViewMiddleware@csrf_protectprotect_from_forgery_token 验证等。

SS007 — 认证信息存储在 localStorage(HIGH)

检测 localStorage.setItem('token'localStorage.setItem('session'localStorage.setItem('auth' 等写入操作。localStorage 可被页面上任意脚本访问,一旦存在 XSS 漏洞,所有存储的凭证将被暴露。建议使用 HttpOnly Cookie 替代。

SS008 — 未配置会话超时(MEDIUM)

检测会话配置中缺少 maxAgeexpirescookie_ageSESSION_COOKIE_AGEMaxInactiveInterval 等参数。未设置超时意味着被盗的会话令牌可长期有效。

SS009 — 会话 ID 生成源过弱(MEDIUM)

检测使用 random.random()Math.random()uuid.uuid4() 但未使用 secrets 模块、str(time.time()) 或顺序 ID 生成会话 ID。会话 ID 必须使用加密安全的随机源生成。

检测 domain: '.example.com'(带前导点)的配置。这会导致 Cookie 在所有子域名间共享,包括可能存在风险的子域名(如 uploads.example.com 上的用户上传内容)。

示例输出

markdown

============================================================

会话审计 — src/

扫描文件数:31 | 标记文件数:5

============================================================

── 严重 (3) ────────────────────────────────────────────────

🔴 SS001 [严重] src/middleware/session.js:12

会话 Cookie 设置时未启用 httpOnly: true。可能导致 XSS 攻击,通过 document.cookie 直接窃取会话。

CWE:CWE-1004:敏感 Cookie 缺少 'HttpOnly' 标志

修复建议:res.cookie('session', token, { httpOnly: true, secure: true, sameSite: 'Strict' })

🔴 SS004 [严重] src/routes/auth.js:45

使用 URL 查询参数中的 token 进行身份验证:req.query.token。

CWE:CWE-598:令牌暴露在 URL 中

修复建议:将 token 移至 Authorization: Bearer 头部。切勿通过查询字符串进行认证。

🔴 SS005 [严重] src/routes/login.js:78

登录成功后(bcrypt.compare)未及时重新生成会话。

CWE:CWE-384:会话固定攻击

修复建议:req.session.regenerate((err) => { req.session.userId = user.id; res.redirect('/dashboard'); })

── 高危 (2) ────────────────────────────────────────────────

🟠 SS003 [高危] src/app.js:23

会话 Cookie 未设置 SameSite 属性。即使存在 CSRF 令牌,仍可能遭受 CSRF 攻击。

CWE:CWE-352:跨站请求伪造

修复建议:app.use(session({ cookie: { sameSite: 'Strict' } }))

🟠 SS007 [高危] src/utils/auth.js:91

JWT 存储在 localStorage:localStorage.setItem('token', jwt)。

CWE:CWE-922:敏感信息不安全存储

修复建议:将 JWT 存储在 HttpOnly Cookie 中。若为 SPA 应用,使用内存变量(刷新后丢失)+ 刷新令牌存于 HttpOnly Cookie。

── 中等 (1) ────────────────────────────────────────────────

🟡 SS008 [中等] src/app.js:18

会话配置中未设置 maxAge/expires。会话永不过期——被盗令牌可永久有效。

CWE:CWE-613:会话过期机制不足

修复建议:cookie: { maxAge: 8 * 60 * 60 * 1000 } (8 小时 —— 根据实际安全需求调整)

────────────────────────────────────────────────────────────

总计:6 个发现

严重:3 | 高危:2 | 中等:1

❌ CI 门禁失败 —— 合并前需解决所有 严重/高危 问题。

markdown

Phy Session Audit

版本:1.0.3

分块:3/4

概述

phy-session-audit —— 会话与 Cookie 安全审计工具

对应 OWASP 2021 风险:A07 - 身份验证失败

支持扫描 Express/Flask/Django/Go/Spring/Rails 等框架中的会话管理漏洞。

无外部依赖。


数据结构

Finding

表示一个安全发现项。

字段类型说明
check_idstr检查项编号,如 SS001
severitystr严重程度:CRITICAL / HIGH / MEDIUM
locationstr发现位置,格式为 文件路径:行号
messagestr问题描述
cwestrCWE 编号(可选)
fixstr修复建议(可选)

输出示例:

🔴 SS001 [CRITICAL] src/auth.js:45
   Session cookie set without explicit HttpOnly flag — defaults to false in most frameworks.
   CWE: CWE-1004: Sensitive Cookie Without 'HttpOnly' Flag
   Fix: res.cookie('session', token, { httpOnly: true, secure: true, sameSite: 'Strict' })

AuditResult

审计结果汇总。

字段类型说明
scan_rootstr扫描根目录
files_scannedint扫描的文件数量
files_flaggedint标记有问题的文件数量
findingslist[Finding]所有发现的问题列表

属性:

  • critical_count:严重级别为 CRITICAL 的数量
  • high_count:严重级别为 HIGH 的数量
  • medium_count:严重级别为 MEDIUM 的数量

常量定义

SS001 — 缺少 HttpOnly 标志

  • COOKIE_SET_RE:匹配设置 Cookie 的语句。
  • HTTPONLY_PRESENT_RE:匹配 httpOnly: true 等启用标志。
  • HTTPONLY_DISABLED_RE:匹配 httpOnly: false 等禁用标志。

SS002 — 缺少 Secure 标志

  • SECURE_PRESENT_RE:匹配 secure: true; Secure 等启用标志。
  • SECURE_DISABLED_RE:匹配 secure: false 等禁用标志。

SS003 — 缺少 SameSite 属性

  • SAMESITE_PRESENT_RE:匹配 sameSiteSameSite 等关键词。
  • SAMESITE_NONE_RE:匹配 sameSite: 'none' 等宽松配置。

SS004 — Token 出现在 URL 中

  • URL_TOKEN_RE:匹配 ?token=, req.query.token, request.getParameter("token") 等。

SS005 — 登录后未重新生成会话(会话固定)

  • LOGIN_SUCCESS_RE:匹配登录成功逻辑(如 bcrypt.compare, authenticate 等)。
  • SESSION_REGENERATE_RE:匹配会话再生操作(如 req.session.regenerate)。

SS006 — 缺少 CSRF 保护

  • POST_ROUTE_RE:匹配 app.post, router.put 等状态变更路由。
  • PYTHON_POST_ROUTE_RE:匹配 @app.post, @router.put 等装饰器。
  • CSRF_GUARD_RE:匹配已启用 CSRF 保护的中间件或注解。

SS007 — 认证信息存储在 localStorage

  • LOCALSTORAGE_AUTH_RE:匹配 localStorage.setItem 存储 token、session 等行为。

SS008 — 会话未设置超时

  • SESSION_CONFIG_RE:匹配会话配置相关代码。
  • TIMEOUT_PRESENT_RE:匹配 maxAge, expires, SESSION_COOKIE_AGE 等超时设置。

SS009 — 会话 ID 生成弱(可预测)

  • WEAK_SESSION_ID_RE:匹配使用 random.random(), Math.random(), time.time() 等弱随机源。
  • BROAD_DOMAIN_RE:匹配 domain: '.example.com' 等跨子域共享配置。

支持的文件类型

.js, .ts, .jsx, .tsx, .py, .go, .java, .kt, .rb, .php


忽略目录

node_modules, .git, venv, .venv, __pycache__, dist, build, .next, vendor, test, tests, __tests__, migrations


检查规则

  • 若显式设置 httpOnly: false,标记为 严重(CRITICAL)
  • 若未显式设置 httpOnly 且涉及 session/auth/token,标记为 严重(CRITICAL)
  • 修复建议:始终设置 httpOnly: true
  • 若显式设置 secure: false,标记为 高危(HIGH)
  • 若未设置 secure 且涉及敏感字段,标记为 高危(HIGH)
  • 修复建议:仅在开发环境禁用,生产环境必须启用 secure: true
  • 若未设置 SameSite,且涉及敏感字段,标记为 高危(HIGH)
  • 若设置为 SameSite=None,标记为 高危(HIGH)
  • 修复建议:使用 SameSite=StrictLax,除非明确需要跨站共享。

SS004 — 认证令牌出现在 URL 查询字符串中

  • 匹配任何包含 tokensession_id 等的 URL 参数。
  • 修复建议:改用 Authorization: Bearer <token> 头部传递;避免长期令牌暴露于日志和历史记录。

SS005 — 登录后未重新生成会话(会话固定)

  • 在检测到登录成功逻辑后,若未调用会话再生函数,标记为 严重(CRITICAL)
  • 修复建议:登录成功后立即调用 req.session.regenerate()

SS006 — 状态变更路由缺少 CSRF 保护

  • 若项目全局已启用 CSRF 保护,则跳过单个检查。
  • 否则,对非 API/健康检查类的 POST/PUT/PATCH/DELETE 路由进行检查。
  • 修复建议:

- Express:安装 csurf 并启用中间件。

- Django:确保 CsrfViewMiddlewareMIDDLEWARE 中。

- Rails:添加 protect_from_forgery with: :exception

SS007 — 认证信息存储在 localStorage

  • 匹配 localStorage.setItem 写入 token、session 等。
  • 修复建议:将 JWT 存储在 HttpOnly Cookie 中;前端应用中,访问令牌放内存,刷新令牌放 HttpOnly Cookie。

SS008 — 会话未设置超时

  • 若配置了会话但未设置 maxAge/expires,标记为 中等(MEDIUM)
  • 修复建议:设置合理超时时间(如 8 小时),高安全场景使用滑动窗口机制。

SS009 — 会话 ID 生成弱(可预测)

  • 匹配使用 random.random(), Math.random(), time.time() 等弱随机源。
  • 修复建议:

- Python:使用 secrets.token_urlsafe(32)

- Node.js:使用 crypto.randomBytes(32).toString('hex')

- 推荐使用成熟会话库,避免自行实现。

  • 匹配 domain: '.example.com' 等配置。
  • 修复建议:使用精确域名(如 domain: 'app.example.com'),避免跨子域共享。

主要审计流程

  1. 递归收集目标路径下所有支持的文件。
  2. 读取每个文件内容并按行解析。
  3. 对每文件依次执行 10 项检查。
  4. 汇总所有发现项,生成报告。
  5. 输出结果并根据 CI 模式决定是否退出非零状态。

报告格式

============================================================
  Session Audit — ./src
  Files scanned: 124  |  Files flagged: 8
============================================================

── CRITICAL (3) ──────────────────────────────────────────────
🔴 SS001 [CRITICAL] auth.js:45
   Session cookie set without explicit HttpOnly flag — defaults to false in most frameworks.
   CWE: CWE-1004: Sensitive Cookie Without 'HttpOnly' Flag
   Fix: res.cookie('session', token, { httpOnly: true, secure: true, sameSite: 'Strict' })

── HIGH (4) ─────────────────────────────────────────────────
🟠 SS003 [HIGH] session.js:23
   Session cookie missing SameSite attribute. Browser sends cookie on cross-origin requests — CSRF possible.
   CWE: CWE-352: Cross-Site Request Forgery
   Fix: Add sameSite: 'Strict' (forms) or sameSite: 'Lax' (external links). Avoid sameSite: 'None' unless required.

── MEDIUM (1) ───────────────────────────────────────────────
🟡 SS008 [MEDIUM] config/session.py:12
   Session configured without maxAge/expires. Sessions never expire — stolen tokens remain valid indefinitely.
   CWE: CWE-613: Insufficient Session Expiration
   Fix: cookie: { maxAge: 8 * 60 * 60 * 1000 }  (8 hours). For high-security: 15-30 minutes with sliding window.

────────────────────────────────────────────────────────────
  Total: 8 findings  |  Critical: 3  High: 4  Medium: 1
  ❌ CI GATE FAILED — resolve CRITICAL/HIGH findings before merging.

CLI 使用

python session_audit.py ./src
python session_audit.py src/middleware/session.js
python session_audit.py ./src --ci
python session_audit.py ./src --only-severity CRITICAL

参数说明

参数说明
path要审计的目录或文件路径
--ci若存在严重或高危问题,返回非零退出码(用于 CI 流水线)
--only-severity只显示指定严重等级及更高级别的问题(可选:CRITICAL / HIGH / MEDIUM)

CI 集成

在 CI 管道中使用 --ci 参数,可自动阻断合并请求。

当发现 CRITICALHIGH 级别问题时,脚本将退出码设为 1,触发构建失败。

适用于 GitHub Actions、GitLab CI、Jenkins 等自动化流程。

yaml

GitHub Actions

  • name: 会话安全审计

run: python session_audit.py ./src --ci

仅 CRITICAL 级别发现会阻塞构建

  • name: 会话审计(仅关键级别)

run: python session_audit.py ./src --only-severity CRITICAL --ci

## 误报说明

- **SS001/SS002/SS003** — 仅在发现与会话、认证、令牌或 JWT 相关的 cookie 且未设置相应标志时触发。纯分析类的 cookie 不会触发。
- **SS005** — 需要同时存在登录成功信号和附近响应(25行范围内)。仅用于检查密码的工具函数不会触发。
- **SS006** — 若文件中任意位置存在任何 CSRF 保护模式,则跳过检测。同时跳过匹配 `webhook`、`health`、`/api/`、`/grpc` 的路由(通常为使用 Bearer Token 而非 Cookie 的无状态 API 路由)。最多报告 3 个发现(全局修复适用于所有)。
- **SS009** — 使用 `uuid.uuid4()` 生成会话 ID 时标记为 MEDIUM 级别。虽然 `uuid.uuid4()` 使用操作系统熵源(`os.urandom`),安全性足够,但若直接使用 `.hex` 并赋值为会话 ID 而未通过 `secrets` 包装,则技术上弱于 `secrets.token_urlsafe()`。若框架内部已处理会话 ID 生成,可忽略此警告。

## OWASP 覆盖映射

| 检查项 | OWASP A07:2021 子类别 |
|-------|-----------------------------|
| SS001 | 会话令牌通过 XSS 泄露 |
| SS002 | 令牌在明文传输中泄露 |
| SS003 | CSRF 保护缺失 |
| SS004 | 令牌通过 URL 泄露 |
| SS005 | 会话固定漏洞 |
| SS006 | CSRF 伪造攻击 |
| SS007 | 客户端不安全存储 |
| SS008 | 会话生命周期无限 |
| SS009 | 可预测的会话令牌 |
| SS010 | 过宽的 Cookie 作用域 |

## 相关技能

- **phy-crypto-audit** — 弱 JWT 签名、令牌使用的 PRNG 问题(补充 SS009)
- **phy-jwt-auth-audit** — 深度 JWT 令牌检查、alg:none 检测、作用域审计
- **phy-cors-audit** — CORS 配置错误导致 SameSite 保护被绕过
- **phy-rate-limit-audit** — 认证接口的暴力破解防护

---

## 作者

**[Canlah AI](https://canlah.ai)** — 在不破坏品牌的情况下实现高效性能营销。

- GitHub: [github.com/PHY041](https://github.com/PHY041)
- 所有技能: [clawhub.ai/PHY041](https://clawhub.ai/PHY041)
P
@phy041

已收录 3 个 Skill

相关推荐