fix: 口令会随 -Verbose 落进日志(DEBUG 下打印整条命令行)

缺陷:Invoke-ExternalCommand 在 DEBUG 级打印整条命令行,而 7z / RAR 只接受命令行
口令(-p<口令>),所以口令必然出现在参数表里。一旦 -Verbose(Backup.ps1 / Restore.ps1
都会因它打开 DEBUG),logs\*.log 里就是明文口令 —— 与 BackupConfig.psd1 和文档里
"口令不落盘、不写进仓库"的承诺直接冲突。

修法:打印前把 -p 参数换成占位符;真正执行的仍然是原参数。在**参数级别**替换而不是
对拼好的命令行做正则 —— 含空格的口令会被引号包起来("-pmy pass"),正则在那种形态上
很容易漏掉,而漏掉的代价是口令明文入日志。

回归断言(零依赖与 Pester 各一份):打开 DEBUG、把日志指向临时目录、带一个哨兵口令
跑一次外部命令,然后读日志文件断言哨兵不在里面、占位符在里面。另加一条"测试的测试":
断言那行 DEBUG 记录确实写进去了 —— 否则前两条会在"压根没记录"时空跑通过。

断言有效性做了红绿证明:把遮蔽改回 $startInfo.Arguments 后断言变红并指名"口令明文
进了日志",还原后转绿。

验收:test.ps1 9/9 全绿;tests\Run-RealSmoke.ps1 4/4 全绿。
This commit is contained in:
Shuery committed 2026-09-26 22:41:52 +08:00
1 parent d32d4b511f
commit e17cdcda79
3 files changed
+59 -1

No files matched your search

+23
View File
@@ -1116,6 +1116,29 @@ Describe 'Resolve-BackupEntry:条目解析' {
Describe '外部命令退出码(旧实现的核心缺陷)' {
# ============================================================================
It '口令不会进日志:DEBUG 下打印的命令行要遮蔽 -p 参数' {
$sandbox = Join-Path $env:TEMP ("bnr-secret-" + [guid]::NewGuid().ToString('N').Substring(0, 8))
New-Item -ItemType Directory -Path $sandbox -Force | Out-Null
$sentinel = 'SENTINEL-PW-9f3a'
$logPath = $null
try {
$logPath = Start-BaknretLog -Directory $sandbox -Prefix 'secret'
Set-BaknretDebug
$null = Invoke-ExternalCommand -FilePath 'cmd.exe' -ArgumentList @('/c', 'exit 0', "-p$sentinel")
} finally {
Set-BaknretDebug -Enabled:$false
Stop-BaknretLog
}
$logText = Get-Content -Encoding UTF8 -LiteralPath $logPath -Raw
# 这条是"测试的测试":没有它,万一 DEBUG 那行压根没写进去,后面两条会空跑通过
$logText | Should -Match '执行:'
$logText | Should -Not -Match ([regex]::Escape($sentinel))
$logText | Should -Match '口令已隐藏'
Remove-Item -LiteralPath $sandbox -Recurse -Force -ErrorAction SilentlyContinue
}
It 'Invoke-ExternalCommand 能拿到真实退出码' {
(Invoke-ExternalCommand -FilePath 'cmd.exe' -ArgumentList @('/c', 'exit 7')) | Should -Be 7
}