audit(v3.0.11): P0 -ExecutionPolicy Bypass + P1 4-项自验证

落地前红队审查发现 2 个阻断性 bug + 6 个非阻断:

[P0] Bug 2: .lnk Args 缺 -ExecutionPolicy Bypass
  根因: npm 全局生成的 claude.ps1 shim 是未签名脚本.
       Phase 1 设的 RemoteSigned 在 LTSC / Group Policy AllSigned 机器
       仍会拒绝执行. 用户启动时报'脚本未数字签名'.
  修: -NoLogo -NoExit -ExecutionPolicy Bypass -File ...

[P1] Bug 8: 自验证只查 claude.ps1 路径, 不查 perms / Bypass
  根因: 验证太松, 关键参数丢失也会通过.
  修: 扩展为 4 项检查 (Target / claude.ps1 路径 / --skip-perms / Bypass),
      任一失败立即删除 .lnk + 弹错, 不交付半成品.

P1 已知限制 (PS5.1 profile / Inject fail soft) 不阻断本版.

EXE 227840 → 228352 bytes (+512)
This commit is contained in:
bookworm 2026-04-25 21:38:28 +08:00
parent 1421338da3
commit 95422376ce
2 changed files with 26 additions and 16 deletions

View File

@ -860,26 +860,31 @@ function New-DesktopShortcuts {
$newLnk = "$desktop\启动Bookworm.lnk" $newLnk = "$desktop\启动Bookworm.lnk"
$shortcut = $shell.CreateShortcut($newLnk) $shortcut = $shell.CreateShortcut($newLnk)
$shortcut.TargetPath = $pwshExe $shortcut.TargetPath = $pwshExe
$shortcut.Arguments = "-NoLogo -NoExit -File `"$claudePs1`" --dangerously-skip-permissions" # v3.0.11 P0 修复: 显式 -ExecutionPolicy Bypass 防 LTSC/组策略 AllSigned 拒绝未签名 npm shim
$shortcut.Arguments = "-NoLogo -NoExit -ExecutionPolicy Bypass -File `"$claudePs1`" --dangerously-skip-permissions"
$shortcut.WorkingDirectory = $env:USERPROFILE $shortcut.WorkingDirectory = $env:USERPROFILE
$shortcut.Description = "Bookworm Smart Assistant (v3.0.11 直调架构)" $shortcut.Description = "Bookworm Smart Assistant (v3.0.11 直调架构)"
if (Test-Path $iconPath) { $shortcut.IconLocation = "$iconPath,0" } if (Test-Path $iconPath) { $shortcut.IconLocation = "$iconPath,0" }
$shortcut.Save() $shortcut.Save()
# ── 5. 自验证: 读回 .lnk 确认 Target/Args 写入完整 ── # ── 5. 自验证: 读回 .lnk 确认 4 项均写入完整 ──
$verify = $shell.CreateShortcut($newLnk) $verify = $shell.CreateShortcut($newLnk)
if ($verify.TargetPath -ne $pwshExe) { $checks = @{
Log-Fail "启动.lnk 自验证失败: TargetPath 不匹配 ($($verify.TargetPath) vs $pwshExe)" "TargetPath = pwshExe" = ($verify.TargetPath -eq $pwshExe)
"Arguments 含 claude.ps1 字面路径" = ($verify.Arguments -match [regex]::Escape("`"$claudePs1`""))
"Arguments 含 --dangerously-skip-perms" = ($verify.Arguments -match "--dangerously-skip-permissions")
"Arguments 含 -ExecutionPolicy Bypass" = ($verify.Arguments -match "-ExecutionPolicy Bypass")
}
$failed = $checks.GetEnumerator() | Where-Object { -not $_.Value } | ForEach-Object { $_.Key }
if ($failed) {
Log-Fail "启动.lnk 自验证失败 (项: $($failed -join ', '))"
Log-Fail " 实际 Target: $($verify.TargetPath)"
Log-Fail " 实际 Args : $($verify.Arguments)"
Remove-Item $newLnk -Force -EA SilentlyContinue Remove-Item $newLnk -Force -EA SilentlyContinue
Show-MsgBox "桌面快捷方式自验证失败 (Target 不匹配). 已删除避免坏快捷方式. 请重跑安装器." "v3.0.11 自验证失败" "OK" "Error" Show-MsgBox "桌面快捷方式自验证失败:`n$(($failed | ForEach-Object { ' - ' + $_ }) -join "`n")`n`n已删除坏 lnk. 请重跑安装器." "v3.0.11 自验证失败" "OK" "Error"
return return
} }
if ($verify.Arguments -notmatch [regex]::Escape("-File `"$claudePs1`"")) { Log-OK "启动Bookworm.lnk 创建并通过 4 项自验证"
Log-Fail "启动.lnk 自验证失败: Arguments 不含 claude.ps1 路径"
Remove-Item $newLnk -Force -EA SilentlyContinue
return
}
Log-OK "启动Bookworm.lnk 创建并自验证通过"
# ── 6. 迁移清理老 lnk (v3.0.3 及以前的 Bookworm.lnk) ── # ── 6. 迁移清理老 lnk (v3.0.3 及以前的 Bookworm.lnk) ──
$oldLnk = "$desktop\Bookworm.lnk" $oldLnk = "$desktop\Bookworm.lnk"

View File

@ -216,7 +216,8 @@ function New-DesktopShortcuts {
$shell = New-Object -ComObject WScript.Shell $shell = New-Object -ComObject WScript.Shell
$shortcut = $shell.CreateShortcut($lnkPath) $shortcut = $shell.CreateShortcut($lnkPath)
$shortcut.TargetPath = $pwshExe $shortcut.TargetPath = $pwshExe
$shortcut.Arguments = "-NoLogo -NoExit -File `"$claudePs1`" --dangerously-skip-permissions" # v3.0.11 P0 修复: -ExecutionPolicy Bypass 防 LTSC/AllSigned 拒绝未签名 npm shim
$shortcut.Arguments = "-NoLogo -NoExit -ExecutionPolicy Bypass -File `"$claudePs1`" --dangerously-skip-permissions"
$shortcut.WorkingDirectory = $env:USERPROFILE $shortcut.WorkingDirectory = $env:USERPROFILE
$shortcut.Description = "Bookworm Smart Assistant (v3.0.11 直调)" $shortcut.Description = "Bookworm Smart Assistant (v3.0.11 直调)"
$iconPath = Join-Path $bootDir "bookworm-desktop.ico" $iconPath = Join-Path $bootDir "bookworm-desktop.ico"
@ -224,12 +225,16 @@ function New-DesktopShortcuts {
if (Test-Path $iconPath) { $shortcut.IconLocation = "$iconPath,0" } if (Test-Path $iconPath) { $shortcut.IconLocation = "$iconPath,0" }
$shortcut.Save() $shortcut.Save()
# 自验证 # 自验证 (4 项)
$verify = $shell.CreateShortcut($lnkPath) $verify = $shell.CreateShortcut($lnkPath)
if ($verify.TargetPath -eq $pwshExe -and $verify.Arguments -match [regex]::Escape($claudePs1)) { $okTarget = $verify.TargetPath -eq $pwshExe
Write-Host " [OK] 桌面快捷方式已创建: 启动Bookworm.lnk → pwsh + claude.ps1" -ForegroundColor Green $okPath = $verify.Arguments -match [regex]::Escape($claudePs1)
$okPerm = $verify.Arguments -match "--dangerously-skip-permissions"
$okBypass = $verify.Arguments -match "-ExecutionPolicy Bypass"
if ($okTarget -and $okPath -and $okPerm -and $okBypass) {
Write-Host " [OK] 桌面快捷方式已创建并通过 4 项自验证" -ForegroundColor Green
} else { } else {
Write-Host " [!] 桌面快捷方式自验证失败" -ForegroundColor Yellow Write-Host " [!] 桌面快捷方式自验证失败 (Target=$okTarget Path=$okPath Perm=$okPerm Bypass=$okBypass)" -ForegroundColor Yellow
Remove-Item $lnkPath -Force -EA SilentlyContinue Remove-Item $lnkPath -Force -EA SilentlyContinue
} }
} catch { } catch {