{"record":{"id":"3aaa7d81d7442147","repo":"jdx/mise","slug":"user-service-environment-value-for-key-con","errorCode":null,"errorMessage":"user service '{}': environment value for {key} contains {c:?}, which cmd.exe would reinterpret; set it inside the program instead","messagePattern":"user service '(.+?)': environment value for (.+?) contains (.+?), which cmd\\.exe would reinterpret; set it inside the program instead","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/scheduled_tasks.rs","lineNumber":216,"sourceCode":"/// change are rejected rather than passed through differently.\nfn exec_action(request: &ScheduledTaskRequest) -> Result<(String, String)> {\n    let (program, args) = split_command(&request.command);\n    if request.environment.is_empty() {\n        return Ok((program, args));\n    }\n    let mut sets = vec![];\n    for (key, value) in &request.environment {\n        if key.is_empty() || key.contains(['=', '\"', '%', '\\n', '\\r']) {\n            bail!(\n                \"user service '{}': environment key {key:?} cannot be set through cmd.exe\",\n                request.name\n            );\n        }\n        if let Some(c) = value\n            .chars()\n            .find(|c| matches!(c, '\"' | '%' | '&' | '|' | '<' | '>' | '^' | '\\n' | '\\r'))\n        {\n            bail!(\n                \"user service '{}': environment value for {key} contains {c:?}, which cmd.exe would reinterpret; set it inside the program instead\",\n                request.name\n            );\n        }\n        sets.push(format!(\"set \\\"{key}={value}\\\"\"));\n    }\n    // the command line goes through cmd.exe too: what it would split or\n    // chain is rejected the same way, rather than run differently\n    if let Some(c) = format!(\"{program} {args}\")\n        .chars()\n        .find(|c| matches!(c, '%' | '&' | '|' | '<' | '>' | '^' | '\\n' | '\\r'))\n    {\n        bail!(\n            \"user service '{}': the command contains {c:?}, which cmd.exe would reinterpret when `environment` is set; move it into a script\",\n            request.name\n        );\n    }\n    let program = if program.contains(char::is_whitespace) {","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/scheduled_tasks.rs#L198-L234","documentation":"When environment variables are set via cmd.exe `set` commands, characters like quotes, percent signs, and cmd metacharacters (&, |, <, >, ^) or line breaks would be reinterpreted by cmd.exe rather than stored literally in the value. exec_action rejects any value containing them to avoid command injection or corrupted env values.","triggerScenarios":"Calling render_xml (via exec_action) for a user service whose request.environment has a value containing any of: '\"', '%', '&', '|', '<', '>', '^', '\\n', or '\\r'.","commonSituations":"Passwords or connection strings containing '&' or '%'; JSON or regex snippets with quotes; multi-line certificates/keys pasted into an env var; Windows-style '%VAR%' expansion strings; values read from files with trailing CRLF.","solutions":["Remove or escape-safe the offending character in the value — set it inside the program itself (config file, internal env setup) instead of through the service definition.","Strip CR/LF when loading values from files or YAML.","Base64-encode values containing metacharacters and decode them in the program.","If the value legitimately needs '%', avoid the cmd.exe env mechanism: drop request.environment and encode the setting in the command or program config."],"exampleFix":"// before\nenv.insert(\"CONN\".into(), \"Server=a&Password=b\".into());\n// after\nenv.insert(\"CONN_FILE\".into(), \"C:\\\\svc\\\\conn.txt\".into()); // program reads the value from the file","handlingStrategy":"validation","validationCode":"fn valid_env_value(key: &str, value: &str) -> Result<(), String> {\n    if let Some(c) = value.chars().find(|c| matches!(c, '\"' | '%' | '&' | '|' | '<' | '>' | '^' | '\\n' | '\\r')) {\n        return Err(format!(\"env value for {key} contains forbidden char {c:?}\"));\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Store secret/complex values in files and pass the file path instead of the raw value","Base64-encode values that must contain metacharacters and decode inside the program","Strip CR/LF from values read from YAML/.env sources","Keep passwords out of env vars set through cmd.exe entirely"],"tags":["windows","environment-variables","injection"],"backgroundTag":"invalid-argument-value","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}