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:
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.
- localvectordb_server.utils.hostmatch.is_valid_hostname(hostname: str) bool
Check if hostname is valid format.
- 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:
- Returns:
True if hostname matches pattern
- Return type:
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:
- Returns:
True if host matches any trusted pattern
- Return type:
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"']