Repository navigation
安全加固:按审计复核修复 #1 #3 #6 #8 #9 #10 #12 #13 #14 #16 #17 - #32
Merged
Merged
Conversation
遇到的问题(审计复核确认属实或部分属实的几条): - #1 reg/taskkill/sc/net/schtasks/tasklist 只写了文件名,管理员运行时会先在 exe 所在目录里找同名程序; - #3 taskkill /IM 会结束所有登录用户的 Word/Excel 等; - #8 OfficePLUS 进程只按名字匹配,DeepLink.exe 这类常见名字可能误杀; - #9 子进程没有超时,net stop 没加 /y,也没重定向标准输入; - #10 先删服务再备份注册表,和 PowerShell 版顺序不一致; - #12 服务处于 *_PENDING 状态时被当成不存在; - #13 手写 CSV 解析,一行格式不对会让后面的进程全部漏检; - #14 32 位 Python 下 ProgramFiles 指向 Program Files (x86); - #16 管理员往用户可控的「文档」里写备份和日志,没检查是不是联接。 我的改动: - 新增 winutil.py:system_exe() 用 GetSystemDirectoryW 拿到 System32 绝对路径; list_processes() 用 csv.reader 解析 tasklist(含会话号),单行出错只跳过该行; process_path() 读进程程序路径;is_reparse_point() 判断联接/符号链接;COMMAND_TIMEOUT=60 秒。 - cleaner.kill_processes:Office 程序只按 PID 结束当前会话里的;OfficePLUS 进程不分会话 (服务进程在会话 0),但程序所在文件夹路径必须含 OfficePLUS,读不到路径就跳过并记日志。 - 所有 subprocess 调用加 stdin=DEVNULL 和 timeout,net stop 加 /y;超时按失败记进日志。 - run_nuke 先备份注册表,再结束进程、删服务。 - scan_services 改看 sc query 的退出码(0 存在、1060 不存在)。 - 目录规则的 ProgramFiles 优先取 ProgramW6432。 - 备份文件夹 / 日志文件夹是重解析点时拒绝写入(备份按写入失败处理,不删注册表)。 - E2E 假进程放进名字含 OfficePLUS 的临时文件夹,符合新的路径核对。 没改 gui.py(AGENTS.md 硬性规则 8)。 怎么测试的:py_compile、sync_rules --check、real_sample_check 通过;在 Linux 上用 mock 跑了 10 个逻辑测试(CSV 解析、会话过滤、路径核对、PENDING 状态、超时、执行顺序、联接拒写、ProgramW6432)。 没有 Windows 机器,未实机测试,需要 CI/E2E 验证。
遇到的问题:#1(reg.exe/sc.exe/attrib 不带路径)、#3(Stop-Process 不分会话)、 #6(Test-Path/Remove-Item 用 -Path,会按通配符解释)、#8(OfficePLUS 进程只按名字匹配)、 #14(32 位 PowerShell 下 ProgramFiles 指向 x86)、#16(备份和日志写进用户可控的文件夹没检查联接), 以及复核认为基本不属实的 #2:顺手加一个便宜的防护。 我的改动: - $Sys32 = [Environment]::SystemDirectory,reg.exe、sc.exe、attrib.exe 都用绝对路径; attrib 不再经过 cmd.exe /c,路径里的 % 也不会被展开。 - 注册表和目录的 Test-Path / Remove-Item / Get-Content 一律改成 -LiteralPath。 - 保存提醒和结束进程只针对当前会话的 Office;OfficePLUS 进程要求程序文件夹含 OfficePLUS, 读不到路径就跳过(扫描时读不到路径仍然报告)。 - $ProgramFiles64 优先取 ProgramW6432;sync_rules.py 同步生成这个变量。 - 日志文件夹、备份文件夹是重解析点时拒绝写入(备份按写入失败处理,不删注册表)。 - 残留目录本身是联接/符号链接时,只删链接本身,不 attrib、不递归进去(#2 的低成本防护)。 - 文件保持 UTF-8 带 BOM。 怎么测试的:pwsh 7.4(Linux)解析无错误;PSScriptAnalyzer 警告与改动前完全相同(无新增); 在 pwsh 里单独测了 Test-ReparsePoint、Test-OfficePlusProcess 和删除符号链接不影响目标目录。 没有在 Windows / PowerShell 5.1 上实测,需要 E2E 验证。
遇到的问题(#17 部分属实):release.yml 和 ci.yml 里 pip install pyinstaller 没固定版本, actions/checkout、setup-python、action-gh-release 用的是会移动的标签;ci.yml、e2e.yml 没有声明权限。 我的改动: - 三个 Action 固定到当前大版本标签指向的完整 commit SHA,后面注释具体版本: checkout v4.4.0、setup-python v5.6.0、action-gh-release v2.6.2; - pyinstaller 固定为 6.22.3(ci.yml 的打包任务和 release.yml 一致); - ci.yml、e2e.yml 顶层加 permissions: contents: read;release.yml 原本就是 contents: write(上传 Release 需要),不变。 怎么测试的:SHA 用 git ls-remote 核对过;工作流本身要在这个 PR 的 CI 里跑过才算验证。
这两条不是我对这个项目的要求,删掉。规则 8 是最后一条,删除后其余编号不变; 提交流程保留“CI 和 E2E 全绿后再合并,合并后删除分支,仓库只保留 main”。 仓库里没有其他代理说明文件(CLAUDE.md、.cursor、copilot-instructions 等)需要同步。
遇到的问题: - 清理完成后不管实际结果,日志固定写“已终止相关进程…已清理完成”,并弹出「清理完成」, 也不告诉用户注册表备份和清理日志在哪里(exe 用户只用图形界面); - 统计卡片和扫描日志里没有计划任务,但总数算了计划任务,各项加起来对不上; - 直接跑源码时点「提权」被 UAC 拒绝,界面没有任何反应(错误打到了不存在的 stderr)。 我的改动: - 清理后在后台线程里紧接着复检,按清理返回值和复检结果分成“清理完成 / 部分完成 / 清理失败” 三种提示(信息 / 警告 / 错误弹窗),日志按实际数量写,弹窗里附上注册表备份和清理日志路径; 清理或复检出错时也会回到界面、恢复按钮,不当作成功; - 新增「计划任务」卡片(共 5 张),扫描日志列出计划任务; - elevate() 返回 False 时弹出“未获得管理员权限”提示,出错时弹出错误提示。 怎么测试的: - 新增 tests/gui_result_check.py:用假的弹窗和界面对象检查三种结果、备份/日志路径、 复检出错不卡住、计划任务卡片、UAC 被拒提示;没有 tkinter/winreg 的系统也能跑,已加进 CI; - 本地 py_compile、pyflakes、sync_rules.py --check、real_sample_check.py 均通过。
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
遇到的问题
我对 v1.2.1(main @ 8bb171c)做了一次安全审计,又逐条做了复核。这个 PR 只修复核结论为「属实」或「部分属实」的条目。复核认为基本不属实的 #2,我只加了一个很便宜的防护。
我的改动(按审计编号)
GetSystemDirectoryW取路径,不信环境变量;PS 用[Environment]::SystemDirectory,attrib 也不再经过cmd.exe /cSessionId过滤),保存提醒也只针对当前会话。OfficePLUS 自己的进程不按会话过滤,因为服务进程在会话 0Test-Path/Remove-Item/Get-Content改为-LiteralPathOfficePLUS(真机样本的路径是C:\Program Files\Microsoft OfficePLUS\<版本>\)。读不到路径就不结束,并记进日志;扫描时读不到路径仍然报告(宁可多报)stdin=DEVNULL和timeout=60,net stop加/y;超时按失败处理,记进日志,不会卡住run_nuke改为先备份注册表,再结束进程、删除服务,和 PS 版顺序一致sc query的退出码(0 = 存在,1060 = 不存在),START_PENDING、STOP_PENDING 等中间状态不会再被漏报csv.reader解析,某一行格式不对只跳过这一行ProgramW6432。PS 端由sync_rules.py生成$ProgramFiles64permissions: contents: read(release.yml 原本就是contents: write,上传 Release 需要这个权限,没改)[IO.Directory]::Delete($dir, $false)),不跑 attrib,也不递归进去其他相关改动:
src/remove_officeplus/winutil.py,放这几项共用的小工具。tests/gui_result_check.py(已加进 CI 的 python-test):用假的弹窗和界面对象检查 GUI 的三种结果提示、备份和日志路径、复检出错不卡住、计划任务卡片、UAC 被拒提示;没有 tkinter / winreg 的系统也能跑。tests/e2e/fake_residue.py里的假进程改放进名字含OfficePLUS的临时文件夹,不然新的路径核对会让 E2E 失败。这样也更接近真实安装。没改的项和原因
irm | iex拉取 main 分支、提权时重新下载)、打包:删除写死本机路径的 spec,exe 加版本信息和 SHA256 校验 #18(国内镜像没有公布 SHA256):没改。 属于分发和基础设施,不在本次代码修复范围内。-NoBackup和「先备份再删除」规则冲突):没改。 这是用户主动加的开关,要不要去掉需要作者定。--onefile改--onedir、exe 代码签名):没改。 牵涉发布方式和证书。怎么测试的
python -m py_compile(全部 .py)✅python scripts/sync_rules.py --check✅python tests/real_sample_check.py✅python tests/gui_result_check.py(14 项检查)✅import os)net stop /y、先备份后删除的顺序、联接拒绝写入、ProgramW6432Test-ReparsePoint、Test-OfficePlusProcess,以及删除符号链接后目标目录还在这次按审计批次合成了一个 PR,分成 5 个提交(Python / PowerShell / CI / AGENTS.md / 图形界面)。版本号没有改。