chore(repo): 导入 M-Z 业务底座 V1.9 基线并建立仓库规范
按周工交付的 SEC-Z-01 清理后源码建立 M-Z 主干,并按 Git 仓库惯例重排目录。 - aomin-gateway/ 后端工程 87 文件,原样保留,路径与构建命令未变 - demo/ 演示前端与设备模拟器 9 文件(原 02_前端与设备端),非正式三端 - docs/handover/ 交付与安全清理材料 6 份,内容未改 - docs/contract/ J-00 规格、OpenAPI、内部五接口、状态机、Mock 样例 - docs/reference/ 指纹与校验清单,含 84 个源码文件的 sha256 清单 目录重排只动位置不动内容:源码树 84 文件哈希与交付一致,逐文件自校验通过; 12 条 Flyway 迁移与交付包内镜像逐字节一致。 未纳入:迁移镜像目录(与工程内一套重复,改留指纹)、target/、证据 raw、 应急恢复脚本、评审用虚构台账数据。 安全:SEC-Z-01 15 处明文已清零,导入前重新扫描无新增命中,本仓库无历史污染。 行尾按交付字节原样保存(.gitattributes 设 * -text),不做归一化以免整树摘要失效。
This commit is contained in:
commit
a7605ef8b8
121 files changed
+23629
No files matched your search
@@ -0,0 +1,126 @@
|
||||
# SEC-Z-01 最小安全清理差异清单(Z-01)
|
||||
|
||||
| 项 | 内容 |
|
||||
|---|---|
|
||||
| 依据 | AM-S1-GOV-020 §4.2「第一优先级:完成 SEC-Z-01 最小安全清理」 |
|
||||
| 执行人 | 周工 |
|
||||
| 执行时间 | 2026-11-13 11:20–11:45 |
|
||||
| 范围 | **15 处明文** + **1 处启动守卫**(为满足"缺参明确失败") |
|
||||
| 是否升版 | **否**,V1.9 内做最小安全清理,未升 V1.10,无无关重构 |
|
||||
| 口令复述 | **本件不含原口令任何字符**,差异表中一律写作「(原值已脱敏)」 |
|
||||
|
||||
---
|
||||
|
||||
## 一、清理前后总览
|
||||
|
||||
| 项 | 清理前 | 清理后 |
|
||||
|---|---|---|
|
||||
| 含明文口令的文件 | **15 个** | **0** |
|
||||
| 明文出现次数 | 15 处(每文件 1 处) | 0 |
|
||||
| 配置层(yml) | 带非空默认值 | 无默认值,缺参启动中止 |
|
||||
| 脚本层(py) | 带非空默认值 | 无默认值,缺参直接退出 |
|
||||
| 文档层(md) | 写出明文示例 | 改为占位符 |
|
||||
| 历史包 | 6 个 zip 内含旧凭据 | 已移入受控归档目录,标注禁止外发 |
|
||||
|
||||
---
|
||||
|
||||
## 二、逐处差异(15 处)
|
||||
|
||||
### A 类:后端配置(1 处)
|
||||
|
||||
| # | 文件 | 位置 | 改前 | 改后 |
|
||||
|---|---|---|---|---|
|
||||
| 1 | `01_后端源码/src/main/resources/application.yml` | `spring.datasource.password` | `${DB_PASS:<原值已脱敏>}` | `${DB_PASS}` |
|
||||
|
||||
同时把上方两行自相矛盾的注释("包里不再有第二处明文"——实际上还有 14 处)改成实际口径。
|
||||
|
||||
### B 类:Python 证据脚本(12 处)
|
||||
|
||||
12 个脚本写法相同,改法相同。以一处示意:
|
||||
|
||||
| 改前 | 改后 |
|
||||
|---|---|
|
||||
| `DB_PASS = os.environ.get("AOMIN_DB_PASS", "<原值已脱敏>")` | `DB_PASS = os.environ.get("AOMIN_DB_PASS")`<br>加 4 行守卫:为空则 `raise SystemExit(...)`,打印设置方法 |
|
||||
|
||||
| # | 文件 |
|
||||
|---|---|
|
||||
| 2 | `06_统一闭环题自测证据/alarm_retry_test.py` |
|
||||
| 3 | `06_统一闭环题自测证据/closed_loop_test.py` |
|
||||
| 4 | `06_统一闭环题自测证据/cmd_chain_test.py` |
|
||||
| 5 | `06_统一闭环题自测证据/run_evidence.py` |
|
||||
| 6 | `06_统一闭环题自测证据/scope_test.py` |
|
||||
| 7 | `06_统一闭环题自测证据/v15_fix_test.py` |
|
||||
| 8 | `06_统一闭环题自测证据/v16_fix_test.py` |
|
||||
| 9 | `06_统一闭环题自测证据/v17_merge_test.py` |
|
||||
| 10 | `06_统一闭环题自测证据/v18_fix_test.py` |
|
||||
| 11 | `06_统一闭环题自测证据/v19_gov008_test.py` |
|
||||
| 12 | `06_统一闭环题自测证据/v20_node_test.py` |
|
||||
| 13 | `06_统一闭环题自测证据/stamp_evidence.py`(特殊:原为内联调用 `"-p" + os.environ.get(...)`,改为在模块顶部定义 `DB_PASS` 并加同样的守卫,调用处改引用常量) |
|
||||
|
||||
### C 类:说明文档(2 处)
|
||||
|
||||
| # | 文件 | 位置 | 改前 | 改后 |
|
||||
|---|---|---|---|---|
|
||||
| 14 | `05_启动构建与测试说明/启动构建与测试说明.md` | §5 启动 | `export DB_PASS=<原值已脱敏>` | `export DB_PASS=<口令>`,注释改为"必需:配置里已无默认值,未设置时启动直接失败" |
|
||||
| 15 | `09_代码与版本/README.md` | 环境变量表 | 默认值列写出明文 | `root` / **必需,无默认值**;说明未设置时脚本直接退出 |
|
||||
|
||||
---
|
||||
|
||||
## 三、新增 1 处启动守卫(为什么必须有)
|
||||
|
||||
**这是本次唯一的代码改动,不是重构,是为满足 §4.2「缺少必需口令时明确失败」。**
|
||||
|
||||
### 问题:只删默认值,并没有"明确失败"
|
||||
|
||||
先按最省事的方式改(`password: ${DB_PASS}` 不设默认值)实测了一次,结果不是报"缺少 DB_PASS",而是:
|
||||
|
||||
```
|
||||
Access denied for user 'root'@'localhost' (using password: YES)
|
||||
```
|
||||
|
||||
原因:Spring Boot 的占位符解析在“解析不到”时是**忽略**而不是报错,于是拿空口令去连库。表现出来像"口令错了",实际是"根本没配"——这正是不允许的静默回退。
|
||||
|
||||
### 处理:在 `main` 里提前拦住
|
||||
|
||||
| 文件 | 改动 |
|
||||
|---|---|
|
||||
| `src/main/java/cn/aomin/gateway/GatewayApplication.java` | `main()` 首行调用 `requireEnv("DB_PASS", "数据库口令")`;新增私有方法 `requireEnv`,为空则打印提示并 `System.exit(1)` |
|
||||
|
||||
改后实测输出(退出码 **1**):
|
||||
|
||||
```
|
||||
[启动中止] 缺少必需的环境变量 DB_PASS(数据库口令)。
|
||||
SEC-Z-01:程序不再内置任何默认口令,也不会回退到包内明文。
|
||||
设置方法:Windows set DB_PASS=<口令> Linux/macOS export DB_PASS=<口令>
|
||||
```
|
||||
|
||||
**只校验"有没有",不校验"对不对",也不打印任何取值。**
|
||||
|
||||
---
|
||||
|
||||
## 四、构建产物与缓存清理
|
||||
|
||||
| 对象 | 处理 |
|
||||
|---|---|
|
||||
| `target/classes/application.yml` | 旧副本含明文;`mvn clean package` 后已由新文件覆盖,实测 jar 内配置 **0 命中** |
|
||||
| `__pycache__` / `*.pyc` | 已删除(编译产物里会残留字符串常量) |
|
||||
| 应用日志 `G:/aomin-dev/logs` | 实测 **0 命中**,保留(不含凭据,且是运行证据) |
|
||||
| `target/` 其余内容 | 43 MB 构建产物,已随 `clean` 重建;**不入代码仓库**(见 `03` 的 `.gitignore`) |
|
||||
|
||||
---
|
||||
|
||||
## 五、历史包处置
|
||||
|
||||
`_历史包/` 下 6 个 zip 都含旧凭据(解开后逐成员扫描,命中 13~15 处)。直接按字节搜 zip 查不出来,因为内容被 deflate 压缩过。
|
||||
|
||||
| 处理 | 说明 |
|
||||
|---|---|
|
||||
| 目录改名 | `_历史包/` → **`_历史包_含旧凭据_禁止外发/`** |
|
||||
| 登记 | 同目录 `_清单_含旧凭据.md` 记录每个 zip 的字节数、SHA-256、含旧口令文件数 |
|
||||
| 约束 | **禁止外发、禁止入代码库、禁止上传公共 AI**;仅作内部留档 |
|
||||
|
||||
> 这是"轮换结论"要覆盖的一部分:口令一旦进过包,就不能假设它只存在于一个地方。
|
||||
|
||||
---
|
||||
|
||||
*后续:清理后哈希、构建说明、155 条证据边界见同目录 `03_…` 与 `04_…`。*
|
||||
Reference in new issue
Block a user