fix(core): harden config, path, and output trust boundaries#976
Open
ben-ranford wants to merge 1 commit into
Open
fix(core): harden config, path, and output trust boundaries#976ben-ranford wants to merge 1 commit into
ben-ranford wants to merge 1 commit into
Conversation
|
Contributor
Memory Benchmarks❌ Memory benchmark summary was not produced. Approval: unavailable because the memory benchmark gate did not complete cleanly. |
Contributor
There was a problem hiding this comment.
Pull request overview
Security-hardening sweep that tightens multiple trust boundaries across config/policy-pack loading, runtime hook discovery, git path parsing, notification redaction/escaping, CLI table output sanitization, and cache path safety.
Changes:
- Disable remote policy packs (no fetching) and adjust policy-pack trust handling/error messaging + tests.
- Anchor runtime hook lookup to fixed, non-ancestor-walk roots and add targeted tests.
- Normalize/sanitize repo-controlled strings at output boundaries (git quoted paths decoding, Slack fallback escaping, webhook redaction expansion, table-output terminal control scrubbing, cache symlink escape rejection).
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/workspace/workspace_changed_files_test.go | Adds regression coverage for decoding git-quoted non-ASCII paths from diff/status. |
| internal/workspace/changed_files.go | Decodes git C-quoted paths (defense-in-depth) in diff/status parsing. |
| internal/thresholds/config.go | Updates policy resolver trust initialization signature for hardened pack resolution. |
| internal/thresholds/config_test.go | Updates/reshapes tests to assert remote policy packs are rejected without fetching. |
| internal/thresholds/config_packs.go | Removes “explicit config implies remote trust” and hard-disables remote packs; adjusts local-root trust. |
| internal/thresholds/config_cov_more_http_test.go | Updates coverage test setup after packTrust changes. |
| internal/runtime/capture_env.go | Reworks runtime hook search roots to anchored locations; adds injectable providers for tests. |
| internal/runtime/capture_env_test.go | Adds anchored-root test and utilities for overriding executable/caller providers. |
| internal/report/terminal.go | Introduces terminal control-character sanitizer for report/table output. |
| internal/report/format_test.go | Adds regression test ensuring table output escapes control characters. |
| internal/report/format_table.go | Sanitizes string args emitted through table formatter helpers; sanitizes key row fields. |
| internal/report/format_table_values.go | Sanitizes table value renderers that may include repo-controlled strings. |
| internal/report/format_table_sections.go | Sanitizes additional table sections (scope, policy sources, comparison keys, codemod, warnings). |
| internal/notify/slack.go | Escapes Slack top-level fallback text to prevent mrkdwn injection from repo names. |
| internal/notify/slack_test.go | Adds tests covering fallback escaping for common mrkdwn/HTML-sensitive characters. |
| internal/notify/dispatcher.go | Expands webhook URL redaction candidates to cover more real-world error-message variants. |
| internal/notify/dispatcher_test.go | Adds tests for redacting path-escaped fragments, bare host+path, and bare token leakage. |
| internal/gitexec/gitexec.go | Forces core.quotePath=false to reduce quoted-path surface area in git outputs. |
| internal/analysis/cache.go | Treats symlinked cache roots as escape attempts (including broken symlinks) via Lstat precheck. |
| internal/analysis/cache_extra_test.go | Adds regression test ensuring broken symlink cache paths are rejected and don’t create dirs outside repo. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+140
to
142
| if _, filename, _, ok := runtimeCaller(0); ok { | ||
| addSearchPath(filepath.Clean(filepath.Join(filepath.Dir(filename), "..", ".."))) | ||
| } |
Comment on lines
+125
to
+129
| roots := runtimeHookSearchRoots() | ||
| want := []string{ | ||
| filepath.Clean(filepath.Join("/tmp", "plant", "bin", "..", "share", "lopper")), | ||
| filepath.Clean(filepath.Join("/tmp", "source", "internal", "runtime", "..", "..")), | ||
| } |
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.


Issue
--configturns repo config into a network-capable trust root #839, [Bug]: Runtime hook search walks every executable ancestor, allowing planted require-hook ACE #865, [Bug]: ChangedFiles never decodes git's quoted (core.quotePath) paths, dropping non-ASCII filenames #866, [Bug]: Slack top-level fallback text uses repo basename without mrkdwn escaping #867, [Bug]: Webhook URL redaction misses PathEscape and bare token segment leakage #868, [Bug]: Default 'lopper analyse --format table' does not strip terminal control chars from repo-controlled fields #869, and [Bug]: cachePathEscapesRepo returns false for broken symlinks, allowing escape outside repo #870.Cause
--confighandling could become a trust signal for remote policy packs.Root cause
Fix
Tests
go test ./internal/gitexec ./internal/thresholds ./internal/runtime ./internal/workspace ./internal/notify ./internal/report ./internal/analysis ./internal/safeio ./internal/appCloses #839
Closes #865
Closes #866
Closes #867
Closes #868
Closes #869
Closes #870