WimLee115/wimsalabim

GitHub: WimLee115/wimsalabim

一款完全本地运行、默认被动且具备授权门控机制的网站安全与隐私侦察工具,生成可签名、可验证的审计级报告。

Stars: 0 | Forks: 0

wimsalabim — PVNL · Captain WimLee115 # `wimsalabim` ### **诚实、可审计级别的网站安全与隐私侦察。** #### *意图即代码 · 证据即输出 · 没有机器学习的Cargo Cult · 没有遥测* [![License: AGPL-3.0](https://img.shields.io/badge/license-AGPL--3.0-darkgreen?style=for-the-badge)](LICENSE) [![Python](https://img.shields.io/badge/python-3.10%20|%203.11%20|%203.12%20|%203.13-blue?style=for-the-badge)](https://www.python.org/downloads/) [![PVNL](https://img.shields.io/badge/under-PVNL_flag-orange?style=for-the-badge)](https://github.com/WimLee115/Privacy-VerzetNL) [![CI](https://img.shields.io/badge/CI-passing-success?style=flat-square)](.github/workflows/ci.yml) [![Coverage](https://img.shields.io/badge/coverage-76%25-green?style=flat-square)](#testing--coverage) [![Mypy](https://img.shields.io/badge/mypy-strict-blue?style=flat-square)](#typing) [![Ruff](https://img.shields.io/badge/lint-ruff_strict-darkblue?style=flat-square)](#linting) [![Bandit](https://img.shields.io/badge/security-bandit_clean-success?style=flat-square)](#security-audit) [![No-Telemetry](https://img.shields.io/badge/telemetry-zero-black?style=flat-square)](#privacy-guarantees) [![Reports](https://img.shields.io/badge/reports-Ed25519_signed-blueviolet?style=flat-square)](#cryptographic-integrity) [![SARIF](https://img.shields.io/badge/output-SARIF_2.1-darkblue?style=flat-square)](#output-formats)
## 一句话概述 ## 目录
**入门指南** - [为什么选择 `wimsalabim`](#why-wimsalabim) - [30 秒教程](#30-second-tour) - [安装](#installation) - [快速开始](#quick-start) **功能特性** - [十大升级](#the-ten-upgrades) - [内置分析器](#built-in-analyzers) - [输出格式](#output-formats) - [授权路径](#authorization-paths) - [密码学完整性](#cryptographic-integrity) - [监控列表模式](#watchlist-mode) **内部机制** - [架构](#architecture) - [Schema 与契约](#schema--contracts) - [风险引擎](#the-risk-engine) - [插件开发](#plugin-development) - [隐私保障](#privacy-guarantees) **运维指南** - [配置](#configuration) - [性能与资源](#performance--resources) - [故障排除](#troubleshooting) - [常见问题解答](#faq) **合规性** - [法律合规](#legal-compliance) - [威胁模型](#threat-model) - [安全审计](#security-audit) **开发指南** - [作为库使用](#use-as-a-library) - [贡献指南](#contributing) - [测试与覆盖率](#testing--coverage) - [发布流程](#releasing) - [路线图](#roadmap) **参考信息** - [与其他工具的对比](#comparison-with-other-tools) - [许可证](#license) - [引用](#citation) - [致谢](#acknowledgements)
## 为什么选择 `wimsalabim` 网站安全扫描器领域已经非常拥挤。大多数工具不外乎以下三类: | 类别 | 示例 | 问题 | | ----------------------- | ---------------------------------- | ------------------------------------------------------------- | | **SaaS 扫描器** | SecurityHeaders, SSL Labs, Detectify | 会将你的目标列表发送给第三方。用于公开规范检查没问题;但不适用于敏感范围。 | | **大型攻击性框架** | Nuclei, Burp, ZAP | 默认采取主动行为。功能强大,但前提是你了解自己的法律边界。 | | **单域名 CLI 工具** | sslyze, testssl.sh, dnsrecon | 各管一摊。需要你自己拼凑。 | `wimsalabim` 则属于另一个类别:**一个单一且固执己见的 CLI 工具,它:** 1. **完全在本地运行** —— 没有向 SaaS 的扇出,没有遥测,没有分析。 2. **默认被动** —— 主动分析器会拒绝运行,除非你证明已获授权。 3. 生成**经过签名的、确定性的、机器可读的报告**,可作为取证证据。 4. 使用**透明的基于规则的风险引擎** —— 每一个评分对于非技术读者(或法官)都是可解释的。 5. 附带**严格的类型检查、测试和安全审计**,使工具本身达到它对目标所要求的标准。 如果你需要一个能经得起偏执的 CISO 代码审查的扫描器,就是它了。 ## 30 秒教程 ``` # 安装 pipx install wimsalabim # 扫描域名(仅被动扫描 — 适用于任何目标) wimsalabim scan example.com # 获取用于 CI 的 JSON wimsalabim scan example.com --format json -o report.json # 签名报告 (Ed25519) wimsalabim keys init wimsalabim scan example.com --sign --format json -o signed.json wimsalabim verify signed.json # → ✓ valid # 主动端口扫描(需要授权证明) wimsalabim scan example.com \ --auth-self-owned ./my-domains.txt \ --enable ports ``` 示例输出: ``` ─────────────────────────── wimsalabim · example.com ─────────────────────────── target example.com started 2026-05-10T02:04:30Z duration 363 ms dns_recon grade A 1 finding(s) 205 ms ┏━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ ┃ sev ┃ id ┃ title ┃ ┡━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ │ low │ dns.caa.absent │ No CAA record │ └──────────┴────────────────┴───────────────┘ headers grade D 7 finding(s) 351 ms […] ╭─────────────────── RISK B 28.0/100 engine=rules ────────────────────╮ │ Grade B (28.0/100) — 1 high — 4 rule(s) fired total. │ │ ● WSL-HEADERS-001 +12 Strict-Transport-Security header missing │ │ → HSTS absent — downgrade attacks possible on first connect. │ │ […] │ ╰─────────────────────────────────────────────────────────────────────────╯ ``` ## 安装 ### 推荐:`pipx` ``` pipx install wimsalabim ``` ### 备选:虚拟环境中的 `pip` ``` python -m venv .venv source .venv/bin/activate pip install wimsalabim ``` ### 从源码安装 ``` git clone https://github.com/WimLee115/wimsalabim.git cd wimsalabim pip install -e ".[dev]" ``` ### 可选依赖 | 功能 | 安装命令 | | ---------------------- | ---------------------------------------------------- | | OpenTimestamps 锚点 | `pipx install opentimestamps-client` | | Tor 传输 | 运行中的本地 Tor 守护进程(端口 9050) | ### 支持的环境 | 操作系统 | Python | 状态 | | ---------- | --------------------------------- | ------ | | Linux | 3.10 / 3.11 / 3.12 / 3.13 | ✓ CI | | macOS | 3.10 / 3.11 / 3.12 / 3.13 | ✓ CI | | Windows | 3.10 / 3.11 / 3.12 / 3.13 | ✓ CI | | FreeBSD | 3.11+ | 尽力支持 | ## 快速开始 ``` # 显示帮助和全局选项 wimsalabim --help # 列出所有已注册的 analyzers 及其法律类别 wimsalabim analyzers # 纯净的被动扫描(DNS + TLS + headers,无端口扫描) wimsalabim scan example.com # 选择特定的 analyzers wimsalabim scan example.com --enable dns_recon --enable headers # 跳过嘈杂的项 wimsalabim scan example.com --disable headers # 输出格式 wimsalabim scan example.com --format json wimsalabim scan example.com --format markdown wimsalabim scan example.com --format sarif # 在终端渲染的同时保存报告 wimsalabim scan example.com --format json -o report.json # 验证已签名的报告 wimsalabim verify signed-report.json # 管理签名密钥 wimsalabim keys init wimsalabim keys show ``` ## 十大升级 `wimsalabim v0.2.0` 是对 v0.1 的彻底重构。以下每一个支柱都是对先前设计的深思熟虑后的偏离: | # | 支柱 | 实现方式 | | -- | ------------------------------------- | ----------------------------------------------------------------------------- | | 01 | **授权门控** | 主动分析器在没有经过验证的证明下会拒绝运行。参见[法律合规](#legal-compliance)。 | | 02 | **溯源引擎** | 每个 `Finding` 都带有一个 `Source` 块(类型、目标、时间戳、正文哈希)。 | | 03 | **加密签名报告** | 基于 RFC-8785 规范 JSON 的 Ed25519 签名;可选 OpenTimestamps 锚点。 | | 04 | **诚实风险引擎** | 基于规则、可追溯、可解释。没有带硬编码 `training_samples=500` 的 `IsolationForest` 装饰。 | | 05 | **插件架构** | `@analyzer(...)` 装饰器 + 能力清单;显式注册。 | | 06 | **标准感知导出** | SARIF 2.1.0、规范 JSON、GitHub 风格 Markdown、富终端。 | | 07 | **监控列表模式** | SQLite 快照 + 随时间推移的差异检测。 | | 08 | **隐私优先设计的基础设施** | 在 HTTP 客户端层面强制执行的遥测黑名单;默认隐去 WHOIS 个人身份信息(PII)。 | | 09 | **严格的 QA** | `mypy --strict`,`ruff` 40 多条规则集,`bandit`,`pip-audit`,≥ 70% 测试覆盖率。 | | 10 | **华丽的 TUI** | Rich 实时渲染、颜色分级、结构化面板。 | ## 内置分析器 | 分析器 | 法律类别 | 用途 | | ------------ | ----------- | ---------------------------------------------------------------------- | | `dns_recon` | passive | A / AAAA / MX / NS / TXT / SOA / CNAME / CAA + DNSSEC 状态 | | `tls` | passive | 单次 TLS 握手;叶证书有效性、过期时间、协议、密码套件 | | `headers` | passive | 单次 GET 请求;安全与信息泄露头 | | `ports` | **active** | 在保守的端口集上进行异步 TCP 连接扫描(需要授权) | **法律类别语义:** - **passive** —— 仅使用公开数据(DNS、CT、WHOIS、单次 GET 请求、单次 TLS 握手)。不属于荷兰法律 Sr 138ab 所规定的 "binnendringen"(非法侵入)。 - **active** —— 执行超出普通客户端范畴的网络探测。除非 `Authorization` 证明操作者拥有目标所有权或正在运行授权的漏洞赏金计划,否则将被拒绝执行。 - **intrusive** —— 可能会改变或给目标状态造成压力的任何操作。除非获得授权**并且**提供了 `--allow-intrusive`,否则将被拒绝执行。 ## 输出格式 ### Rich(默认) 带颜色编码、表格化的终端输出,并在最后附带一个风险面板。支持 `NO_COLOR` 和 `TERM=dumb` 环境变量。 ### JSON(规范格式) ``` wimsalabim scan example.com --format json -o report.json ``` - RFC-8785 规范键排序(已排序,无多余空格)。 - ISO-8601 UTC 时间戳。 - Schema 版本:`wimsalabim/2.0`。 - 幂等性:相同的输入 + 相同的日内时间会产生逐字节完全相同的输出(`started_at` 除外)。 ``` { "schema_version": "wimsalabim/2.0", "tool_version": "0.2.0", "target": "example.com", "started_at": "2026-05-10T02:04:30Z", "duration_ms": 363.0, "config_hash": "ea1b…", "analyzers": { "dns_recon": { "name": "dns_recon", "legal_class": "passive", "status": "ok", "report": { "analyzer": "dns_recon", "grade": "A", "findings": [{"id": "dns.caa.absent", "severity": "low", …}], "metadata": {"dnssec": true, "total_records": 9} } } }, "risk": { "engine": "rules", "overall_score": 28.0, "grade": "B", "rules_fired": [{"rule_id": "WSL-HEADERS-001", …}] } } ``` ### Markdown GitHub 风格,适合直接发布在 PR 评论或 issue 中: ``` wimsalabim scan example.com --format markdown ``` ### SARIF 2.1.0 适用于 GitHub Code Scanning、GitLab Security Dashboard、Defect Dojo: ``` wimsalabim scan example.com --format sarif -o sarif.json # 上传至 GitHub Code Scanning: gh codeql database upload sarif.json ``` 发现项包含 CWE-id 以及(适用的)CVSS 向量,以便接收系统能正确地进行优先级排序。 ## 授权路径 有三种方式可以证明你有权对目标运行主动分析器。任选其一;验证失败会有明显提示。 ### 1 · 自有清单 包含每行一个主机的本地文件: ``` # my-domains.txt example.com api.example.com internal.lab.example.com ``` ``` wimsalabim scan api.example.com \ --auth-self-owned ./my-domains.txt \ --enable ports ``` 用例:拥有独立所有权证据的开发/CI 环境。 ### 2 · DNS TXT 记录 在 `_wimsalabim-auth.` 处发布一条 TXT 记录: ``` _wimsalabim-auth.example.com. IN TXT "v=wimsalabim1 pubkey=" ``` ``` wimsalabim scan example.com \ --auth-dns-txt "" \ --enable ports ``` 用例:每位研究人员拥有稳定公钥的漏洞赏金计划。 ### 3 · Well-known 文件 将已签名的清单发布在 `https:///.well-known/wimsalabim-auth.txt`: ``` v=wimsalabim1 pubkey= sig= target=example.com ``` ``` wimsalabim scan example.com \ --auth-well-known "" \ --enable ports ``` 用例:偏好基于文件声明的漏洞赏金计划(HackerOne 风格)。 ## 密码学完整性 ### 签名 ``` wimsalabim keys init wimsalabim scan example.com --sign --format json -o signed.json ``` 执行流程: 1. 报告被规范化(RFC 8785)。 2. 剥离 `signature` 和 `signing_pubkey` 字段。 3. 对剩余字节进行 SHA-256 哈希。 4. 使用 Ed25519 签名该哈希(私钥位于 `~/.wimsalabim/keys/signing.key`,权限为 0600)。 5. 将签名和公钥重新添加回 JSON 中。 ### 验证 ``` wimsalabim verify signed.json ``` 输出: ``` ✓ valid pubkey a4er2DIQ/HIwnIHp… digest 0ea1269b8089d100… ``` 如果报告被篡改: ``` ✗ INVALID signature $ echo $? 2 ``` ### 使用 OpenTimestamps 锚定(可选) ``` # 安装上游客户端 pipx install opentimestamps-client # 计算摘要,并加盖时间戳 sha256sum signed.json | awk '{print $1}' > signed.digest ots stamp signed.digest # 等待几个小时以完成升级 ots upgrade signed.digest.ots # 根据 Bitcoin 区块头进行验证 ots verify signed.digest.ots ``` `.ots` 证明是一个锚定在比特币链上的客观可验证时间戳。无需信任任何单一方。 ## 监控列表模式 `wimsalabim watch` 子命令按固定间隔重新扫描一个或多个目标,将每次结果持久化到 SQLite 基线中,并与上一次快照进行对比报告差异(新增/移除的发现项、评级变化)。 ``` # 每小时扫描 example.com,默认数据库位于 ~/.wimsalabim/watch.sqlite wimsalabim watch example.com # 多个目标,15分钟间隔,仅打印存在差异的轮次 wimsalabim watch --interval 900 --diff-only a.example b.example # 一次性冒烟测试(记录基线 + 退出) wimsalabim watch --once example.com ``` 在收到 `SIGINT` / `SIGTERM` 时会干净地停止。失败的扫描不会导致守护进程崩溃;它会记录错误并继续处理下一个目标。授权选项(`--auth-self-owned`、`--auth-dns-txt`、`--auth-well-known`)在启动时对每个目标进行一次验证。 ### 编程式使用 ``` from pathlib import Path import asyncio from wimsalabim.core.orchestrator import Orchestrator, OrchestratorConfig from wimsalabim.core.authorization import AuthorizationGate from wimsalabim.core.registry import all_analyzers import wimsalabim.analyzers # registers built-ins from wimsalabim.watch import BaselineStore store = BaselineStore(Path("./baseline.sqlite")) async def watch(target: str) -> None: orch = Orchestrator( config=OrchestratorConfig(target=target, enabled=("dns_recon", "tls", "headers")), registrations=list(all_analyzers().values()), gate=AuthorizationGate(), ) report = await orch.run() diff = store.diff_against_previous(report) if diff and diff.is_meaningful: notify(diff) store.record(report) asyncio.run(watch("example.com")) ``` `Diff` 对象列出了每个分析器新增的发现项、移除的发现项以及评级变化。 ## 架构 ``` %%{init: {'theme':'dark'}}%% flowchart TD CLI["CLI
(click)"] Orch["Orchestrator
(async, per-analyzer timeout)"] Gate["AuthorizationGate
(legal_class check)"] HTTP["HTTP client factory
(telemetry blacklist hook)"] Reg["Registry
(@analyzer decorator)"] Risk["HeuristicRiskEngine
(rule-based)"] Disp["Renderers
rich · json · md · sarif"] Crypto["Ed25519 sign/verify
+ OTS anchor"] CLI --> Orch Orch --> Gate Orch --> HTTP Orch --> Reg Reg -.-> A1["dns_recon"] Reg -.-> A2["tls"] Reg -.-> A3["headers"] Reg -.-> A4["ports (active)"] Orch --> Risk Risk --> Disp Disp --> Crypto classDef gate fill:#221,stroke:#fc6,color:#fff class Gate gate ``` ### 模块分解 ``` src/wimsalabim/ ├── cli.py Click entrypoint, slim ├── analyzers/ │ ├── base.py BaseAnalyzer ABC + AnalysisContext │ ├── dns_recon.py DNS analyzer (passive) │ ├── tls.py TLS analyzer (passive) │ ├── headers.py HTTP headers analyzer (passive) │ └── ports.py TCP-connect scan (active) ├── core/ │ ├── schema.py Pydantic v2 frozen models │ ├── exceptions.py Typed exception hierarchy │ ├── logging.py structlog setup │ ├── registry.py @analyzer + capabilities │ ├── authorization.py AuthorizationGate + verification helpers │ ├── orchestrator.py Async runner with timeouts │ ├── http_client.py httpx factory + telemetry guard │ ├── privacy.py WHOIS redact + telemetry blacklist │ ├── canonical.py RFC 8785 canonical JSON │ ├── crypto.py Ed25519 sign/verify │ └── timestamps.py OpenTimestamps wrapper ├── risk/ │ ├── rules.py Rule registry │ └── heuristic.py Rule executor + grading ├── display/ │ ├── rich_renderer.py Rich terminal output │ ├── markdown.py GitHub Markdown export │ └── sarif.py SARIF 2.1.0 export └── watch/ └── baseline.py SQLite snapshot store + Diff ``` ## Schema 与契约 分析器产生的每个 `BaseReport` 都满足此契约: ``` class BaseReport(BaseModel): model_config = ConfigDict(frozen=True, extra="forbid") analyzer: str target: str started_at: datetime # always UTC duration_ms: float # ≥ 0 grade: Grade = "N/A" # Literal["A","B","C","D","F","N/A"] findings: list[Finding] metadata: dict[str, str|int|float|bool] ``` 每个 `Finding` 都带有溯源信息: ``` class Finding(BaseModel): id: str # e.g. "tls.cert.expiring_soon" title: str description: str severity: Severity # Literal["critical","high","medium","low","info"] source: Source # required cwe: str | None # CWE-NNN cvss_vector: str | None # CVSS v4.0 if applicable cvss_score: float | None # 0.0–10.0 remediation: str | None references: list[str] ``` 每个 `Source` 都回答了*这是从哪里来的*: ``` class Source(BaseModel): kind: str # "http","dns","tls","ct_log","whois",… target: str timestamp: datetime # always UTC body_sha256: str | None # 64-hex when applicable metadata: dict[str, str] ``` 这些是 pydantic v2 的冻结模型 —— 一旦生成,即不可变。这正是让我们能够安全地对它们进行哈希、签名和时间戳戳记的原因。 ## 风险引擎 两种引擎,都很诚实: ### `--engine=rules`(默认) 分数中的每一分都可以追溯到具有 id、、CWE 和依据的已注册 `Rule`。添加规则只需向 `src/wimsalabim/risk/rules.py` 中的 `RULE_REGISTRY` 追加即可。 ``` Rule( rule_id="WSL-TLS-002", name="TLS certificate expiring within 7 days", severity="critical", points=25.0, cwe="CWE-298", predicate=lambda r: _has_finding(r, "tls", "tls.cert.expiring_soon"), rationale_fn=lambda _: "Leaf certificate expires within 7 days — outage risk imminent.", ) ``` 评级是**严重性感知**的:任何未缓解的 Critical(严重)问题都会将最终评级拉低到 D 或更差,即使原始分数总和落在 C 区也是如此。这反映了理性的操作者在现实中如何对待 Critical 级别问题。 ### `--engine=ml`(计划中,视条件而定) 只有当满足以下所有条件时,我们才会发布 `ml` 引擎: - 仓库中包含真实的模型文件(`models/risk_v0.X.onnx`)并发布了 SHA-256。 - 包含 `model_card.md`,描述训练数据、特征、预期准确率和已知偏差。 - 可复现的训练:数据集哈希、训练脚本、固定种子、训练/验证/测试划分。 - 验证保留样本模型预测的测试套件。 在这些实现之前,**没有 ML 引擎**。以前版本的 "ML 模块" 只是导入了 sklearn 类却从未训练——这是不诚实的,已被移除。 ## 插件开发 ### 编写你自己的分析器 ``` # my_org/scanners/cookie_audit.py from datetime import datetime, timezone from wimsalabim.analyzers.base import AnalysisContext, BaseAnalyzer from wimsalabim.core.exceptions import NetworkError from wimsalabim.core.registry import Capabilities, analyzer from wimsalabim.core.schema import BaseReport, Finding, Source @analyzer( "cookie_audit", legal_class="passive", capabilities=Capabilities(network=("https",), rate_limit_per_second=2, timeout_seconds=10.0), description="Inspect Set-Cookie attributes (Secure, HttpOnly, SameSite).", ) class CookieAnalyzer(BaseAnalyzer): async def analyze(self, context: AnalysisContext) -> BaseReport: started = datetime.now(tz=timezone.utc) try: response = await context.http.get(f"https://{context.target}/") except Exception as exc: raise NetworkError(kind="http", target=context.target, message=str(exc)) from exc findings: list[Finding] = [] # ... inspect response.cookies and emit findings ... return BaseReport( analyzer="cookie_audit", target=context.target, started_at=started, duration_ms=(datetime.now(tz=timezone.utc) - started).total_seconds() * 1000, findings=findings, metadata={}, ) ``` 然后在你的项目中注册它: ``` # my_project/__init__.py import my_org.scanners.cookie_audit # imports trigger @analyzer ``` ### 能力声明 | 字段 | 用途 | | ------------------------ | -------------------------------------------------- | | `network` | 你将接触的协议(`dns`、`https` 等)。授权门控会参考此信息以进行法律类别的强制执行。 | | `rate_limit_per_second` | 为编排器的限速器提供的提示(编排器级别的限速在路线图中)。 | | `timeout_seconds` | 编排器将强制执行的每次调用软超时。 | ### 法律类别 | 类别 | 何时选择它 | | ----------- | ------------------------------------------------------------ | | `passive` | 你只读取公开数据(DNS、CT、单次 GET、单次 TLS 握手)。 | | `active` | 你的探测超出了普通客户端的范畴。 | | `intrusive` | 你可能会改变目标状态(写入、模糊测试、负载)。 | 如果有疑问:选择更严格的选项。框架将拒绝在未证明授权的情况下运行你。这比引入法律风险要好。 ## 隐私保障 ``` ┌────────────────────────────────────────────────────────────────┐ │ │ │ 1. No telemetry. No analytics. No phone-home. Ever. │ │ 2. WHOIS PII (registrant name/email/phone) redacted unless │ │ --show-pii is explicitly set. │ │ 3. Bodies hashed up to 64 KB; full content never stored or │ │ transmitted. │ │ 4. Reports stored locally; signing keys local + 0600. │ │ 5. --via-tor routes both HTTP and DNS via SOCKS5+Tor. │ │ 6. --offline forbids any outbound network call. │ │ │ └────────────────────────────────────────────────────────────────┘ ``` 验证依据: - `core/privacy.TELEMETRY_BLACKLIST` 通过 `make_client()` 中的 httpx 事件钩子强制执行。 - `tests/test_no_telemetry.py`(21 个用例)静态禁止导入已知的遥测 SDK。 - `tests/test_privacy.py` 验证隐去逻辑。 ## 配置 ### 完整的 CLI 标志 ``` Usage: wimsalabim scan [OPTIONS] TARGET Options: -e, --enable TEXT Enable only these analyzers (repeatable). -d, --disable TEXT Disable these analyzers (repeatable). --via-tor Route HTTP via local Tor SOCKS5 (127.0.0.1:9050). --offline Forbid any outbound network call. --show-pii Do not redact PII (use only on data you own). --allow-intrusive Permit intrusive analyzers (extra confirmation). --auth-self-owned PATH Path to self-owned domains manifest. --auth-dns-txt TEXT Verify _wimsalabim-auth. TXT record. --auth-well-known TEXT Verify /.well-known/wimsalabim-auth.txt manifest. --format [rich|json|markdown|sarif] Output format (default: rich). -o, --output PATH Write report to file (also rendered to stdout). --sign Sign the report (Ed25519). --keys-dir PATH Signing key directory (default: ~/.wimsalabim/keys). --verbose / --quiet -h, --help Show this message and exit. ``` ### 环境变量 | 变量 | 效果 | | ------------------------ | ----------------------------------------------------------- | | `NO_COLOR` | 禁用 Rich 渲染中的颜色。 | | `WIMSALABIM_KEYS_DIR` | 覆盖默认的 `~/.wimsalabim/keys`(计划在 v0.3 中实现)。 | ### 配置文件(计划在 v0.3 中实现) `~/.config/wimsalabim/config.toml` 将允许持久化标志。在 v0.2.0 中,所有配置均通过 CLI 标志进行。 ## 性能与资源 以下数据来自在家庭宽带下对 `example.com` 的被动扫描: | 指标 | 值 | | --------------------- | ---------------------- | | 实际耗时 | ~360 毫秒 | | 并发分析器 | 3(通过 asyncio 并行) | | 峰值内存 | ~25 MB | | 出站 HTTP | 向 `https://target/` 发起 1 次 GET 请求 | | 出站 DNS | 9 次记录查询 | | 出站 TLS | 1 次握手 | | 磁盘 I/O | 1 次 SQLite 写入(如果在监控模式下),1 个 JSON 文件(如果指定了 `-o`) | `ports` 分析器的耗时随端口列表大小而变化;对于响应及时的主机,默认的 23 个端口可在 1-3 秒内完成。 ## 作为库使用 ``` import asyncio from wimsalabim.core.orchestrator import Orchestrator, OrchestratorConfig from wimsalabim.core.authorization import AuthorizationGate from wimsalabim.core.registry import all_analyzers from wimsalabim.risk.heuristic import HeuristicRiskEngine import wimsalabim.analyzers # register built-ins async def scan(target: str) -> None: orch = Orchestrator( config=OrchestratorConfig( target=target, enabled=("dns_recon", "headers"), ), registrations=list(all_analyzers().values()), gate=AuthorizationGate(), ) report = await orch.run() risk = HeuristicRiskEngine().assess(report.analyzers) print(report.model_dump_json(indent=2)) print("RISK:", risk.grade, risk.overall_score) asyncio.run(scan("example.com")) ``` 稳定的公共 API 接口(自 v1.0 起遵循 semver): - `wimsalabim.core.schema` — `Source`、`Finding`、`BaseReport`、`ScanReport`、`RiskAssessment`、… - `wimsalabim.core.orchestrator` — `Orchestrator`、`OrchestratorConfig` - `wimsalabim.core.authorization` — `AuthorizationGate`、`Authorization` - `wimsalabim.core.registry` — `analyzer` 装饰器、`Capabilities`、`all_analyzers` - `wimsalabim.risk.heuristic` — `HeuristicRiskEngine` - `wimsalabim.display` — `render_rich`、`render_markdown`、`render_sarif` - `wimsalabim.watch` — `BaselineStore`、`Diff` ## 法律合规 ### 荷兰 Sr 第 138ab 条 — 计算机犯罪 `AuthorizationGate` 拒绝在没有经过验证的证明的情况下运行 `active` 和 `intrusive` 分析器。CLI 中没有逃生舱——没有 `--yolo`,也没有 `--force`。这是 *binnendringen alleen met toestemming*(仅在获得许可时侵入)原则的技术实现。 ### 欧盟 GDPR / 荷兰 AVG | 条款 | 我们的遵守方式 | | ---------- | --------------------------------------------------------------------- | | 第 5 条 | 数据最小化:正文被哈希处理(不存储原文),WHOIS 个人隐私信息被隐去。 | | 第 6 条 | 我们仅处理公开数据及操作者控制的目标。 | | 第 25 条 | 隐私保护设计:在 HTTP 客户端层强制执行遥测黑名单。 | | 第 32 条 | 处理过程的安全性:签名报告,本地 0600 权限的密钥。 | ### 欧盟 AI 法案 `HeuristicRiskEngine` 在 AI 法案下**不属于 AI 系统**: - 没有学习到的模型。没有训练。没有统计泛化。 - 每一个分数都确定性地源自一个已注册的规则。 - 完全可解释;没有缺乏人类可读谓词的“自动化决策”。 如果我们未来发布 `--engine=ml`,它将同样通过此可解释性测试,并附上数据集和模型卡片。 ### NCSC 负责任的披露 由 `wimsalabim` 产生的发现项: 1. 生成一份带有签名的 JSON 或 SARIF 报告。 2. 发送给目标的安全联系人(首先查找 `security.txt`,然后依据 `RFC 9116`)。 3. 适用 90 天的披露窗口(行业标准),除非接收方要求更短的时间。 ## 威胁模型 我们使用 STRIDE 进行自我分析。完整表格见 [`docs/PENTEST_REPORT.md`](docs/PENTEST_REPORT.md)。概要: | 威胁 | 状态 | 缓解措施 | | ----------------------- | ------------- | ------------------------------------------------------------ | | 操作者身份欺骗 | 已缓解 | 授权路径要求由操作者控制的 DNS/文件。 | | 报告被篡改 | 已缓解 | 基于 Ed25519 签名的规范 JSON + 通过 `verify` 进行篡改检测。 | | 抵赖 | 已缓解 | 报告中的 `signing_pubkey` + `verified_at` 块。 | | 信息泄露 | 已缓解 | WHOIS 个人隐私信息隐去,限制正文哈希,无遥测。 | | 通过缓慢的分析器发起的 DoS | 已缓解 | 由编排器强制执行的单分析器超时。 | | 权限提升 | 已缓解 | `AuthorizationGate.check()` 是强制性的且默认拒绝。 | ## 安全审计 完整的渗透测试报告已提交至仓库中的 [`docs/PENTEST_REPORT.md`](docs/PENTEST_REPORT.md)。 摘要: | 工具 | 结果 | | ------------ | --------------------------------------- | | `mypy --strict` | 30 个源文件 0 个错误 | | `ruff`(40 多条规则集) | 所有检查通过 | | `bandit` | 5 个低级(OTS 中可接受的子进程),0 个中级,0 个高级 | | `pip-audit` | 没有已知漏洞 | | `pytest` | 118 / 118 通过 | | 覆盖率 | 76.42%(超过 70% 阈值) | 手动审查涵盖了 SSRF、路径遍历、命令注入、正则表达式 DoS、竞态条件、机密/凭证泄露。**零 Critical 或 High 级别发现。** ## 与其他工具的对比 | 功能 | `wimsalabim` | `nuclei` | `sslyze` | `dnsrecon` | SecurityHeaders.com | | ---------------------------------------- | ------------ | -------- | -------- | ---------- | ------------------- | | 本地执行(非 SaaS) | ✓ | ✓ | ✓ | ✓ | ✗ | | 默认被动且具有硬性门控 | ✓ | ✗ | n/a | n/a | ✓ | | 签名报告 (Ed25519) | ✓ | ✗ | ✗ | ✗ | ✗ | | OpenTimestamps 锚点 | ✓ (可选) | ✗ | ✗ | ✗ | ✗ | | SARIF 2.1.0 输出 | ✓ | ✓ | ✗ | ✗ | ✗ | | Pydantic 验证的 schema | ✓ | partial | ✗ | ✗ | n/a | | 基于规则的可解释风险评分 | ✓ | (按模板) | ✗ | ✗ | ✓ (不透明) | | WHOIS 个人隐私信息默认隐去 | ✓ | n/a | n/a | n/a | n/a | | `mypy --strict` 纯净 | ✓ | n/a (Go) | partial | ✗ | n/a | | 用于自定义分析器的插件 API | ✓ | ✓ | ✗ | ✗ | ✗ | 其他工具的卓越之处: - **nuclei**:庞大的漏洞检测模板生态系统。我们是补充,而不是替代。 - **sslyze**:更深度的 TLS 分析(我们只做单次握手;sslyze 会进行密码套件枚举)。 - **dnsrecon**:更多的 DNS 模式(区域传送、暴力破解)——按设计,我们保持被动。 ## 测试与覆盖率 ``` make test # full suite + coverage make lint # ruff check + format make typecheck # mypy --strict make audit # bandit + pip-audit make all # everything in CI order ``` 不使用 `make` 的情况下: ``` pytest -v # 118 tests pytest --cov=wimsalabim --cov-report=term-missing # with coverage ruff format --check src tests ruff check src tests mypy src bandit -r src --severity-level low pip-audit ``` ### 类型检查 严格度: ``` [tool.mypy] strict = true disallow_untyped_defs = true disallow_any_generics = true warn_unused_ignores = true warn_redundant_casts = true warn_unreachable = true no_implicit_optional = true ``` 结果:整个代码库中存在 **0 个错误**。 ### 代码检查 活跃的规则集:`E`、`F`、`W`、`I`、`N`、`UP`、`B`、`C4`、`SIM`、`RUF`、`ASYNC`、`TRY`、`PTH`、`PL`。结果:**0 个违规**。 ## 发布流程 1. 在 `pyproject.toml` 中提升 `version`。 2. 更新 [`CHANGELOG.md`](CHANGELOG.md)。 3. 打标签:`git tag -s v0.X.Y -m "release v0.X.Y"`。 4. 推送标签:`git push origin v0.X.Y`。 5. 发布 CI 将构建 wheels + sdist,运行测试 + 审计,对构件签名,并上传到 PyPI。 (发布 CI 工作流目前处于[计划阶段](#roadmap) —— 当前通过 `make build` 在本地生成构件。) ## 路线图 ``` 2026 Q2 · Public release of v0.2.0 [DONE] 2026 Q2 · `wimsalabim watch` CLI subcommand [DONE] 2026 Q2 · Mock TLS server for tls.py coverage ≥ 85% [next] 2026 Q2 · Socket-mock fixture for ports.py coverage ≥ 85% 2026 Q2 · Periodic re-verification of authorization in watch sessions 2026 Q3 · CycloneDX VEX export 2026 Q3 · Mutation testing (mutmut) with ≥ 80% kill rate 2026 Q3 · Atheris fuzzing on parsers (cert, headers) 2026 Q4 · Remediation wizard (interactive --fix flow) 2026 Q4 · Shell completions (bash / zsh / fish) 2027 · PQC hybrid keys (X25519 + ML-KEM) 2027 · Distributed-watch federation across PVNL operators ``` ## 故障排除 ### 扫描输出中显示 `denied` 这意味着 `AuthorizationGate` 拒绝了某个主动分析器。你可以: - 仅使用被动分析器:`--enable dns_recon --enable headers --enable tls`。 - 提供授权证明:`--auth-self-owned`、`--auth-dns-txt` 或 `--auth-well-known`。 ### `OpenTimestampsUnavailable: 未找到 ots CLI` 安装上游客户端: ``` pipx install opentimestamps-client ``` OTS 锚定是可选的;`wimsalabim` 的其余部分可以在没有它的情况下正常工作。 ### `NetworkError: 已拦截:目标位于遥测黑名单中` 你扫描的域名与遥测黑名单存在重叠(例如 `*.google-analytics.com`)。这是故意的 —— `wimsalabim` 不会与已监控端点通信。如果你确实需要扫描此类主机,这超出了本工具的范围。 ### `httpx.ConnectError: 所有连接尝试均失败` 目标在你的网络中不可达。请检查网络连通性、DNS 和防火墙。 ### 对未签名报告的签名验证失败 `wimsalabim verify` 要求同时包含 `signature` 和 `signing_pubkey` 字段。请在生成时使用 `--sign`。 ## 常见问题解答 ### 为什么不直接用 `nmap` + `sslyze` + `dnsrecon`? 你可以这么做。我们需要的是一个这样的工具: - 在设计上拒绝未经授权的主动扫描。 - 生成一份单一的签名报告,而不是三个文本日志。 - 在 CI 中运行且不需要 root 权限。 ### 为什么没有 GUI? CLI 工具可以进行组合;而 GUI 不能。`--format markdown` 的输出在任何 Markdown 查看器中都能很好地渲染;SARIF 可以直接被 GitHub/GitLab 仪表盘消费。 ### 为什么用 Python 而不是 Go/Rust? 速度不是瓶颈——网络 I/O 才是。带有 asyncio 的 Python 足够快,而且生态系统(pydantic、rich、structlog、click)让我们能快速获得安全性和用户体验。如果基准测试有要求,我们可能会用 Rust 重写热点路径。 ### 我可以在 CI 中运行它吗? 可以。固定版本,使用 `--format sarif` 上传到 GitHub Code Scanning,并使用 `--auth-self-owned` 配合提交到你仓库的清单文件。工作流示例片段: ``` - name: Wimsalabim scan run: | pipx install wimsalabim wimsalabim scan ${{ vars.TARGET_DOMAIN }} \ --auth-self-owned ./security/owned-domains.txt \ --format sarif -o sarif.json - uses: github/codeql-action/upload-sarif@v3 with: { sarif_file: sarif.json } ``` ### 这能替代真正的渗透测试吗? 不能。它能抓住简单的 80%。真正的渗透测试能发现困难的 20%(身份验证流缺陷、业务逻辑错误、复杂的漏洞利用链)。请两者并用。 ## 贡献指南 我们欢迎各种贡献。请阅读 [`CONTRIBUTING.md`](CONTRIBUTING.md) 和 [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md)。 快速开始: ``` git clone https://github.com/WimLee115/wimsalabim.git cd wimsalabim make dev # creates venv, installs dev deps, hooks make all # lint + typecheck + test + audit ``` 我们正在寻找以下方面的贡献: - 新的被动分析器(cookie 审计、security.txt、robots.txt、sitemap.xml 等)。 - `tls.py` 和 `ports.py` 的模拟夹具以提升覆盖率。 - 为现有发现项添加更多 CWE/CVSS 映射。 - 面向用户的字符串翻译(目前我们呈现的是英文)。 我们不接受以下内容: - 没有明确授权说明的主动攻击功能。 - 遥测、分析或回传电话。 - 没有发布模型卡片作为支撑的“AI”功能。 ## 安全披露 关于 `wimsalabim` 本身的漏洞:参见 [`SECURITY.md`](SECURITY.md)。90 天的披露窗口。 ## 许可证 代码采用 **AGPL-3.0-or-later** 许可;文档采用 **CC BY-SA 4.0** 许可。 详见 [`LICENSE`](LICENSE)。 ## 引用 如果你在学术工作中使用了 `wimsalabim`,请引用: ``` @software{wimsalabim_2026, title = {wimsalabim: Honest, audit-grade website security and privacy reconnaissance}, author = {WimLee115}, year = {2026}, url = {https://github.com/WimLee115/wimsalabim}, note = {Under PVNL flag — Privacy Verzet NL} } ``` 提供了 `CITATION.cff` 文件,以便自动引用工具使用。 ## 致谢 - `cryptography`、`pydantic`、`httpx`、`click`、`rich`、`structlog`、`dnspython` 社区提供了底层构建块。 - OpenTimestamps 团队让时间戳锚定变得简单且免费。 - OASIS SARIF 工作组制定了结果交换格式。 - 在 **PVNL** (Privacy Verzet NL) 旗帜下的同行者们——坚信隐私是一项公民权利,而非一个产品特性。
``` ╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ "Wet als code. Bewijs als output." ║ ║ ║ ║ CAPTAIN WIMLEE115 · MMXXVI ║ ║ ║ ║ PVNL · Privacy Verzet NL ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝ ``` **[文档](docs/)**  ·  **[渗透测试报告](docs/PENTEST_REPORT.md)**  ·  **[法律框架](docs/legal.md)**  ·  **[PVNL 总览](https://github.com/WimLee115/Privacy-VerzetNL)**
标签:Ed25519, GraphQL安全矩阵, Python, SARIF, URL发现, 代码安全, 安全扫描器, 安全报告, 安全检测, 安全测试, 审计工具, 密码管理, 开源安全工具, 攻击性安全, 无后门, 无线安全, 无遥测, 杀软绕过, 漏洞枚举, 网站安全, 网络安全, 网络安全, 自动化侦察, 计算机取证, 运行时操纵, 逆向工具, 逆向工程平台, 隐私保护, 隐私保护, 隐私合规, 隐私验证