Ozark-Security-Labs/SessionScope

GitHub: Ozark-Security-Labs/SessionScope

一款面向产品安全团队和开发者的防御性静态分析工具,通过对会话、Cookie、JWT 和 Token 全生命周期进行离线代码审计,系统性地发现身份验证配置缺陷与安全风险。

Stars: 0 | Forks: 0

# SessionScope SessionScope 是一款防御性的产品安全工具,用于审计应用程序代码中的会话、cookie、JWT 和 token 生命周期行为。 它可以解答: SessionScope 专为产品安全团队和开发人员设计,供那些需要对会话管理风险进行基于证据的审查,但又无需对运行中的系统发起攻击的人员使用。 ## 问题 会话和 token 漏洞影响巨大且十分常见。团队通常依赖框架默认配置、分散的 middleware 或第三方库,但仍会无意中引入以下问题: - cookie 缺少 `HttpOnly`、`Secure`、作用域受限的生命周期或 `SameSite` - JWT 在未经颁发者或受众验证的情况下即被接受 - refresh token 从未进行轮换 - 登出路径未撤销服务端状态 - 长期有效的 token 未强制执行过期机制 - token 在信任边界之间被重用 - API 密钥或 bearer token 被存储在不安全的位置 - 密码重置或电子邮件验证 token 缺乏一次性使用语义 通过映射 token 生命周期路径和配置证据,可以对许多检查进行静态审查。 ## 产品论点 身份验证安全不仅仅是“登录是否能正常工作?”。这是一个生命周期问题。 SessionScope 构建了一张涵盖 token 颁发、存储、验证、刷新、撤销和过期过程的映射图,以便审查人员能够清晰地看到生命周期中的漏洞。 ## 初始范围 SessionScope 是一款适用于常见 Web 应用程序模式的 CLI 和 CI 友好型分析器。 初始目标: - Express 会话/cookie/JWT middleware - Next.js 身份验证/会话模式 - FastAPI 身份验证依赖项 - Django 会话和签名工具 - TypeScript 和 Python 中的 JWT 库 - 用于设置 cookie 的 API 初始输出: - Markdown 生命周期报告 - JSON token 流量清单 - 针对高置信度问题的 SARIF 发现结果 - GitHub Actions 摘要 ## 示例报告形式 ``` Token: access_jwt Issued at: src/auth/login.ts:44 Validation evidence: - jwt.verify(token, publicKey) - issuer check: present - audience check: missing - expiry check: library default Storage evidence: - Authorization bearer token expected Risk: review_required Reviewer question: - Should this service enforce an audience claim? ``` ``` Cookie: session Set at: app/auth/session.py:71 Attributes: - HttpOnly: present - Secure: missing - SameSite: lax - Max-Age: 30 days Risk: high_confidence_misconfiguration Suggested fix: - Set Secure in production cookie configuration. ``` ## 核心概念 带有版本控制的清单和发现结果 schema 记录在 [`docs/SCHEMA.md`](docs/SCHEMA.md) 中。 ### 生命周期阶段 SessionScope 通过以下阶段对身份验证产物进行建模: - issue(颁发) - store(存储) - transmit(传输) - validate(验证) - refresh(刷新) - revoke(撤销) - expire(过期) - introspect(内省) ### Token 类型 SessionScope 可分类: - 会话 cookie - 签名 cookie - 访问 JWT - 刷新 JWT - 不透明的 bearer token - API 密钥 - 服务 token - 未知 token 流 - 密码重置 token - 电子邮件验证 token - 设备/会话记录 - token 作用域和信任边界证据 ### 基于证据的发现结果 SessionScope 倾向于采用精确的表述: - “在 JWT 验证附近未检测到受众验证证据。” - “此 cookie 设置调用未设置 Secure。” - “未找到 refresh token 轮换证据。” 除非有确定性证据证明,否则应避免使用诸如“身份验证绕过”之类缺乏依据的断言。 ## CLI 概览 ``` sessionscope init sessionscope scan --path . --format markdown --output sessions.md sessionscope scan --path . --include "src/**/*.ts" --exclude "**/*.test.ts" --format json --output sessions.json sessionscope scan --path . --max-file-size 1000000 sessionscope explain FINDING_ID sessionscope diff main...HEAD sessionscope baseline create ``` JSON 报告是使用已记录在案的 schema 版本的机器可读清单。一份简明的 cookie 审计摘录如下所示: ``` { "schema_version": "0.5.0", "summary": { "files_discovered": 1, "files_scanned": 1, "files_skipped": 0, "diagnostics": [] }, "artifacts": [ { "id": "artifact_...", "artifact_type": "session_cookie", "display_name": "session", "locations": [{ "path": "src/app.ts", "line": 12, "column": 3 }], "lifecycle_evidence": { "issue": [], "store": ["evidence_cookie_store"], "transmit": ["evidence_cookie_secure"], "validate": [], "refresh": [], "revoke": [], "expire": [], "introspect": [] }, "confidence": "high", "framework_hints": ["express"], "cookie_attributes": { "http_only": { "state": "missing", "evidence_ids": ["evidence_cookie_http_only"], "confidence": "high" }, "secure": { "state": "present", "value": "true", "evidence_ids": ["evidence_cookie_secure"], "confidence": "high" }, "same_site": { "state": "present", "value": "lax", "evidence_ids": ["evidence_cookie_same_site"], "confidence": "high" }, "max_age": { "state": "missing", "evidence_ids": ["evidence_cookie_max_age"], "confidence": "high" }, "expires": { "state": "missing", "evidence_ids": ["evidence_cookie_expires"], "confidence": "high" }, "path": { "state": "framework_default", "value": "/", "evidence_ids": ["evidence_cookie_path"], "confidence": "low" }, "domain": { "state": "missing", "evidence_ids": ["evidence_cookie_domain"], "confidence": "high" } } } ], "evidence": [ { "id": "evidence_cookie_store", "lifecycle_stage": "store", "location": { "path": "src/app.ts", "line": 12, "column": 3 }, "detector_id": "cookie.set", "confidence": "high", "excerpt": "response.cookie(\"session\", [REDACTED], ...)", "dynamic": false, "framework_default": false } ], "lifecycle_paths": [ { "id": "lifecycle_path_...", "artifact_ids": ["artifact_..."], "stages": [ { "stage": "store", "evidence_ids": ["evidence_cookie_store"] } ], "confidence": "high", "dynamic": false, "reviewer_question": null } ], "findings": [ { "id": "finding_...", "category": "high_confidence_misconfiguration", "severity": "high", "artifact_ids": ["artifact_..."], "evidence_ids": ["evidence_cookie_http_only"], "title": "Session-like cookie `session` does not set HttpOnly", "description": "No HttpOnly attribute evidence was detected for this cookie-setting call.", "suggested_fix": "Set HttpOnly on session cookies so client-side scripts cannot read them.", "reviewer_question": "Is this cookie intended to be inaccessible to browser JavaScript?" } ], "files": [] } ``` ## GitHub Action 概览 ``` name: SessionScope on: [pull_request] jobs: sessionscope: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: bjcorder/SessionScope@v0 with: mode: advisory output: markdown,sarif ``` ## 配置 运行 `sessionscope init` 以创建一个可提交至版本控制的 `sessionscope.toml` 文件。该命令是非交互式的,不需要网络访问,并且在未传入 `--force` 参数的情况下拒绝覆盖现有配置。 初始化后的配置示例: ``` # SessionScope 配置 # 由 `sessionscope init` 生成。可安全提交。 # 请勿在此文件中放置 token 值、私钥、bearer 字符串、cookie 值或 # 特定环境的 secrets。 scan_paths = ["."] include = ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx", "**/*.py", "**/*.json", "**/*.yaml", "**/*.yml", "**/*.toml"] exclude = ["**/*.test.ts", "**/*.spec.ts", "**/__tests__/**"] formats = ["markdown"] mode = "advisory" max_file_size_bytes = 1000000 framework_hints = ["express", "nextjs", "fastapi", "django"] provider_hints = [] ``` 配置优先级依次为: 1. CLI 标志,例如 `--path`、`--include`、`--exclude`、`--format` 和 `--max-file-size` 2. `sessionscope.toml` 3. 内置默认值 `--include` 会替换已配置的包含模式,而 `--exclude` 则会追加到已配置的排除列表中。SessionScope 还会在实际可行的范围内遵循 `.gitignore` 规则,应用内置的 dependency/vendor/build 排除项,并在加载源代码之前跳过敏感路径(例如 env 文件和私钥材料)。 ## 潜在检查项 - Cookie 缺少 `HttpOnly` - Cookie 缺少 `Secure` - 不安全或需要审查的 cookie 状态,包括生命周期过长、Domain/Path 作用域过宽以及 `SameSite=None` 的处理方式 - JWT 验证未进行颁发者验证 - JWT 验证未进行受众验证 - 颁发的 token 没有明确的过期时间 - Refresh token 缺少轮换证据 - 登出时缺少撤销证据 - 密码重置 token 缺少过期时间或一次性使用证据 - 会话固定风险信号 - 接受来自查询参数的 token - 跨服务、环境或信任边界的 token 重用需要审查 ## 非目标 SessionScope 不旨在: - 利用身份验证系统 - 对 token 进行暴力破解 - 攻击正在运行的应用程序 - 窃取或解码机密信息 - 取代人工安全审查 ## 开发 SessionScope 采用 Rust Cargo workspace 搭建脚手架,使用 Rust 2024 edition。在运行本地检查之前,请从 安装 stable Rust 工具链。 该 workspace 被拆分为多个专注的 crate,分别用于 CLI、核心扫描器 pipeline、共享模型、检测器、分类器、报告器和测试辅助工具。CLI 二进制文件命名为 `sessionscope`。 标准的本地检查命令: ``` cargo fmt --all -- --check cargo clippy --workspace --all-targets -- -D warnings cargo check --workspace cargo test --workspace --all-targets ``` 开发过程中常用的 CLI 命令: ``` cargo run -p sessionscope-cli -- --help cargo run -p sessionscope-cli -- version cargo run -p sessionscope-cli -- scan --path . --format markdown cargo run -p sessionscope-cli -- scan --path . --include "src/**/*.ts" --exclude "**/*.test.ts" --max-file-size 1000000 --format json ``` 扫描器是防御性和纯离线运行的。请勿添加会打印 token 值、私钥、bearer 字符串、cookie 值或其他运行时机密信息的分析器行为。 ## 脱敏信任边界 SessionScope 将源代码文本和检测器输出视为不受信任的内容,直到它们通过 `sessionscope-core::redaction` 处理。证据摘录和渲染后的报告应保留源码位置、发现结果 ID、生命周期阶段、声明名称和属性名称,但 token 值、cookie 值、bearer 字符串、私钥和高熵的类似机密字面量必须替换为 `[REDACTED]`。 脱敏是一种尽力而为的静态保护措施,不能保证任意源代码中都不包含机密。为了保持可审查性,稳定的 ID 和源码位置会被保留,且绝不能从运行时的 token 值、私钥、bearer 字符串、cookie 值或其他机密信息中生成。 ## 状态 此代码库包含初始的产品文档和 Rust workspace 脚手架。目前 CLI、pipeline、检测器、分类器、报告器和测试辅助工具 crate 均已就绪,其中的检测器和分类器行为将在下一个里程碑中实现。
标签:API安全, AV绕过, CI/CD安全, Cookie安全, DevSecOps, Django, Express, FastAPI, JSON输出, JWT, Llama, LNA, Python, SAST, TypeScript, Web安全, 上游代理, 产品安全, 代码安全审计, 令牌生命周期, 会话安全, 可视化界面, 安全审查, 安全工程, 安全插件, 文档结构分析, 无后门, 盲注攻击, 蓝队分析, 通知系统, 防御加固, 静态应用安全测试