Attacker Page

Served from an external origin. The vulnerability is demonstrated if the ACL-gated plugin command below succeeds — it should only be callable by Origin::Local, but is_local_url() misclassifies this origin as local due to the subdomain confusion bug.

This page's origin
Step 1 — Tauri init scripts injected?
checking…
Step 2 — invoke('plugin:sample|ping') — ACL-gated, local origin only
waiting…
Why this works
Capability in capabilities/main.json:
  { "local": true, "permissions": ["sample:allow-ping"] }

This grants plugin:sample|ping to Origin::Local only.
A genuine remote origin would be rejected by the ACL check.

Vulnerable check in is_local_url() — crates/tauri/src/webview/mod.rs:

  let maybe_protocol = current_url
    .domain()                         // e.g. "app.localhost"
    .and_then(|d| d.split_once('.'))  //      ("app", "localhost")
    .unwrap_or_default()
    .0;                               //      "app"

  protocols.contains_key("app")       // true — "app" is registered
    && scheme == "http"               // true

  → Origin::Local granted to this external page
  → ACL check passes → plugin command executes