{"record":{"id":"7bc498c3c1f32439","repo":"jdx/mise","slug":"invalid-repository-origin","errorCode":null,"errorMessage":"invalid repository origin","messagePattern":"invalid repository origin","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/remote_repository.rs","lineNumber":46,"sourceCode":"async fn git_async(path: &Path, args: &[&str]) -> Result<String> {\n    let mut command = Command::new(\"git\");\n    crate::git::sanitize_git_command(&mut command);\n    command.arg(\"-C\").arg(path).args(args);\n    let output = tokio::process::Command::from(command)\n        .kill_on_drop(true)\n        .output()\n        .await?;\n    if !output.status.success() {\n        bail!(\"repository operation failed ({})\", output.status);\n    }\n    Ok(String::from_utf8(output.stdout)?\n        .trim_end_matches('\\n')\n        .to_string())\n}\n\npub(crate) fn validate_origin(origin: &str) -> Result<()> {\n    if origin.starts_with('-') || origin.chars().any(char::is_control) {\n        bail!(\"invalid repository origin\");\n    }\n    // Explicit local paths may contain colons; otherwise :: selects a Git helper.\n    let explicit_local = std::path::Path::new(origin).is_absolute()\n        || origin.starts_with(\"./\")\n        || origin.starts_with(\"../\");\n    if !explicit_local\n        && origin.split_once(\"::\").is_some_and(|(prefix, _)| {\n            !prefix.is_empty() && !prefix.contains(['/', '\\\\', '[', ']', '@', ':'])\n        })\n    {\n        bail!(\"Git remote helpers are not supported for remote onboarding\");\n    }\n    if !explicit_local && origin.contains(\"://\") {\n        let url = url::Url::parse(origin).wrap_err(\"invalid repository URL\")?;\n        if !matches!(url.scheme(), \"https\" | \"ssh\" | \"file\") {\n            bail!(\"remote bootstrap requires HTTPS, SSH, or a local path\");\n        }\n    }","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/remote_repository.rs#L28-L64","documentation":"`validate_origin` screens the repository origin before it is passed to git: it must not start with '-' (which git would parse as a flag, enabling argument injection) and must contain no control characters. Non-explicit-local origins (not absolute/./.. paths) must further be a valid remote URL form (an scp-like or URL scheme selected by '::'). Failing these checks throws this error.","triggerScenarios":"Configuring an origin like '-upload-pack=evil', a string with embedded control bytes, or a non-local value that is neither a valid URL nor scp-like syntax (no scheme/colon pattern).","commonSituations":"Typo'd remote URLs; copy-paste introducing invisible control characters; attempts to pass extra git flags through the origin; writing a bare hostname without the required URL/scp form.","solutions":["Correct the origin to a valid git URL (https://..., git@host:path, ssh://...) or an explicit local path (absolute, ./, or ../)","Remove any leading '-' and control characters from the configured origin","Re-check the remote.toml/config encoding (save as clean UTF-8) if invisible characters are suspected"],"exampleFix":"// before\norigin = \"-u evil.com/repo.git\"\n// after\norigin = 'https://evil.com/repo.git'","handlingStrategy":"validation","validationCode":"function isValidOrigin(o) {\n  if (typeof o !== 'string' || o.startsWith('-') || /[\\x00-\\x1f]/.test(o)) return false;\n  if (/^(\\/|\\.\\.?\\/)/.test(o)) return true; // explicit local path\n  return /^(ssh|https?|git|file):\\/\\//.test(o) || /^[^\\s:]+:[^\\/]/.test(o); // URL or scp-like\n}","typeGuard":"const isSafeOrigin = (o: unknown): o is string =>\n  typeof o === 'string' && !o.startsWith('-') && !/[\\x00-\\x1f]/.test(o) && o.length > 0;","tryCatchPattern":"try { validate_origin(origin)?; } catch (e) {\n  // prompt user for a corrected git URL before any git invocation\n}","preventionTips":["Always configure origins as full https/ssh URLs or explicit local paths","Never allow config values that begin with '-' to reach git arguments","Save config files as clean UTF-8 to avoid control characters","Validate origins at config-load time, not at first git call"],"tags":["git","security","validation","config"],"backgroundTag":"invalid-url-format","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}