Skip to content

fix(config): ignore local trust controls#10357

Merged
jdx merged 3 commits into
mainfrom
fix/local-trust-settings-bypass
Jun 12, 2026
Merged

fix(config): ignore local trust controls#10357
jdx merged 3 commits into
mainfrom
fix/local-trust-settings-bypass

Conversation

@jdx

@jdx jdx commented Jun 12, 2026

Copy link
Copy Markdown
Owner

Fixes GHSA-436v-8fw5-4mj8 by ignoring trust-control settings from non-global config files before trust checks run.

Summary

  • ignore local project values for trust-control settings before settings are loaded
  • keep global config, CLI, and environment settings behavior unchanged
  • add unit and e2e regression coverage for the trust bypass

Tests

  • mise run format
  • cargo test test_parse_settings_file_strips_local_trust_controls
  • mise run test:e2e e2e/config/test_local_settings_trust_controls

Note

High Risk
Security fix for config trust bypass; behavior change for anyone who relied on project-level trusted_config_paths, paranoid, ci, or yes in local mise.toml files.

Overview
Fixes a trust bypass (GHSA-436v-8fw5-4mj8) by treating ci, paranoid, trusted_config_paths, and yes as global-only settings in settings.toml, so they are stripped when loading project/local config via the existing strip_local_only_settings path in parse_settings_file.

A malicious local .mise.toml can no longer set e.g. trusted_config_paths = ["/"] or paranoid = false to auto-trust itself or skip prompts before env sources run. Global config, CLI flags, and environment variables are unchanged.

Regression coverage adds unit tests for strip vs preserve behavior and an e2e script that asserts hook-env rejects an untrusted config (with MISE_PARANOID=1) and does not run _.source scripts.

Reviewed by Cursor Bugbot for commit 37e2538. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • Bug Fixes

    • Trust-related configuration keys are no longer honored from non-global/local config files, preventing local overrides of global trust behavior.
  • Tests

    • Added unit tests for stripping trust keys in local configs and an end-to-end test that simulates an untrusted local config, verifies the command fails with a “not trusted” message, and ensures no side effects.

@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 81f48d94-609a-4f15-887f-7f4cdc5ca5dc

📥 Commits

Reviewing files that changed from the base of the PR and between 2b272c2 and 37e2538.

📒 Files selected for processing (3)
  • e2e/config/test_local_settings_trust_controls
  • settings.toml
  • src/config/settings.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • e2e/config/test_local_settings_trust_controls

📝 Walkthrough

Walkthrough

Strips trust-related fields (ci, paranoid, trusted_config_paths, yes) from non-global settings during parsing via a new helper, integrates it into Settings::parse_settings_file, and adds unit and end-to-end tests validating local configs cannot set those controls.

Changes

Trust Controls Enforcement

Layer / File(s) Summary
Trust controls stripping in settings parsing
src/config/settings.rs
Adds strip_non_global_trust_controls to clear trust-related fields for non-global config paths and calls it from Settings::parse_settings_file before alias normalization.
Schema metadata for global-only keys
settings.toml
Marks ci, paranoid, trusted_config_paths, and yes with global_only = true in the settings schema.
Unit tests for stripping behavior
src/config/settings.rs
Adds two unit tests verifying trust-related fields are cleared for local .mise.toml and preserved for global config paths.
End-to-end untrusted config validation
e2e/config/test_local_settings_trust_controls
E2E Bash test creates a .mise.toml referencing ./poc.sh, runs mise hook-env with untrusted env, asserts the command fails, the marker file was not created, and output includes a “not trusted” message.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • jdx/mise#10356: Also modifies src/config/settings.rs::Settings::parse_settings_file to strip configuration values for non-global parsed paths (clears credential_command in that PR).

Poem

I nibble lines and fold the knots,
I hide the sneaky trusty spots.
Local files lose their secret art—
A bashy test, a muffled start.
Hooray, the rabbit stamps its cart! 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately summarizes the main change: ignoring trust control settings loaded from local (non-global) configuration files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps

greptile-apps Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes GHSA-436v-8fw5-4mj8 by marking ci, paranoid, trusted_config_paths, and yes as global_only in settings.toml, causing the existing strip_local_only_settings mechanism to silently drop these keys (with a warning) when they appear in any non-global config file before settings are merged.

  • settings.toml: Four trust-influencing settings gain global_only = true, slotting into the already-wired stripping pipeline with no new Rust logic required.
  • src/config/settings.rs: Two unit tests verify the strip path (temp dir → keys become None) and the preserve path (is_global = true → all four values survive deserialization).
  • e2e/config/test_local_settings_trust_controls: An end-to-end regression test writes a .mise.toml that attempts trusted_config_paths = [\"/\"], runs mise hook-env under forced paranoid mode with empty trusted paths, and asserts non-zero exit, absence of a side-effect marker file, and "not trusted" in stderr.

Confidence Score: 5/5

Safe to merge — the change is minimal, extends an already-proven stripping mechanism, and is covered by both unit and e2e tests that directly exercise the bypass scenario.

The fix piggybacks on the existing global_only / strip_local_only_settings infrastructure already proven for credential_command. Adding four keys to settings.toml with global_only = true is the entire change on the Rust side. The strip function, its path-discrimination logic via is_global_config, and the warning path are all unchanged. Unit tests cover both strip and preserve branches; the e2e test confirms the end-to-end attack vector is closed.

No files require special attention.

Important Files Changed

Filename Overview
settings.toml Adds global_only = true to ci, paranoid, trusted_config_paths, and yes — extends the existing stripping mechanism to cover the four settings that can be weaponised for trust bypass.
src/config/settings.rs Adds two unit tests: one confirming the four trust-control keys are stripped from a non-global file path, and one confirming they are preserved when is_global = true is passed directly to strip_local_only_settings.
e2e/config/test_local_settings_trust_controls New e2e regression test: writes a local .mise.toml that attempts to trust / via trusted_config_paths and sets ci/yes/paranoid overrides, then asserts that mise hook-env rejects the config and the poc.sh payload is never executed.

Reviews (3): Last reviewed commit: "refactor(config): clarify global-only tr..." | Re-trigger Greptile

Comment thread src/config/settings.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@e2e/config/test_local_settings_trust_controls`:
- Around line 22-33: The test currently masks hook-env's exit status by
appending "|| true" so it can wrongly pass when hook-env warns but exits 0;
change the test to capture and assert hook-env's actual exit code instead of
ignoring it: run the command (MISE_YES=0 MISE_PARANOID=1 mise hook-env -s bash
--force) into output, capture its exit status (e.g., via $?), assert that the
exit status is non-zero (fail the test if it is zero), and then continue to
check the marker absence and that output contains "not trusted"; update
references to the hook-env invocation and the marker check accordingly so the
test fails when hook-env exits 0.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f0778bb7-02f0-4440-9792-1812c9a4f092

📥 Commits

Reviewing files that changed from the base of the PR and between fff92e0 and eb18499.

📒 Files selected for processing (2)
  • e2e/config/test_local_settings_trust_controls
  • src/config/settings.rs

Comment thread e2e/config/test_local_settings_trust_controls Outdated
@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown

Hyperfine Performance

mise x -- echo

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.6.4 x -- echo 21.9 ± 1.4 19.6 29.4 1.00
mise x -- echo 23.6 ± 1.9 20.5 40.8 1.08 ± 0.11

mise env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.6.4 env 21.7 ± 1.3 19.3 27.6 1.00
mise env 22.6 ± 1.5 19.9 29.9 1.04 ± 0.10

mise hook-env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.6.4 hook-env 23.7 ± 1.6 20.3 29.4 1.00
mise hook-env 24.2 ± 1.7 20.5 30.4 1.02 ± 0.10

mise ls

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.6.4 ls 19.2 ± 1.5 15.6 23.8 1.00
mise ls 19.6 ± 1.4 16.7 25.7 1.02 ± 0.11

xtasks/test/perf

Command mise-2026.6.4 mise Variance
install (cached) 148ms 149ms +0%
ls (cached) 67ms 69ms -2%
bin-paths (cached) 73ms 73ms +0%
task-ls (cached) 143ms 143ms +0%

@jdx jdx force-pushed the fix/local-trust-settings-bypass branch from 2b272c2 to 37e2538 Compare June 12, 2026 16:59
@jdx jdx merged commit f696567 into main Jun 12, 2026
35 checks passed
@jdx jdx deleted the fix/local-trust-settings-bypass branch June 12, 2026 17:22
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.

1 participant