Skip to content

fix: panic on corrupted permission.yaml instead of silently allowing all (#7432)#7458

Merged
michaelneale merged 1 commit intomainfrom
fix/corrupted-permission-yaml
Feb 28, 2026
Merged

fix: panic on corrupted permission.yaml instead of silently allowing all (#7432)#7458
michaelneale merged 1 commit intomainfrom
fix/corrupted-permission-yaml

Conversation

@michaelneale
Copy link
Copy Markdown
Collaborator

Tentative fix for #7432.

When permission.yaml is corrupted/malformed, the YAML parse error was silently swallowed and an empty HashMap returned — wiping all never_allow entries. Denied tools became silently re-allowed.

Fix: panic with a clear error message pointing to the corrupted file. Consistent with existing pattern (file read already uses .expect()). Includes test.

…all tools

When permission.yaml contains malformed YAML, the parser error was
silently swallowed via unwrap_or_else(|_| HashMap::new()), replacing
all permission entries (including never_allow) with an empty map.
This is a fail-open security bug: denied tools become allowed with
zero user notification.

Now the code logs a tracing::error with the parse error details and
panics, refusing to start with corrupted security configuration.
This is consistent with the existing panic on read failure and is
the safe default for security-critical config.

Fixes #7432
@michaelneale
Copy link
Copy Markdown
Collaborator Author

hey @marlonbarreto-git is this the kind of thing that would be better - not sure if panic, but will at least stop it. coudl also revert to most strict but then that could be annoying too if it wasn't that before? reset things? offer to help> ideas?

@michaelneale michaelneale marked this pull request as ready for review February 24, 2026 02:29
Copilot AI review requested due to automatic review settings February 24, 2026 02:29
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a critical security vulnerability where corrupted permission.yaml files were silently ignored, causing all permission restrictions (including never_allow entries) to be wiped and replaced with an empty map. This created a fail-open scenario where previously blocked tools became allowed without user notification.

Changes:

  • Replace silent error handling with explicit panic when permission.yaml cannot be parsed
  • Add error logging before panic to provide diagnostic information
  • Add test coverage to verify panic behavior on corrupted YAML

use std::fs;
use std::path::{Path, PathBuf};
use std::sync::{Arc, LazyLock, RwLock};
use tracing;
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Import the tracing macro directly instead of the module. Change use tracing; to use tracing::error; to match the idiomatic Rust pattern used throughout the codebase. This allows using error!() instead of tracing::error!().

Suggested change
use tracing;
use tracing::error;

Copilot uses AI. Check for mistakes.
@marlonbarreto-git
Copy link
Copy Markdown
Contributor

Hey @michaelneale — thanks for picking this up! The fix is a clear improvement over the silent reset. Some thoughts on the approach:

Panicking is the right call here — this is a security-relevant config file. A corrupted permission.yaml silently becoming an empty HashMap means never_allow rules disappear, which is the worst-case failure mode for a permissions system. Better to fail loud than to silently grant access.

The existing code already uses .expect() for the read_to_string call (line 47), so panicking on corrupt content is consistent with how the file-read failure is handled. If you can't read it → panic. If you can read it but it's garbage → should also panic.

One small thought: if you wanted to be slightly more graceful in the future, the alternative would be to fall back to a deny-all default (PermissionLevel::NeverAllow for everything) instead of panicking — that way a corrupted file still fails safe. But that's a bigger change and the panic is fine for now since it matches the existing pattern.

The test looks clean — #[should_panic] is the right way to assert this. 👍

@michaelneale
Copy link
Copy Markdown
Collaborator Author

@marlonbarreto-git yeah I think the silent failure of it muddling along could be frustrating, so better to blow up like this. I don't know how a file like that gets corrupted but not great!

@michaelneale michaelneale added this pull request to the merge queue Feb 28, 2026
Merged via the queue into main with commit b77b959 Feb 28, 2026
24 checks passed
@michaelneale michaelneale deleted the fix/corrupted-permission-yaml branch February 28, 2026 01:08
lifeizhou-ap added a commit that referenced this pull request Mar 2, 2026
* main: (46 commits)
  chore(deps): bump minimatch from 10.1.1 to 10.2.3 in /evals/open-model-gym/suite (#7498)
  chore(deps): bump swiper from 11.2.10 to 12.1.2 in /documentation (#7368)
  Better network failure error & antrhopic retry (#7595)
  feat: make the text bar persistent and add a queue for messages (#7560)
  fix: outdated clippy command in goosehints (#7590)
  chore(deps): bump hono from 4.11.7 to 4.12.1 in /evals/open-model-gym/mcp-harness (#7417)
  chore(deps-dev): bump ajv from 6.12.6 to 6.14.0 in /ui/desktop (#7437)
  chore(deps): bump ajv from 8.17.1 to 8.18.0 in /evals/open-model-gym/mcp-harness (#7491)
  chore(deps): bump hono from 4.12.0 to 4.12.2 in /ui/desktop (#7515)
  chore(deps-dev): bump rollup from 4.57.1 to 4.59.0 in /ui/desktop (#7522)
  chore(deps): bump minimatch in /ui/desktop (#7572)
  fix: validate configure probe for streaming providers (#7564)
  Dockerfile: add missing build/runtime dependencies (#7546)
  fix(claude-code): Permission routing for smart-approve (#7501)
  Add base_path field to custom provider config (#7558)
  fix(cli): avoid debug logging by default in CLI (#7569)
  fix: panic on corrupted permission.yaml instead of silently allowing all (#7432) (#7458)
  fix(openai): handle null reasoning effort in Responses API (#7469)
  Allow GOOSE_NODE_DIR override in batch file (#7422)
  feat: add analyze platform extension with tree-sitter AST parsing (#7542)
  ...
craigwalkeruk pushed a commit to craigwalkeruk/custom-goose that referenced this pull request Mar 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants