Skip to content

lint: SECURITY/insecure-transport false positive on validate_url in komide #203

@forkwright

Description

@forkwright

Where

crates/komide/src/service/mod.rs:572 in validate_url:

fn validate_url(url: &str) -> Result<(), KomideError> {
    if url.is_empty() || (!url.starts_with("http://") && !url.starts_with("https://")) {
        return InvalidUrlSnafu { url: url.to_string() }.fail();
    }
    Ok(())
}

Current kanon lint output

ERROR komide/src/service/mod.rs:572  [SECURITY/insecure-transport]
  HTTP URL for API endpoint (use HTTPS for credential safety)

Why this is a false positive

The "http://" literal here is a prefix check for input validation, not a hardcoded outbound endpoint. Komide accepts user-supplied podcast RSS feed URLs; many legitimate podcast feeds are still served over plain HTTP, so rejecting http:// inputs would break real use cases.

The SECURITY/insecure-transport rule is meant to catch code like reqwest::get("http://api.example.com/secret"), not prefix-match validation.

Proposed fix (pick one)

  1. Scope the rule to reqwest/hyper/ureq URL construction call-sites only — not str::starts_with pattern matches. This is the right fix upstream (in kanon basanos/standards).
  2. Targeted suppression at the call-site with reason:
    // kanon-allow: SECURITY/insecure-transport — prefix validator, not outbound URL
    if url.is_empty() || (!url.starts_with("http://") && !url.starts_with("https://")) {
  3. Refactor to parse via url::Url and check scheme — avoids the string-literal trigger entirely:
    let parsed = url::Url::parse(url).map_err(|_| InvalidUrlSnafu { url: url.into() }.build())?;
    match parsed.scheme() {
        "http" | "https" => Ok(()),
        _ => InvalidUrlSnafu { url: url.into() }.fail(),
    }
    This is the strongest option: more correct (catches htp://, https:/foo, etc.) and dodges the lint.

Context

Surfaced while clearing unrelated clippy errors in fix/clippy-too-many-args-post-lint-sync — this error is pre-existing on main @ a18094c and blocks kanon gate for any PR against main. Tracking separately so the clippy-fix PR stays scoped.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions