Files
Nexus/docs/release/20260708/Nexus-SSH命令执行安全巡检阶段2-安全解压-20260707.md
T
r 9b583ccc91
Nexus CI/CD / test (push) Waiting to run
Nexus CI/CD / e2e (push) Blocked by required conditions
Nexus CI/CD / deploy (push) Blocked by required conditions
Nexus Pre-commit Checks / quick-check (push) Waiting to run
docs(release): 主与 release 分支合并功能清单 + 导入 release 文档目录
便于 Gitea 上 main ↔ release/20260708-axs 合并评审与冲突对照。
2026-07-09 01:14:32 +08:00

4.2 KiB
Raw Blame History

Nexus SSH/文件管理安全巡检阶段 2:安全解压(2026-07-07

1. 本阶段目标

继续 SSH/文件管理安全巡检,重点检查:

  • /api/sync/decompress 解压链路。
  • tar/zip 归档成员是否可能写出目标目录。
  • 归档中的软链接、硬链接、设备文件是否可能造成覆盖或越权写入。

script_service 仍按用户确认的口径处理:它是设计内管理员远程 shell,不作为漏洞;本阶段只加固文件管理 UI 的“封装式安全操作”。


2. 修复提交

提交:

845d7e2 fix: validate remote archives before extraction

修改文件:

server/api/sync_v2.py
server/infrastructure/ssh/remote_archive.py
tests/test_remote_archive_commands.py

3. 修复前风险

原解压逻辑直接执行:

tar xzf <archive> -C <dest>
unzip -o <archive> -d <dest>

虽然 <archive><dest> 已经做过绝对路径规范化和 shell quote,但归档文件内部成员名不受 Nexus 控制,仍需要额外检查:

  • 成员名为 ../evil 可能尝试路径穿越。
  • 成员名为 /etc/passwd 属于绝对路径。
  • zip 中 Windows 分隔符 dir\evil 在某些工具/平台语义下容易产生歧义。
  • 归档内软链接/硬链接/设备文件可能造成解压后写出目标目录或制造特殊文件。

4. 修复后设计

解压流程从 API 中下沉到:

server/infrastructure/ssh/remote_archive.py::run_remote_decompress()

新流程:

  1. 判断格式:
    • .tar.gz / .tgz -> tar.gz
    • .zip -> zip
  2. 先列出成员名:
    • tartar -tzf <archive>
    • zipunzip -Z1 <archive>
  3. 校验成员名:
    • 禁止空文件名。
    • 禁止绝对路径。
    • 禁止 .. 路径穿越。
    • 禁止 Windows 反斜杠分隔符。
  4. 再列出成员类型:
    • tartar -tvzf <archive>
    • zipzipinfo -l <archive>
  5. 校验成员类型:
    • 允许普通文件和目录。
    • 禁止符号链接。
    • 禁止硬链接。
    • 禁止块设备、字符设备、FIFO、socket。
  6. 通过校验后才解压。

安全 tar 解压命令增加:

tar --no-same-owner --no-same-permissions -xzf <archive> -C <dest>

避免归档强行恢复 owner/permission,降低解压后权限异常风险。


5. 新增测试覆盖

新增/扩展测试文件:

tests/test_remote_archive_commands.py

覆盖:

  • tar/zip 成员列表命令。
  • tar 解压命令使用 --no-same-owner --no-same-permissions
  • 拒绝 ../evil.txt
  • 拒绝 /etc/passwd
  • 拒绝 dir\evil.txt
  • 允许普通相对文件和目录。
  • 拒绝符号链接。
  • 拒绝字符设备。
  • 允许 zipinfo header/footer + 普通文件/目录。

6. 验证结果

相关测试:

pytest tests/test_remote_archive_commands.py tests/test_schema_path_validators.py tests/test_file_permissions.py -q
31 passed in 0.55s

完整后端测试:

pytest -q
742 passed, 1 skipped in 11.83s

格式检查:

git diff --check
无输出

运行容器热更新:

  • 已复制以下文件到 nexus-nexus-1
    • server/api/sync_v2.py
    • server/infrastructure/ssh/remote_archive.py
  • 已重启 Nexus 容器。
  • http://127.0.0.1:18600/health 返回 ok
  • 容器内已确认存在:
    • validate_archive_member_names
    • run_remote_decompress
    • API 调用 run_remote_decompress(...)

7. 当前最新提交链

845d7e2 fix: validate remote archives before extraction
bcec78f fix: harden file manager shell operations
112e617 fix: stop archive option injection via filenames
99edd30 chore: default compose ports for nexus test deploy
a538358 fix: keep bt panel sessions alive after one-click login

8. 下一阶段建议

继续巡检:

  1. server/application/services/server_file_transfer_service.py
    • 跨服务器打包/拉取/投递路径校验。
    • 临时文件清理。
    • sudo fallback 边界。
  2. server/infrastructure/ssh/remote_shell.py / asyncssh_pool.py
    • timeout 默认值。
    • stdout/stderr 截断。
    • 敏感信息是否可能返回前端。
  3. server/api/servers.py
    • agent 安装/升级/回滚命令拼接。
    • 参数来源和 quote。