localvectordb_server.utils.hostmatch module

Host Header Validation Utilities

Provides robust host header validation with support for: - Automatic port stripping (host:port -> host) - Wildcard subdomain patterns (*.example.com) - Exact hostname matching - Case-insensitive comparison - IPv4 and IPv6 address handling

This module addresses security vulnerabilities in naive string comparison by implementing proper hostname parsing and pattern matching.

Examples

Basic usage:

from localvectordb_server.utils.hostmatch import validate_host_against_patterns

trusted_patterns = ["localhost", "*.example.com", "api.mysite.org"]

# These will match
validate_host_against_patterns("localhost:5000", trusted_patterns)  # True
validate_host_against_patterns("api.example.com", trusted_patterns)  # True
validate_host_against_patterns("www.example.com", trusted_patterns)  # True
validate_host_against_patterns("api.mysite.org", trusted_patterns)   # True

# These will not match
validate_host_against_patterns("evil.com", trusted_patterns)         # False
validate_host_against_patterns("example.com.evil.com", trusted_patterns)  # False

Pattern Types

  • Exact: example.com matches only example.com

  • Wildcard subdomain: *.example.com matches api.example.com, www.example.com, etc.

  • Wildcard any: * matches any hostname (use with caution)

  • Port handling: localhost:5000 is treated as localhost

  • Case insensitive: EXAMPLE.COM matches example.com

Security Notes

  • Wildcard patterns only match subdomains, not arbitrary domains

  • IPv6 addresses in brackets are properly handled

  • Port numbers are automatically stripped

  • Empty or malformed hosts are rejected

localvectordb_server.utils.hostmatch.parse_host(host_string: str) Tuple[str, int | None]

Extract hostname and port from host:port format.

Handles various formats including IPv6 addresses in brackets.

Parameters:

host_string (str) – Host string potentially including port (e.g., ‘localhost:5000’, ‘[::1]:8080’)

Returns:

Tuple of (hostname, port) where port is None if not specified

Return type:

Tuple[str, Optional[int]]

Examples

>>> parse_host("localhost:5000")
('localhost', 5000)
>>> parse_host("example.com")
('example.com', None)
>>> parse_host("[::1]:8080")
('::1', 8080)
>>> parse_host("[2001:db8::1]")
('2001:db8::1', None)
localvectordb_server.utils.hostmatch.normalize_hostname(hostname: str) str

Normalize hostname for comparison.

Parameters:

hostname (str) – Hostname to normalize

Returns:

Normalized hostname (lowercase, stripped)

Return type:

str

localvectordb_server.utils.hostmatch.is_valid_hostname(hostname: str) bool

Check if hostname is valid format.

Parameters:

hostname (str) – Hostname to validate

Returns:

True if hostname is valid format

Return type:

bool

localvectordb_server.utils.hostmatch.match_host_pattern(hostname: str, pattern: str) bool

Check if hostname matches pattern with wildcard support.

Supports: - Exact matches: ‘example.com’ matches only ‘example.com’ - Wildcard subdomains: ‘.example.com’ matches ‘api.example.com’, ‘www.example.com’ - Universal wildcard: ‘’ matches any hostname

Parameters:
  • hostname (str) – Hostname to check (should be normalized)

  • pattern (str) – Pattern to match against (supports wildcards)

Returns:

True if hostname matches pattern

Return type:

bool

Examples

>>> match_host_pattern("api.example.com", "*.example.com")
True
>>> match_host_pattern("example.com", "*.example.com")
False
>>> match_host_pattern("example.com", "example.com")
True
>>> match_host_pattern("api.example.com", "*")
True
localvectordb_server.utils.hostmatch.validate_host_against_patterns(host: str, trusted_patterns: List[str]) bool

Validate host against list of trusted patterns.

This is the main function to use for host validation. It handles port stripping, normalization, and pattern matching.

Parameters:
  • host (str) – Host string from request (may include port)

  • trusted_patterns (List[str]) – List of trusted host patterns

Returns:

True if host matches any trusted pattern

Return type:

bool

Examples

>>> patterns = ["localhost", "*.example.com", "api.mysite.org"]
>>> validate_host_against_patterns("localhost:5000", patterns)
True
>>> validate_host_against_patterns("api.example.com", patterns)
True
>>> validate_host_against_patterns("evil.com", patterns)
False
localvectordb_server.utils.hostmatch.validate_trusted_host_patterns(patterns: List[str]) List[str]

Validate and normalize a list of trusted host patterns.

Parameters:

patterns (List[str]) – List of host patterns to validate

Returns:

List of validation error messages (empty if all valid)

Return type:

List[str]

Examples

>>> validate_trusted_host_patterns(["localhost", "*.example.com"])
[]
>>> validate_trusted_host_patterns(["", "invalid..domain"])
['Empty pattern at index 0', 'Invalid pattern format: "invalid..domain"']