Preserve trusted MITM hook constraints

This commit is contained in:
Winston Howes
2026-05-16 01:34:43 -07:00
parent 60c59733f2
commit f74951488b
4 changed files with 140 additions and 1 deletions
+55
View File
@@ -1529,6 +1529,61 @@ mod tests {
assert!(validate_policy_against_constraints(&config, &constraints).is_err());
}
#[test]
fn validate_policy_against_constraints_preserves_managed_mitm_hooks() {
let managed_hook = crate::mitm_hook::MitmHookConfig {
host: "api.github.com".to_string(),
matcher: crate::mitm_hook::MitmHookMatchConfig {
methods: vec!["POST".to_string()],
path_prefixes: vec!["/repos/openai/".to_string()],
..crate::mitm_hook::MitmHookMatchConfig::default()
},
actions: crate::mitm_hook::MitmHookActionsConfig {
strip_request_headers: vec!["authorization".to_string()],
..crate::mitm_hook::MitmHookActionsConfig::default()
},
};
let extra_hook = crate::mitm_hook::MitmHookConfig {
host: "api.example.com".to_string(),
matcher: crate::mitm_hook::MitmHookMatchConfig {
methods: vec!["GET".to_string()],
path_prefixes: vec!["/".to_string()],
..crate::mitm_hook::MitmHookMatchConfig::default()
},
..crate::mitm_hook::MitmHookConfig::default()
};
let constraints = NetworkProxyConstraints {
required_mitm_hook_prefix: Some(vec![managed_hook.clone()]),
..NetworkProxyConstraints::default()
};
let config = NetworkProxyConfig {
network: NetworkProxySettings {
enabled: true,
mitm: true,
mitm_hooks: vec![managed_hook.clone(), extra_hook],
..NetworkProxySettings::default()
},
};
assert!(validate_policy_against_constraints(&config, &constraints).is_ok());
let config = NetworkProxyConfig {
network: NetworkProxySettings {
enabled: true,
mitm: true,
mitm_hooks: vec![crate::mitm_hook::MitmHookConfig {
actions: crate::mitm_hook::MitmHookActionsConfig {
strip_request_headers: vec!["x-api-key".to_string()],
..crate::mitm_hook::MitmHookActionsConfig::default()
},
..managed_hook
}],
..NetworkProxySettings::default()
},
};
assert!(validate_policy_against_constraints(&config, &constraints).is_err());
}
#[test]
fn validate_policy_against_constraints_allows_narrowing_wildcard_allowlist() {
let constraints = NetworkProxyConstraints {
+13
View File
@@ -36,6 +36,7 @@ pub struct NetworkProxyConstraints {
pub denylist_expansion_enabled: Option<bool>,
pub allow_unix_sockets: Option<Vec<String>>,
pub allow_local_binding: Option<bool>,
pub required_mitm_hook_prefix: Option<Vec<MitmHookConfig>>,
}
#[derive(Debug, Clone, Deserialize)]
@@ -126,6 +127,18 @@ pub fn validate_policy_against_constraints(
let config_allow_unix_sockets = config.network.allow_unix_sockets();
validate_mitm_hook_config(config).map_err(invalid_mitm_hook_configuration)?;
validate_non_global_wildcard_domain_patterns("network.denied_domains", &config_denied_domains)?;
if let Some(required_mitm_hook_prefix) = constraints.required_mitm_hook_prefix.as_ref()
&& !config
.network
.mitm_hooks
.starts_with(required_mitm_hook_prefix)
{
return Err(invalid_value(
"network.mitm_hooks",
"managed MITM hooks were replaced or reordered",
"managed MITM hooks preserved before lower-trust hooks",
));
}
if let Some(max_enabled) = constraints.enabled {
validate(enabled, move |candidate| {
if *candidate && !max_enabled {