fix: Use SafeCommand directly for vault health check to avoid shell injection false positive
All checks were successful
BotServer CI/CD / build (push) Successful in 6m46s
All checks were successful
BotServer CI/CD / build (push) Successful in 6m46s
- Replace safe_sh_command with SafeCommand::new("curl").args() in vault_health_check()
- The URL contains https:// which triggered '//' pattern detection in shell command
- Direct SafeCommand bypasses shell parsing, URL passed as single argument
- Add vault data directory existence check before recovery attempt
- Prevents 'Dangerous pattern // detected' errors during bootstrap
This commit is contained in:
parent
07a6c1edb3
commit
9919a8321c
2 changed files with 62 additions and 46 deletions
|
|
@ -90,25 +90,30 @@ pub fn vault_health_check() -> bool {
|
|||
let vault_addr =
|
||||
std::env::var("VAULT_ADDR").unwrap_or_else(|_| "https://localhost:8200".to_string());
|
||||
|
||||
let cmd = format!(
|
||||
"curl -f -s --connect-timeout 2 -k {}/v1/sys/health",
|
||||
vault_addr
|
||||
);
|
||||
let health_url = format!("{}/v1/sys/health", vault_addr);
|
||||
|
||||
let output = safe_sh_command(&cmd);
|
||||
if output.is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
if let Ok(json) = serde_json::from_str::<serde_json::Value>(&output) {
|
||||
match SafeCommand::new("curl")
|
||||
.and_then(|c| c.args(&["-f", "-s", "--connect-timeout", "2", "-k", &health_url]))
|
||||
.and_then(|c| c.execute())
|
||||
{
|
||||
Ok(output) => {
|
||||
if output.status.success() {
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
if let Ok(json) = serde_json::from_str::<serde_json::Value>(&stdout) {
|
||||
let sealed = json.get("sealed").and_then(|v| v.as_bool()).unwrap_or(true);
|
||||
let initialized = json
|
||||
.get("initialized")
|
||||
.and_then(|v| v.as_bool())
|
||||
.unwrap_or(false);
|
||||
!sealed && initialized
|
||||
} else {
|
||||
false
|
||||
return !sealed && initialized;
|
||||
}
|
||||
}
|
||||
// Health endpoint returns 503 when sealed but initialized
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
stdout.contains("\"initialized\":true") || stderr.contains("\"initialized\":true")
|
||||
}
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1387,6 +1387,15 @@ EOF"#.to_string(),
|
|||
let vault_bin = bin_path.join("vault");
|
||||
let vault_data = self.base_path.join("data/vault");
|
||||
|
||||
// Check if Vault data directory exists (real indicator of initialized state)
|
||||
let vault_data_exists = vault_data.exists();
|
||||
|
||||
if !vault_data_exists {
|
||||
info!("Vault data directory not found, will initialize fresh");
|
||||
} else {
|
||||
info!("Vault data directory found, checking health...");
|
||||
}
|
||||
|
||||
// Wait for Vault to be ready
|
||||
info!("Waiting for Vault to start...");
|
||||
std::thread::sleep(std::time::Duration::from_secs(3));
|
||||
|
|
@ -1395,6 +1404,8 @@ EOF"#.to_string(),
|
|||
std::env::var("VAULT_ADDR").unwrap_or_else(|_| "https://localhost:8200".to_string());
|
||||
let ca_cert = conf_path.join("system/certificates/ca/ca.crt");
|
||||
|
||||
// Only attempt recovery if data directory exists
|
||||
if vault_data_exists {
|
||||
// Check if Vault is already initialized via health endpoint
|
||||
let health_cmd = format!(
|
||||
"curl -f -s --connect-timeout 2 -k {}/v1/sys/health",
|
||||
|
|
@ -1419,16 +1430,16 @@ EOF"#.to_string(),
|
|||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
stdout.contains("\"initialized\":true")
|
||||
|| stderr.contains("\"initialized\":true")
|
||||
|| vault_data.exists()
|
||||
}
|
||||
} else {
|
||||
vault_data.exists()
|
||||
false
|
||||
};
|
||||
|
||||
if already_initialized {
|
||||
info!("Vault already initialized (detected via health/data), skipping init");
|
||||
return self.recover_existing_vault();
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize Vault
|
||||
let init_cmd = format!(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue