fix: etcdutl snapshot 未知子命令应拒绝而非默认当写

修复验证中发现的安全漏洞:
- etcdutl snapshot <bogus> 原会默认返回 write (需审批),
  现改为显式拒绝 (ValueError)
- 新增 _ETCDUTL_SNAPSHOT_WRITE = {restore, make} 显式枚举写子命令
- 同时补充 etcdctl defrag 为写操作 (需审批)

验证: 65 项 ad-hoc 检查全部通过, 56 个单元测试通过
This commit is contained in:
cnbugs
2026-07-25 13:52:19 +08:00
parent 4f37c65f18
commit 1f37cd3268
+5 -1
View File
@@ -133,7 +133,7 @@ SHELL_READ_ONLY_COMMANDS: dict[str, set[str] | None] = {
# etcdctl 单段式只读 verb
_ETCDCTL_READ_VERBS = {"get", "watch", "version", "lock", "lease", "move-leader", "leader"}
# etcdctl 单段式写 verb (需人工审批)
_ETCDCTL_WRITE_VERBS = {"put", "del", "delete", "compact", "txn", "snapshot"}
_ETCDCTL_WRITE_VERBS = {"put", "del", "delete", "compact", "txn", "snapshot", "defrag"}
# etcdctl 两段式 (verb, subverb) 只读组合
_ETCDCTL_READ_SUBVERBS = {
"endpoint": {"status", "health", "hashkv"},
@@ -154,6 +154,8 @@ _ETCDCTL_WRITE_SUBVERBS = {
}
# etcdutl snapshot 只读子命令
_ETCDUTL_SNAPSHOT_READ = {"status", "hash"}
# etcdutl snapshot 写子命令 (需人工审批)
_ETCDUTL_SNAPSHOT_WRITE = {"restore", "make"}
# 系统修改命令白名单:需要人工审批
SHELL_WRITE_COMMANDS: dict[str, set[str] | None] = {
@@ -233,7 +235,9 @@ def classify_shell_command(command: str) -> CommandDecision:
if ev == "snapshot":
if esub in _ETCDUTL_SNAPSHOT_READ:
return CommandDecision("read", False, ev, parts[1:])
if esub in _ETCDUTL_SNAPSHOT_WRITE:
return CommandDecision("write", True, ev, parts[1:])
raise ValueError(f"etcdutl snapshot 不支持子命令: {esub}")
if ev == "version":
return CommandDecision("read", False, ev, parts[1:])
raise ValueError(f"etcdutl 不支持该子命令: {ev}")