Skip to content

Commit 02680ad

Browse files
author
SqlRush
committed
Classify PowerShell certutil hashfile as read-only
1 parent d0ddefb commit 02680ad

4 files changed

Lines changed: 41 additions & 0 deletions

File tree

docs/cc-100-roadmap.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ M5 补充:Bash read-only classifier 现在覆盖常见 checksum 命令 `md5sum
209209

210210
M5 补充:PowerShell read-only classifier 现在覆盖 `Get-FileHash` 的安全路径读取和常见 native checksum 命令 `md5sum`/`sha*sum`/`b2sum`/`shasum`/`cksum`/`sum`,同时拒绝 `Get-FileHash -InputStream` 表达式和 `-c`/`--check` 校验清单模式。
211211

212+
M5 补充:PowerShell read-only classifier 继续覆盖 Windows `certutil -hashfile <path> [algorithm]` 的安全相对路径 checksum 形态,同时拒绝 `certutil` 其它子命令、pass-through、越界路径、动态算法和额外参数。
213+
212214
M5 补充:Bash 前台输出和 `BashOutput` 现在都走统一 tool-result budget 截断/落盘路径;`BashOutput` 增加 100k 最大结果限制,大后台输出会保存完整内容并返回 `full_output_path` 元数据。
213215

214216
M5 补充:Bash/PowerShell 后台任务现在会发 `*_background_started``*_background_finished` tool progress 事件,包含后台 ID、shell/status、exit/timed_out/cancelled、duration、时间戳和输出字节数,不携带 command 文本;completed、timed_out、cancelled 终态均已覆盖测试。

docs/claude-code-go-rewrite-plan.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ test/parity/ # golden tests against TS/official behavior
216216
- 本轮补充:Bash read-only classifier 继续覆盖 `comm` 文件比较命令,`comm -12 old.txt new.txt``comm --check-order ...` 这类只读比较不再误触发写权限确认,同时仍拒绝越界路径。
217217
- 本轮补充:Bash read-only classifier 现在覆盖常见 checksum 命令 `md5sum`/`sha*sum`/`b2sum`/`shasum`/`cksum`/`sum` 的普通文件读取形态,同时阻断 `-c`/`--check` 校验清单模式,避免清单内路径绕过路径权限。
218218
- 本轮补充:PowerShell read-only classifier 现在覆盖 `Get-FileHash` 的安全路径读取和常见 native checksum 命令 `md5sum`/`sha*sum`/`b2sum`/`shasum`/`cksum`/`sum`,同时拒绝 `Get-FileHash -InputStream` 表达式和 `-c`/`--check` 校验清单模式。
219+
- 本轮补充:PowerShell read-only classifier 继续覆盖 Windows `certutil -hashfile <path> [algorithm]` 的安全相对路径 checksum 形态,同时拒绝 `certutil` 其它子命令、pass-through、越界路径、动态算法和额外参数。
219220
- 本轮补充:`BashOutput` 现在设置 100k 最大结果大小,和前台 `Bash` 一起覆盖大输出 tool-result preview 截断、完整输出落盘及 `full_output_path` 元数据。
220221
- 本轮补充:Bash/PowerShell 后台命令现在会通过 tool progress 通道发 started/finished 事件,记录后台 ID、shell/status、exit/timed_out/cancelled、duration、时间戳和 stdout/stderr byte count,且 completed、timed_out、cancelled 终态测试确保 progress 不携带 command 文本。
221222
- 本轮补充:WebSearch domain filters 现在在 schema 层声明 array `items:string`,通用 tool schema validator 同步支持 `items` 校验;`allowed_domains`/`blocked_domains` 会拒绝空字符串、URL/port、非法 wildcard 和非域名 label。

internal/tools/powershell/tools.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,6 +1601,8 @@ func readOnlyWords(words []string) bool {
16011601
switch command {
16021602
case "git":
16031603
return bashtools.IsReadOnlyCommand(powerShellGitCommand(words))
1604+
case "certutil":
1605+
return readOnlyCertutil(words[1:])
16041606
case "docker":
16051607
return readOnlyDocker(words[1:])
16061608
case "dotnet":
@@ -1798,6 +1800,33 @@ func readOnlyDotnet(words []string) bool {
17981800
return true
17991801
}
18001802

1803+
func readOnlyCertutil(words []string) bool {
1804+
if len(words) < 2 || len(words) > 3 {
1805+
return false
1806+
}
1807+
for _, word := range words {
1808+
if strings.TrimSpace(word) == "--%" {
1809+
return false
1810+
}
1811+
}
1812+
if strings.ToLower(strings.Trim(strings.TrimSpace(words[0]), `"'`)) != "-hashfile" {
1813+
return false
1814+
}
1815+
if !safeRelativePowerShellPath(words[1]) {
1816+
return false
1817+
}
1818+
return len(words) == 2 || safeCertutilHashAlgorithm(words[2])
1819+
}
1820+
1821+
func safeCertutilHashAlgorithm(value string) bool {
1822+
switch strings.ToLower(strings.Trim(strings.TrimSpace(value), `"'`)) {
1823+
case "md2", "md4", "md5", "sha1", "sha256", "sha384", "sha512":
1824+
return true
1825+
default:
1826+
return false
1827+
}
1828+
}
1829+
18011830
func readOnlyDocker(words []string) bool {
18021831
if len(words) == 0 {
18031832
return true

internal/tools/powershell/tools_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,9 @@ func TestPowerShellCommandClassification(t *testing.T) {
211211
"shasum -a 256 README.md",
212212
"cksum --algorithm crc README.md",
213213
"sum -r README.md",
214+
"certutil -hashfile README.md SHA256",
215+
"certutil.exe -hashfile README.md",
216+
`certutil -hashfile .\README.md SHA1`,
214217
"dotnet --info",
215218
"dotnet --list-runtimes --list-sdks",
216219
"docker ps",
@@ -341,6 +344,12 @@ func TestPowerShellCommandClassification(t *testing.T) {
341344
"sha256sum --check checksums.txt",
342345
"md5sum --check=checksums.txt",
343346
"shasum -c checksums.txt",
347+
"certutil -hashfile /etc/passwd SHA256",
348+
`certutil -hashfile C:\Users\secret.txt SHA256`,
349+
"certutil -hashfile README.md $env:ALG",
350+
"certutil -hashfile README.md SHA256 extra",
351+
"certutil --% -hashfile README.md SHA256",
352+
"certutil -urlcache -split -f https://example.com/file out.bin",
344353
"dotnet build",
345354
"dotnet --info $env:SECRET",
346355
"docker run alpine",

0 commit comments

Comments
 (0)