Skip to content

Commit 044047e

Browse files
Enforce whole-worktree non-mutating audit
Normalize subdirectory inputs, suppress repository fsmonitor hooks, and encode the classic-protection branch parameter without adding broader policy analysis.
1 parent 0085174 commit 044047e

3 files changed

Lines changed: 86 additions & 4 deletions

File tree

public-source-release-audit/SKILL.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,11 @@ gh api repos/OWNER/REPO --jq '{visibility,security_and_analysis}'
5656
gh ruleset check --default --repo OWNER/REPO
5757
gh ruleset list --repo OWNER/REPO --parents --limit 100
5858
gh ruleset view RULESET-ID --repo OWNER/REPO
59-
gh api repos/OWNER/REPO/branches/DEFAULT-BRANCH/protection
59+
default_branch="$(gh repo view OWNER/REPO --json defaultBranchRef \
60+
--jq '.defaultBranchRef.name')"
61+
encoded_branch="$(ruby -rerb -e \
62+
'print ERB::Util.url_encode(ARGV.fetch(0))' "$default_branch")"
63+
gh api "repos/OWNER/REPO/branches/${encoded_branch}/protection"
6064
gh api 'repos/OWNER/REPO/actions/runners?per_page=100' \
6165
--jq '{total_count,runners:[.runners[] | {name,status,busy}]}'
6266
```

public-source-release-audit/scripts/check_current_source.rb

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,15 @@ def usage(message = nil)
4242
end
4343

4444
def git_capture(repo, *arguments)
45-
Open3.capture3(GIT_ENVIRONMENT, "git", "-C", repo, *arguments)
45+
Open3.capture3(
46+
GIT_ENVIRONMENT,
47+
"git",
48+
"-C",
49+
repo,
50+
"-c",
51+
"core.fsmonitor=false",
52+
*arguments
53+
)
4654
end
4755

4856
def matching_labels(content)
@@ -82,13 +90,22 @@ def symlinked_parent?(repo, relative_path)
8290
repo = File.expand_path(ARGV.first || ".")
8391
usage("Repository must be a directory") unless File.directory?(repo)
8492

93+
toplevel_output, _toplevel_error, toplevel_status = git_capture(
94+
repo,
95+
"rev-parse",
96+
"--show-toplevel"
97+
)
98+
usage("Repository must be a Git worktree") unless toplevel_status.success?
99+
repo = toplevel_output.b.sub(/\r?\n\z/, "".b)
100+
usage("Unable to resolve Git worktree root") unless File.directory?(repo)
101+
85102
index_output, _index_error, index_status = git_capture(
86103
repo,
87104
"ls-files",
88105
"--stage",
89106
"-z"
90107
)
91-
usage("Repository must be a Git worktree") unless index_status.success?
108+
usage("Unable to enumerate Git index") unless index_status.success?
92109

93110
errors = Set.new
94111
findings = Set.new

public-source-release-audit/tests/test_check_current_source.rb

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,22 @@ def test_staged_credential_cannot_be_hidden_by_clean_worktree_replacement
6060
end
6161
end
6262

63+
def test_subdirectory_argument_still_scans_the_complete_worktree
64+
with_repo do |repo|
65+
token = github_token
66+
stage(repo, "root-secret.txt", token)
67+
child = File.join(repo, "child")
68+
FileUtils.mkdir_p(child)
69+
70+
_stdout, stderr, status = run_checker(child)
71+
72+
refute status.success?
73+
assert_includes stderr, "root-secret.txt"
74+
assert_includes stderr, "GitHub token"
75+
refute_includes stderr, token
76+
end
77+
end
78+
6379
def test_unstaged_credential_is_checked_before_it_can_be_added
6480
with_repo do |repo|
6581
token = github_token
@@ -266,6 +282,48 @@ def test_git_commands_disable_lazy_object_fetching
266282
end
267283
end
268284

285+
def test_repository_fsmonitor_hook_is_disabled
286+
with_repo do |repo|
287+
stage(repo, "README.md", "Public documentation without credentials.\n")
288+
hook = File.join(repo, "fsmonitor-hook")
289+
marker = File.join(repo, "fsmonitor-ran")
290+
File.write(hook, <<~'SH')
291+
#!/bin/sh
292+
printf 'ran\n' > "$FSMONITOR_MARKER"
293+
SH
294+
FileUtils.chmod(0o755, hook)
295+
system(
296+
"git",
297+
"-C",
298+
repo,
299+
"config",
300+
"core.fsmonitor",
301+
hook,
302+
exception: true
303+
)
304+
305+
_output, error, status = Open3.capture3(
306+
{ "FSMONITOR_MARKER" => marker },
307+
"git",
308+
"-C",
309+
repo,
310+
"ls-files"
311+
)
312+
assert status.success?, error
313+
assert File.exist?(marker), "fsmonitor fixture did not execute"
314+
FileUtils.rm(marker)
315+
316+
stdout, stderr, checker_status = run_checker(
317+
repo,
318+
{ "FSMONITOR_MARKER" => marker }
319+
)
320+
321+
assert checker_status.success?, stderr
322+
assert_includes stdout, "current public-source check passed"
323+
refute File.exist?(marker), "checker executed the repository fsmonitor hook"
324+
end
325+
end
326+
269327
def test_non_utf8_git_paths_are_scanned_without_crashing
270328
with_repo do |repo|
271329
token = github_token
@@ -275,7 +333,10 @@ def test_non_utf8_git_paths_are_scanned_without_crashing
275333
#!/usr/bin/env ruby
276334
STDOUT.binmode
277335
path = "raw-\xFF.txt".b
278-
if ARGV.include?("--stage")
336+
if ARGV.include?("rev-parse")
337+
repo_index = ARGV.index("-C") + 1
338+
STDOUT.write(ARGV.fetch(repo_index) + "\n")
339+
elsif ARGV.include?("--stage")
279340
STDOUT.write("100644 #{'a' * 40} 0\t".b + path + "\0".b)
280341
elsif ARGV.include?("cat-file")
281342
STDOUT.write("gh" + "p_" + ("A" * 24))

0 commit comments

Comments
 (0)