Config Validator
验证 OpenClaw 配置字段与值的正确性,提供官方 schema 参考和示例。
扫描源码中的10类会话管理漏洞,支持多框架,零依赖。
openclaw skills install @phy041/phy-session-audit命令、参数、文件名以原文为准
扫描源代码中的 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| ID | 严重性 | 检查项 | CWE |
|---|---|---|---|
| SS001 | CRITICAL | 会话 Cookie 缺少 HttpOnly 标志 | CWE-1004 |
| SS002 | HIGH | 会话 Cookie 缺少 Secure 标志 | CWE-614 |
| SS003 | HIGH | 会话 Cookie 缺少 SameSite 属性 | CWE-352 |
| SS004 | CRITICAL | 会话令牌 / 认证令牌出现在 URL 查询字符串中 | CWE-598 |
| SS005 | CRITICAL | 登录后未重新生成会话 ID(会话固定) | CWE-384 |
| SS006 | HIGH | 状态变更路由缺少 CSRF 保护 | CWE-352 |
| SS007 | HIGH | 会话/认证数据存储在 localStorage 中 | CWE-922 |
| SS008 | MEDIUM | 未配置会话超时时间(会话无限期有效) | CWE-613 |
| SS009 | MEDIUM | 会话 ID 弱 — 未使用加密安全的生成源 | CWE-330 |
| SS010 | MEDIUM | 会话 Cookie 的域名范围过广(如 domain=.example.com) | CWE-565 |
检测 Set-Cookie 头部及会话配置中缺少 httpOnly: true 或 HttpOnly 标志的情况。若缺少 HttpOnly,任何页面上的 XSS 漏洞都可能通过 document.cookie 盗取会话 Cookie。
检测模式: res.cookie(name, val, {}) 未设置 httpOnly: true,Django 中的 cookie_secure=False,SESSION_COOKIE_HTTPONLY = False,set_cookie(key, value) 未设置 httponly=True。
缺少 Secure 标志的会话 Cookie 可能在非 HTTPS 连接下发送(例如浏览器重定向或用户手动输入 http://)。攻击者在同一网络中可通过被动中间人攻击截获。
若未设置 SameSite=Strict 或 SameSite=Lax,浏览器会在跨域请求中发送会话 Cookie,即使使用了 CSRF 令牌库但配置错误,仍可能遭受 CSRF 攻击。Chrome 80 之前默认值为 SameSite=None。
检测 req.query.token、request.args.get('session_id')、?auth=、?session=、?token= 等作为认证方式的使用情况。URL 中的令牌会出现在服务器日志、浏览器历史记录、Referer 头部和 CDN 访问日志中,存在泄露风险。
在成功登录后(如 password.check()、authenticate()、login(user)、bcrypt.compare()),必须重新生成会话 ID。检测登录成功路径中缺少 req.session.regenerate()、session.cycle_key()、request.session.flush()、session.save() 等操作。会话固定攻击允许攻击者预先设定一个已知的会话 ID,在用户登录后劫持其会话。
检测 POST/PUT/PATCH/DELETE 请求路由定义中缺少 CSRF 中间件或令牌验证。识别框架特定的 CSRF 模式:csurf、csrf_token、CsrfViewMiddleware、@csrf_protect、protect_from_forgery、_token 验证等。
检测 localStorage.setItem('token'、localStorage.setItem('session'、localStorage.setItem('auth' 等写入操作。localStorage 可被页面上任意脚本访问,一旦存在 XSS 漏洞,所有存储的凭证将被暴露。建议使用 HttpOnly Cookie 替代。
检测会话配置中缺少 maxAge、expires、cookie_age、SESSION_COOKIE_AGE、MaxInactiveInterval 等参数。未设置超时意味着被盗的会话令牌可长期有效。
检测使用 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
版本:1.0.3
分块:3/4
phy-session-audit —— 会话与 Cookie 安全审计工具
对应 OWASP 2021 风险:A07 - 身份验证失败
支持扫描 Express/Flask/Django/Go/Spring/Rails 等框架中的会话管理漏洞。
无外部依赖。
Finding表示一个安全发现项。
| 字段 | 类型 | 说明 |
|---|---|---|
check_id | str | 检查项编号,如 SS001 |
severity | str | 严重程度:CRITICAL / HIGH / MEDIUM |
location | str | 发现位置,格式为 文件路径:行号 |
message | str | 问题描述 |
cwe | str | CWE 编号(可选) |
fix | str | 修复建议(可选) |
输出示例:
🔴 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_root | str | 扫描根目录 |
files_scanned | int | 扫描的文件数量 |
files_flagged | int | 标记有问题的文件数量 |
findings | list[Finding] | 所有发现的问题列表 |
属性:
critical_count:严重级别为 CRITICAL 的数量high_count:严重级别为 HIGH 的数量medium_count:严重级别为 MEDIUM 的数量COOKIE_SET_RE:匹配设置 Cookie 的语句。HTTPONLY_PRESENT_RE:匹配 httpOnly: true 等启用标志。HTTPONLY_DISABLED_RE:匹配 httpOnly: false 等禁用标志。SECURE_PRESENT_RE:匹配 secure: true 或 ; Secure 等启用标志。SECURE_DISABLED_RE:匹配 secure: false 等禁用标志。SAMESITE_PRESENT_RE:匹配 sameSite、SameSite 等关键词。SAMESITE_NONE_RE:匹配 sameSite: 'none' 等宽松配置。URL_TOKEN_RE:匹配 ?token=, req.query.token, request.getParameter("token") 等。LOGIN_SUCCESS_RE:匹配登录成功逻辑(如 bcrypt.compare, authenticate 等)。SESSION_REGENERATE_RE:匹配会话再生操作(如 req.session.regenerate)。POST_ROUTE_RE:匹配 app.post, router.put 等状态变更路由。PYTHON_POST_ROUTE_RE:匹配 @app.post, @router.put 等装饰器。CSRF_GUARD_RE:匹配已启用 CSRF 保护的中间件或注解。LOCALSTORAGE_AUTH_RE:匹配 localStorage.setItem 存储 token、session 等行为。SESSION_CONFIG_RE:匹配会话配置相关代码。TIMEOUT_PRESENT_RE:匹配 maxAge, expires, SESSION_COOKIE_AGE 等超时设置。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=Strict 或 Lax,除非明确需要跨站共享。token、session_id 等的 URL 参数。Authorization: Bearer <token> 头部传递;避免长期令牌暴露于日志和历史记录。req.session.regenerate()。 - Express:安装 csurf 并启用中间件。
- Django:确保 CsrfViewMiddleware 在 MIDDLEWARE 中。
- Rails:添加 protect_from_forgery with: :exception。
localStorage.setItem 写入 token、session 等。HttpOnly Cookie 中;前端应用中,访问令牌放内存,刷新令牌放 HttpOnly Cookie。maxAge/expires,标记为 中等(MEDIUM)。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'),避免跨子域共享。============================================================
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.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 参数,可自动阻断合并请求。
当发现 CRITICAL 或 HIGH 级别问题时,脚本将退出码设为 1,触发构建失败。
适用于 GitHub Actions、GitLab CI、Jenkins 等自动化流程。
yaml
run: python session_audit.py ./src --ci
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)已收录 3 个 Skill