Skip to content

Network policy: wildcard host matching not supported #663

@JMLX42

Description

@JMLX42

Summary

The network policy's AllowedHost::matches() performs exact string comparison, so neither global wildcards (host: "*") nor subdomain wildcards (host: "*.example.com") work. The wildcard characters are stored literally and compared against request hosts, which never matches.

Reproduction

  1. Load a WASM component with a policy granting network access to host: "*" (or host: "*.example.com")
  2. The component attempts an HTTP request to any host (e.g., https://www.sciencedaily.com/...)
  3. The request is blocked with:
    WARN wassette::http: HTTP request blocked by network policy
      uri=https://www.sciencedaily.com/...
      allowed_hosts={AllowedHost { scheme: None, host: "*" }}
    

Root cause

In crates/wassette/src/http.rs, AllowedHost::matches() does:

fn matches(&self, request_host: &str, request_scheme: Option<&str>) -> bool {
    if self.host != request_host {
        return false;
    }
    // ...
}

There is no special handling for wildcards — they are compared literally against the request host.

Expected behavior

Two wildcard patterns should be supported:

Pattern Matches Does not match
* any host
*.example.com foo.example.com, bar.baz.example.com example.com (bare domain)

Suggested fix

fn matches(&self, request_host: &str, request_scheme: Option<&str>) -> bool {
    let host_matches = if self.host == "*" {
        true
    } else if let Some(suffix) = self.host.strip_prefix("*.") {
        request_host.ends_with(suffix)
            && request_host.len() > suffix.len()
            && request_host.as_bytes()[request_host.len() - suffix.len() - 1] == b'.'
    } else {
        self.host == request_host
    };

    if !host_matches {
        return false;
    }

    match (&self.scheme, request_scheme) {
        (Some(allowed_scheme), Some(req_scheme)) => allowed_scheme == req_scheme,
        _ => true,
    }
}

This issue was drafted with the help of an AI assistant (Claude).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions