-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
feat(config): load safe mise.toml files without trust #10360
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
1be6abf
feat(config): load safe mise.toml files without trust
jdx 46e02fd
feat(config): allow tasks in safe untrusted configs
jdx ad54f73
fix(config): close trust bypass via escaped template delimiters
jdx c70a4dc
docs: regenerate man page for trust safe-config text
jdx c01306d
fix(task): close trust bypass via escaped templates in task includes
jdx 1dd9a7e
test(task): exercise decoded #MISE header path in escaped-template test
jdx File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,112 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
| # Safe mise.toml files (min_version, [tools] with plain version strings, and | ||
| # [tasks]) can be loaded without trusting them first. Anything that can execute | ||
| # code at load time or change mise's behavior still requires trust. | ||
|
|
||
| export MISE_TRUSTED_CONFIG_PATHS="" | ||
| unset CI GITHUB_ACTIONS GITHUB_ACTION 2>/dev/null || true | ||
|
|
||
| # Fail if any trust marker file/symlink exists under trusted-configs. This is | ||
| # precise (a stale empty dir won't mask a wrongly-written marker) unlike a bare | ||
| # directory-existence check. | ||
| assert_no_trust_marker() { | ||
| local found | ||
| found=$(find "$MISE_STATE_DIR/trusted-configs" -mindepth 1 \( -type f -o -type l \) 2>/dev/null || true) | ||
| [[ -z $found ]] || fail "$1 (found trust markers: $found)" | ||
| } | ||
|
|
||
| mkdir -p project | ||
| cd project || exit 1 | ||
|
|
||
| cat <<'EOF' >mise.toml | ||
| min_version = "2024.1.1" | ||
|
|
||
| [tools] | ||
| tiny = "3.1.0" | ||
|
|
||
| [tasks.hi] | ||
| run = "echo task-ran-without-trust" | ||
| EOF | ||
|
|
||
| # loads without prompting and without creating a trust marker | ||
| MISE_YES=0 mise install tiny | ||
| assert_contains "MISE_YES=0 mise ls tiny" "3.1.0" | ||
| assert_no_trust_marker "safe config should not be silently trusted" | ||
|
|
||
| # config tasks only execute on explicit `mise run`, so they don't need trust | ||
| assert_contains "MISE_YES=0 mise run hi" "task-ran-without-trust" | ||
|
|
||
| # template-free file tasks are inert at load time and runnable without trust | ||
| mkdir -p mise-tasks | ||
| cat <<'EOF' >mise-tasks/filetask | ||
| #!/usr/bin/env bash | ||
| #MISE description="a plain file task" | ||
| echo file-task-ran-without-trust | ||
| EOF | ||
| chmod +x mise-tasks/filetask | ||
| assert_contains "MISE_YES=0 mise run filetask" "file-task-ran-without-trust" | ||
| assert_no_trust_marker "file task should not require or create trust" | ||
|
|
||
| # a template in a file task header renders at load time, so it requires trust | ||
| cat <<'EOF' >mise-tasks/evil | ||
| #!/usr/bin/env bash | ||
| #MISE description="{{ exec(command='echo PWNED > marker') }}" | ||
| echo evil | ||
| EOF | ||
| chmod +x mise-tasks/evil | ||
| output=$(MISE_YES=0 mise tasks 2>&1 || true) | ||
| [[ ! -f marker ]] || fail "file task header template executed without trust" | ||
| echo "$output" | grep -qi "trust" || fail "expected trust error for templated file task, got: $output" | ||
| rm mise-tasks/evil | ||
|
|
||
| # a template in a version string requires trust and must not execute | ||
| cat <<'EOF' >mise.toml | ||
| [tools] | ||
| tiny = "{{ exec(command='echo PWNED > marker') }}" | ||
| EOF | ||
| output=$(MISE_YES=0 mise ls 2>&1 || true) | ||
| [[ ! -f marker ]] || fail "template executed in untrusted config" | ||
| echo "$output" | grep -qi "trust" || fail "expected trust error for template, got: $output" | ||
|
|
||
| # a template in a task renders at load time, so it requires trust | ||
| cat <<'EOF' >mise.toml | ||
| [tasks.hi] | ||
| run = "echo hi" | ||
| description = "{{ exec(command='echo PWNED > marker') }}" | ||
| EOF | ||
| output=$(MISE_YES=0 mise tasks 2>&1 || true) | ||
| [[ ! -f marker ]] || fail "task template executed in untrusted config" | ||
| echo "$output" | grep -qi "trust" || fail "expected trust error for task template, got: $output" | ||
|
|
||
| # escaped Tera delimiters ({ == '{', } == '}') decode to a template | ||
| # after TOML parsing; this must not bypass the safety check and exec | ||
| printf '[tools]\ntiny = "\\u007b\\u007b exec(command=%stouch marker%s) \\u007d\\u007d"\n' "'" "'" >mise.toml | ||
| output=$(MISE_YES=0 mise ls 2>&1 || true) | ||
| [[ ! -f marker ]] || fail "escaped template executed in untrusted config (tools)" | ||
| echo "$output" | grep -qi "trust" || fail "expected trust error for escaped tools template, got: $output" | ||
|
|
||
| printf '[tasks.hi]\nrun = "echo hi"\ndescription = "\\u007b\\u007b exec(command=%stouch marker%s) \\u007d\\u007d"\n' "'" "'" >mise.toml | ||
| output=$(MISE_YES=0 mise tasks 2>&1 || true) | ||
| [[ ! -f marker ]] || fail "escaped template executed in untrusted config (tasks)" | ||
| echo "$output" | grep -qi "trust" || fail "expected trust error for escaped task template, got: $output" | ||
|
|
||
| # tool options can run code (postinstall) or alter installs (install_env) | ||
| cat <<'EOF' >mise.toml | ||
| [tools] | ||
| tiny = { version = "3.1.0", postinstall = "touch marker" } | ||
| EOF | ||
| output=$(MISE_YES=0 mise ls 2>&1 || true) | ||
| echo "$output" | grep -qi "trust" || fail "expected trust error for tool options, got: $output" | ||
|
|
||
| # env vars require trust | ||
| cat <<'EOF' >mise.toml | ||
| [env] | ||
| FOO = "bar" | ||
| EOF | ||
| output=$(MISE_YES=0 mise env 2>&1 || true) | ||
| echo "$output" | grep -qi "trust" || fail "expected trust error for env, got: $output" | ||
|
|
||
| # unsafe configs still load normally once trusted | ||
| mise trust | ||
| assert_contains "mise env" "FOO=bar" | ||
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
| # A safe (untrusted) mise.toml is tracked and its tool pins remain visible | ||
| # through tracked-config reload paths like `mise ls --all-sources`, even when | ||
| # invoked from a different directory. Regression: tracked-config loading used | ||
| # to skip any config without a trust marker, which safe configs don't create. | ||
|
|
||
| export MISE_TRUSTED_CONFIG_PATHS="" | ||
| unset CI GITHUB_ACTIONS GITHUB_ACTION 2>/dev/null || true | ||
|
|
||
| mkdir -p proj other | ||
| cat <<'EOF' >proj/mise.toml | ||
| [tools] | ||
| tiny = "3.1.0" | ||
| EOF | ||
|
|
||
| # install from the safe config (loads + tracks it, no trust prompt/marker) | ||
| (cd proj && MISE_YES=0 mise install tiny) | ||
|
|
||
| # from an unrelated directory, the tracked safe config's pin is still listed | ||
| cd other || exit 1 | ||
| assert_contains "MISE_YES=0 mise ls --all-sources 2>&1" "proj/mise.toml" | ||
| assert_contains "MISE_YES=0 mise ls --all-sources 2>&1" "tiny" |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
| # Task include files (mise-tasks/*.toml and #MISE script headers) that hide a | ||
| # Tera template behind escaped delimiters ({ -> '{', } -> '}') must | ||
| # still require trust: the escapes decode to a real template that renders — and | ||
| # can exec() — at load time. A raw-text scan alone would miss them. This is the | ||
| # non-paranoid case (paranoid mode trivially requires trust for everything). | ||
|
|
||
| export MISE_TRUSTED_CONFIG_PATHS="" | ||
| unset CI GITHUB_ACTIONS GITHUB_ACTION 2>/dev/null || true | ||
|
|
||
| mkdir -p mise-tasks | ||
|
|
||
| # 1. escaped template in a .toml task file | ||
| printf '[evil]\nrun = "echo hi"\ndescription = "\\u007b\\u007b exec(command=%stouch toml-marker%s) \\u007d\\u007d"\n' "'" "'" >mise-tasks/ci.toml | ||
| output=$(MISE_YES=0 mise tasks 2>&1 || true) | ||
| [[ ! -f toml-marker ]] || fail "escaped template executed from untrusted .toml task include" | ||
| echo "$output" | grep -qi "not trusted" || fail "expected trust error for escaped .toml include, got: $output" | ||
| rm -f mise-tasks/ci.toml | ||
|
|
||
| # 2. escaped template in a #MISE script header (printf so the \u escapes reach | ||
| # the file literally, exercising the decoded-header path rather than the | ||
| # raw-text gate) | ||
| { | ||
| printf '#!/usr/bin/env bash\n' | ||
| printf '#MISE description="\\u007b\\u007b exec(command=%stouch script-marker%s) \\u007d\\u007d"\n' "'" "'" | ||
| printf 'echo hi\n' | ||
| } >mise-tasks/evil.sh | ||
| chmod +x mise-tasks/evil.sh | ||
| output=$(MISE_YES=0 mise tasks 2>&1 || true) | ||
| [[ ! -f script-marker ]] || fail "escaped template executed from untrusted script header" | ||
| echo "$output" | grep -qi "not trusted" || fail "expected trust error for escaped script header, got: $output" | ||
| rm -f mise-tasks/evil.sh | ||
|
|
||
| # 3. sanity: a plain (template-free) file task still loads without trust | ||
| cat <<'EOF' >mise-tasks/hello.sh | ||
| #!/usr/bin/env bash | ||
| #MISE description="a plain task" | ||
| echo plain-task-ran | ||
| EOF | ||
| chmod +x mise-tasks/hello.sh | ||
| assert_contains "MISE_YES=0 mise run hello" "plain-task-ran" |
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
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
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
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
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
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.