Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions e2e/config/test_local_settings_trust_controls
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env bash

export MISE_TRUSTED_CONFIG_PATHS=""

marker="$MISE_TMP_DIR/local-settings-trust-controls"

cat >poc.sh <<EOF
echo trusted_paths_hookenv > "$marker"
EOF

cat >.mise.toml <<EOF
[settings]
ci = "true"
paranoid = false
trusted_config_paths = ["/"]
yes = true

[env]
_.source = ["./poc.sh"]
EOF

set +e
output=$(MISE_YES=0 MISE_PARANOID=1 mise hook-env -s bash --force 2>&1)
status=$?
set -e

if [[ $status -eq 0 ]]; then
echo "FAIL: expected hook-env to reject untrusted local config"
echo "Output: $output"
exit 1
fi

if [[ -f $marker ]]; then
echo "FAIL: local trust-control settings allowed untrusted env source execution"
echo "Output: $output"
exit 1
fi

if ! echo "$output" | grep -qi "not trusted"; then
echo "FAIL: expected untrusted config error, got: $output"
exit 1
fi
4 changes: 4 additions & 0 deletions settings.toml
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ default = "false"
description = "Set to true if running in a CI environment"
deserialize_with = "bool_string"
env = "CI"
global_only = true
hide = true
type = "Bool"

Expand Down Expand Up @@ -1781,6 +1782,7 @@ docs = """
Enables extra-secure behavior. See [Paranoid](/paranoid.html).
"""
env = "MISE_PARANOID"
global_only = true
type = "Bool"

[pin]
Expand Down Expand Up @@ -2629,6 +2631,7 @@ Set to `["/"]` to trust all config files, effectively disabling the trust mechan
Paths are separated by the OS path separator when using the environment variable \
(`:` on Unix, `;` on Windows)."""
env = "MISE_TRUSTED_CONFIG_PATHS"
global_only = true
parse_env = "list_by_os_path_separator"
rust_type = "BTreeSet<PathBuf>"
type = "ListPath"
Expand Down Expand Up @@ -2753,6 +2756,7 @@ type = "String"
[yes]
description = "This will automatically answer yes or no to prompts. This is useful for scripting."
env = "MISE_YES"
global_only = true
type = "Bool"

[zig.use_community_mirrors]
Expand Down
51 changes: 51 additions & 0 deletions src/config/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1098,6 +1098,57 @@ mod tests {
);
}

#[test]
fn test_parse_settings_file_strips_non_global_trust_controls() {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join(".mise.toml");
std::fs::write(
&path,
r#"
[settings]
ci = "true"
paranoid = true
trusted_config_paths = ["/"]
yes = true
"#,
)
.unwrap();

let partial = Settings::parse_settings_file(&path).unwrap();

assert_eq!(partial.ci, None);
assert_eq!(partial.paranoid, None);
assert_eq!(partial.trusted_config_paths, None);
assert_eq!(partial.yes, None);
}

#[test]
fn test_global_config_preserves_trust_controls() {
let path = Path::new("/tmp/global-config.toml");
let mut settings = toml::from_str::<toml::Value>(
r#"
ci = "true"
paranoid = true
trusted_config_paths = ["/"]
yes = true
"#,
)
.unwrap()
.as_table()
.unwrap()
.clone();
strip_local_only_settings(&mut settings, path, true);
let partial = settings_partial_from_table(settings);

assert_eq!(partial.ci, Some(true));
assert_eq!(partial.paranoid, Some(true));
assert_eq!(
partial.trusted_config_paths,
Some([PathBuf::from("/")].into_iter().collect())
);
assert_eq!(partial.yes, Some(true));
}

#[test]
fn test_set_by_comma_empty_string() {
let result: Result<BTreeSet<String>, _> = set_by_comma("");
Expand Down
Loading