DreadpiratePickles/key-kettle

GitHub: DreadpiratePickles/key-kettle

一款基于 NIST/OWASP/CISA 指南对密码策略进行评分审计的离线 CLI 工具,输出带来源引用的结构化改进报告。

Stars: 0 | Forks: 0

# 🫖 Key Kettle ### 根据现代 NIST / OWASP / CISA 指南审计密码策略要求。 ![python](https://img.shields.io/badge/python-3.11%2B-3776AB?logo=python&logoColor=white) ![license](https://img.shields.io/badge/license-MIT-blueviolet) ![tests](https://img.shields.io/badge/tests-49%20passing-brightgreen) ![interface](https://img.shields.io/badge/interface-CLI%20%2B%20Web-22c55e) ![transmits](https://img.shields.io/badge/transmits-nothing%20by%20default-success) *“一个大写字母、一个数字、一个符号”——正是这条规则导致了 `P@ssw0rd1` 被使用了十亿次。*
Key Kettle 接收以 JSON 表示的密码策略,并返回一份经过评分、定级和按优先级排序的报告:存在什么问题、如何修复、*为何重要*,以及是哪项标准的要求。这是一款你在客户会议前运行的工具,这样你就可以直接提交“这里有 6 项未通过的控制措施,并按严重程度排序”,而不是含糊地说“你们的密码规则感觉过时了”。 它是一个**防御性的、离线的**咨询工具。它只读取策略*描述*——绝不接触目录、身份验证系统或真实密码。唯一的网络暴露面是可选的本地报告 UI,且该功能受到限制(参见[安全与授权](#safety--authorization))。 ## 开发初衷 现实中大多数密码策略仍然包含当前指南明确不鼓励的控制措施:最大长度过短、强制定期轮换、死板的组合规则、禁止粘贴/密码管理器,以及使用快速的通用哈希进行存储。Key Kettle 将这些要求转化为符合标准的改进计划,让合规顾问、MSP 或内部安全团队能够直接付诸行动。 每一项发现都引用了其来源: - [NIST SP 800-63B](https://pages.nist.gov/800-63-4/sp800-63b.html) — 长度优先于组合,无强制轮换,黑名单筛选,速率限制,慢速哈希。 - [OWASP Authentication / Password Storage Cheat Sheets](https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html) — 具体实现细节。 - [CISA Multifactor Authentication](https://www.cisa.gov/topics/cybersecurity-best-practices/multifactor-authentication) — 强调 MFA。 - [Verizon DBIR](https://www.verizon.com/business/resources/reports/dbir/) — 为什么凭证滥用始终是攻击者的实用路径。 ## 工作原理 ``` policy JSON ──▶ PasswordPolicy.from_dict ──▶ analyze_policy ──▶ PolicyReport (validate + coerce + (one check per (score, grade, fill weak defaults) control) summary, recs) │ │ ├─ policy_key_warnings ──▶ stderr notes ├─ rich table/panel (humans) │ └─ pure JSON (machines) ``` **1. 解析与验证 (`policy.py`)。** 输入被视为不可信的敌对数据。字段被强制转换为其真实类型(布尔值接受 `true`/`"yes"`/`1`,轮换接受 `0`/`""`/`null` 作为“禁用”),检查范围(`min_length` 在 `1..4096` 之内,`max_length ≥ min_length`,无非负值或荒谬的值),错误的输入会引发 `PolicyError` 并指出出错字段。**缺失的字段会故意回退到*脆弱的*示例**——审计工具应对未告知的控制措施做最坏的假设,而不是凭空给出一个看似美好的默认值。未知/拼写错误和省略的字段将作为非致命提示输出到 stderr。 **2. 分析 (`analyzer.py`)。** 评估十一项控制措施,每项恰好生成一个建议——`pass` 或某个问题——因此输出是一份完整的清单,而不仅仅是一堆抱怨: | 控制措施 | 通过条件 | 失败时的权重 | | --- | --- | --- | | 最小长度 | ≥ 15 (如果要求 MFA 则 ≥ 8) | high | | 最大长度 | ≥ 64 | medium | | 组合规则 | 无要求 | medium (建议) | | 定期轮换 | 无 | medium/low (建议) | | 泄露密码筛查 | 启用 | high | | 多因素认证 | 必须 | high | | 密码管理器与粘贴 | 均允许 | medium | | 速率限制 | 1–10 次失败尝试 | high | | 密码存储 | 加盐哈希 | **critical** | | 密码哈希算法 | Argon2id / bcrypt / scrypt / PBKDF2 | high (建议) | | 字符允许范围 | 空格 + Unicode | low (建议) | **3. 评分与定级。** 从 100 开始,减去每项未通过控制措施的严重性权重(`critical 28, high 18, medium 10, low 4`),下限为 0。等级划分:`A ≥ 90`, `B ≥ 80`, `C ≥ 70`, `D ≥ 60`,否则为 `F`。在表格和 JSON 中,建议均按最差优先排序。 **4. 渲染。** 人类将获得丰富的摘要面板 + 颜色编码的表格(严重性 `critical/high → 红色`,`medium → 黄色`,`low → 青色`,`pass → 绿色`)。机器将获得纯 JSON。两者绝不混用。 ### 数据模型 `PasswordPolicy`(不可变数据类,无数据库)捕获:`min_length`,`max_length`,四个 `require_*` 组合标志,`rotation_days`,`breach_screening`,`mfa_required`,`paste_allowed`,`password_manager_allowed`,`lockout_threshold`,`stores_hashed`,`hashing_algorithm`,`allows_spaces`,`allows_unicode`。运行 `key-kettle sample-policy` 以查看完整结构。 ## 安装 ``` cd key-kettle python -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate pip install -r requirements.txt pip install -e . # provides the `key-kettle` command cp .env.example .env # optional: sets default serve host/port ``` 不想进行可编辑安装?所有命令均可通过 `PYTHONPATH=src python -m key_kettle.cli ...` 运行。 ## CLI 用法 全局参数:`--plain` / `--no-color` 禁用颜色、emoji 和表格绘制(当设置了 `NO_COLOR` 或输出不是 TTY 时也会自动生效)。`--version` 打印版本号。无论这些设置如何,JSON 输出始终是纯净的。 ### `sample-policy` — 打印策略以供编辑 ``` key-kettle sample-policy # a deliberately dated weak baseline key-kettle sample-policy --strong # a modern, NIST-aligned baseline key-kettle sample-policy > policy.json ``` 将策略 JSON 打印到 stdout(品牌标头(如果有)会输出到 stderr,因此 JSON 保持可通过管道传输)。 ### `analyze` — 对策略进行评分 ``` key-kettle analyze --policy policy.json # human report key-kettle analyze --policy - < policy.json # read from stdin key-kettle sample-policy | key-kettle analyze --policy - # pipe straight in key-kettle analyze --policy policy.json --json | jq # machine-readable key-kettle analyze --policy policy.json --fail-under 80 # stricter CI gate ``` | 标志 | 含义 | | --- | --- | | `--policy PATH` | 策略 JSON 文件,或 `-` 表示 stdin(必填)。文件大小限制为 1 MiB。 | | `--json` | 向 stdout 输出纯 JSON(无颜色,无标头)。 | | `--fail-under SCORE` | 如果分数 < SCORE,则以非零状态退出(默认为 70)。 | **退出代码:** `0` = 分数达到阈值;`1` = 低于阈值*或*输入错误(文件缺失、JSON 错误、字段无效)。非常适合作为 CI 的检查关卡。 人类可读的输出示例(强密码策略): ``` ┌───────────────────────── Audit result ─────────────────────────┐ │ 100/100 grade A │ │ 0 failing controls, 0 warnings. │ │ 0 failing · 0 advisory · 11 passing · 11 controls reviewed │ └─────────────────────────────────────────────────────────────────┘ Sev Control Finding Recommended fix ───────────────────────────────────────────────────────────────────────────── ✓ pass Multi-factor authentication MFA is required. Keep MFA required… ✓ pass Rate limiting Failed attempts… Keep tight rate… … ``` 对于弱密码策略,同一视图会将最严重的问题展示在最前面: ``` X high Compromised-password screening No blocklist… Compare new passwords… X high Minimum length Minimum length 8… Set minimum length to 15… X high Multi-factor authentication MFA is not req… Require MFA… ``` ### `serve` — 本地报告 UI ``` key-kettle serve # http://127.0.0.1:5065 key-kettle serve --host 127.0.0.1 --port 5065 ``` 打开一个 Flask 页面,你可以在其中粘贴策略 JSON 并获取渲染后的报告。默认绑定到环回地址。绑定到其他任何地址均需要明确确认(见下文)。 ## 安全与授权 Key Kettle 用于**审计你拥有或被授权评估的策略**。它不执行任何扫描,也不发送任何电子邮件。唯一需要关注的风险面是 `serve`: - **默认绑定到 `127.0.0.1`。** 报告 UI *没有身份验证*,并会评估任何能访问到它的人粘贴的策略 JSON。 - **非环回绑定受到限制。** 除非你传递 `--allow-nonlocal`(这是一种明确的“我拥有此网络并接受风险”的确认),否则 `serve --host 0.0.0.0`(或任何局域网 IP / 主机名)将被拒绝。拒绝时的退出代码为 `2`。 - **在非环回主机上使用 `--debug` 总是被拒绝的** —— Werkzeug 交互式调试器允许远程代码执行。 - **输入被视为不可信。** 读取文件大小受限(CLI 1 MiB / HTTP 正文 256 KiB),非对象和超出范围的 JSON 将被拒绝并返回整洁的错误信息,错误响应绝不会泄露堆栈跟踪。输出由 Jinja 自动转义,并带有 `X-Content-Type-Options`、`X-Frame-Options`、`Referrer-Policy` 和严格的 `Content-Security-Policy`。 - **不会读取或记录任何机密。** `.env` 仅保存默认的主机/端口。对于笔记本电脑以外的任何实际部署,请在前面部署真实的 WSGI 服务器和身份验证系统。 ## 开发与测试 ``` cd key-kettle PYTHONPATH=src python -m pytest -q ``` 测试快速且完全离线(无网络,无睡眠):Flask 端点通过进程内测试客户端进行测试。测试范围涵盖分析器(评分、定级边界、全清单不变性)、策略验证器(范围和类型拒绝、弱默认填充、关键警告)、CLI(退出代码、JSON 纯净度、文件/stdin 处理、大小上限、环回限制)以及应用程序(错误输入返回 400 而非 500、超大返回 413、安全标头)。 **布局** ``` key-kettle/ src/key_kettle/ policy.py # PasswordPolicy dataclass, validation, sample baselines analyzer.py # 11 controls → scored PolicyReport ui.py # shared rich theme, banner, report renderer cli.py # sample-policy / analyze / serve app.py # Flask JSON input + report UI (hardened) templates/ tests/ ``` ## 🏷️ 为什么叫 "Key Kettle"? 把策略放在壶里煮沸,看看能剩下什么。大多数密码规则都是在合规文档之间流传的民俗,它们的目标是“看起来很严格”而不是“真正很强”。NIST 在 2017 年重写了其指南;令人吃惊的是,大量的密码策略根本没收到通知。该工具根据从 NIST、OWASP 和 CISA 提取的 11 项控制措施来审计你的策略——并为每一个问题都引用了来源,这样在会议开始之前,你就已经赢得了关于修复方案的争论。 ## 🔬 此工具的构建方式 **目的。** 一款密码策略审计工具,其输出像一份完整的、按优先级分诊排序的清单,而不是一堆抱怨。与 NIST/OWASP/CISA 对齐的 11 项控制措施中的每一项都会报告通过或失败,并附带引用的修复方案。 **工作原理。** 它接收一个策略(JSON 文件、stdin 或生成的 `sample-policy`),验证并强制转换字段,评估全部 11 项控制措施,对结果进行评分和定级,并按最差优先对建议进行排序。相同的数据驱动着 CLI 表格、JSON 和本地报告 UI。 **出色的 CLI。** 带有评分/定级摘要面板的颜色编码、按分诊排序的表格;对于机器命令,横幅会输出到 stderr,从而保持 stdout 可通过管道传输;`--policy -` 从 stdin 读取,因此 `sample-policy | analyze --policy -` 可以正常工作;而 `--fail-under SCORE` 将 `analyze` 变成了一个可调节的 CI 检查关卡。 **关键改进。** *功能性:* 审计现在会将**每一项**控制措施报告为通过或失败(共 11 项),而不是仅仅列出问题,因此你可以看到完整的安全态势;对范围和类型进行严格的 `PolicyError` 验证;真实世界的类型强制转换(布尔字符串,`0`/`""`/`null` 作为禁用的轮换);扩展了 `GOOD_HASHES` 以包含 argon2i/argon2d。*安全性:* `serve` 拒绝在没有 `--allow-nonlocal` 的情况下进行非环回绑定(UI 没有身份验证且会评估粘贴的 JSON),并拒绝在环回网络之外使用 `--debug`;`MAX_CONTENT_LENGTH` 限制为 256 KiB 并在处理器内进行二次检查;CLI 将读取大小限制在 1 MiB;严格的 CSP 以及标准标头集。 **示例。** ``` PYTHONPATH=src python -m key_kettle.cli sample-policy --strong \ | PYTHONPATH=src python -m key_kettle.cli analyze --policy - ``` ## ⚖️ 授权使用与安全准则 **这些是用于你拥有或被明确授权评估的系统、文件、网络和人员的防御性工具。** 在运行任何程序之前,请阅读本声明: - **授权不是可选的。** 钓鱼演练、网络扫描、IP 信誉查询和 Web 应用程序探测都会涉及他人的系统或数据。请首先获得书面授权。有几种工具在你声明之前*拒绝执行任何操作*(`--yes`, `--authorized-training`, `--i-have-authorization`, `--i-am-authorized` 等)。 - **默认安全。** 每个 Web UI 都绑定到 `127.0.0.1` (环回网络)。出站流量、实时发送和主动扫描都被限制在明确的标志之后——空运行 (dry-run)、被动模式或拒绝并警告始终是默认设置。 - **避免意外的自毁操作。** Flask `--debug`(Werkzeug 交互式调试器在任何堆栈跟踪上都可以执行远程代码执行)会受到明确的警告,并且在环回网络之外会被完全拒绝。不可信的输入受到大小限制和验证,并被无害化渲染,因此充满恶文件或日志行不会导致崩溃——或接管——你的终端。 - **输出中不含机密。** API key 保留在请求标头中,密码来自环境变量,不会记录或打印任何敏感信息。 这些不是攻击性工具。它们不包含任何漏洞利用、凭证收集器或 payload。如果某个工具*可能*被滥用,那么它在构造上就被设计为能够抵御此类滥用。 ## 🧪 开发 ``` python -m venv .venv && source .venv/bin/activate pip install -e . pytest -q # 49 tests, no network, no sleeps key-kettle --help ``` ## 📄 许可证 基于 **MIT License** 发布。参见 [LICENSE](LICENSE)。
防御性工具。不包含漏洞利用、payload 或凭证收集器。
标签:Python, Web界面, 安全合规, 安全基线检查, 密码策略审计, 无后门, 网络代理, 逆向工具