Skip to content

🐛 bug: reject malformed hostnames in hostauthorization wildcard path#4408

Open
gaby wants to merge 2 commits into
mainfrom
fix-wildcard-host-authorization-vulnerability
Open

🐛 bug: reject malformed hostnames in hostauthorization wildcard path#4408
gaby wants to merge 2 commits into
mainfrom
fix-wildcard-host-authorization-vulnerability

Conversation

@gaby
Copy link
Copy Markdown
Member

@gaby gaby commented Jun 6, 2026

Motivation

  • Prevent wildcard AllowedHosts from accepting malformed authority strings that can bypass subdomain checks (e.g. attacker.test/.example.com).
  • Ensure the host-authorization middleware enforces that a normalized authority is a syntactically valid IP or DNS name before exact/wildcard matching.
  • Keep wildcard semantics while closing an authz bypass introduced by raw strings.HasSuffix over insufficiently validated host input.

Description

  • Added isValidHostSyntax(host string) bool to middleware/hostauthorization/hostauthorization.go to validate normalized host syntax (accept IP literals or RFC-style DNS labels and reject delimiters/whitespace, empty labels, labels with leading/trailing hyphens, and oversize labels).
  • Call isValidHostSyntax from parseNormalizedAuthority to reject malformed hosts early before matchHost runs.
  • Added regression cases to Test_ParseNormalizedAuthority in middleware/hostauthorization/hostauthorization_test.go for inputs containing /, ?, and spaces to ensure these are rejected.

Testing

  • Ran make audit which executed but failed due to govulncheck reporting multiple Go stdlib vulnerabilities in the pinned toolchain (go1.25.1), causing a non-zero exit (scan output reported numerous standard-library issues). (failed)
  • Ran make generate; the generation step completed successfully. (passed)
  • Ran make betteralign; completed successfully. (passed)
  • Ran make modernize; failed in this environment because the modernize tool requires Go >= 1.26 while the CI/toolchain uses go1.25.1. (failed)
  • Ran make format; completed successfully. (passed)
  • Ran make lint; linter passed with 0 issues after a minor gocritic suggestion was addressed. (passed)
  • Ran make test; full test suite executed successfully (3417 tests, 2 skipped). (passed)

Codex Task

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 6, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 41c0cb33-4135-4659-b2d8-9564cbac5f51

📥 Commits

Reviewing files that changed from the base of the PR and between 6d4d2e1 and 588163f.

📒 Files selected for processing (2)
  • middleware/hostauthorization/hostauthorization.go
  • middleware/hostauthorization/hostauthorization_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • middleware/hostauthorization/hostauthorization_test.go
  • middleware/hostauthorization/hostauthorization.go

Walkthrough

A new isValidHostSyntax helper validates normalized hosts (rejecting empty, leading/trailing dots, invalid labels; accepting IP literals). parseNormalizedAuthority calls this validator before accepting a host. Tests now assert rejection for hosts containing '/', '?', or whitespace.

Changes

Host Syntax Validation

Layer / File(s) Summary
Host syntax validation and test coverage
middleware/hostauthorization/hostauthorization.go, middleware/hostauthorization/hostauthorization_test.go
isValidHostSyntax added to validate host syntax (accept IP literals via net.ParseIP; reject empty hosts and leading/trailing dots; enforce per-label rules: non-empty, within max label length, no leading/trailing -, ASCII letters/digits/hyphen). parseNormalizedAuthority now calls this validator and returns failure for invalid hosts. Three tests verify rejection of hosts with /, ?, and whitespace.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • gofiber/fiber#4293: Modifies hostauthorization host validation and test coverage for malformed authority inputs.
  • gofiber/fiber#4291: Adds early rejection of invalid/empty normalized host values in hostauthorization middleware.
  • gofiber/fiber#4307: Changes trailing-dot normalization in authority parsing which interacts with this PR's validation.

Suggested labels

📜 RFC Compliance

Suggested reviewers

  • sixcolors
  • ReneWerner87
  • efectn

Poem

🐰 I hopped the host-check garden gate,
Sniffed for dots and spaces late,
IPs are welcome, labels must behave,
No stray slashes, query marks to save —
A careful rabbit guards the Host name's fate.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main security fix: rejecting malformed hostnames in the hostauthorization wildcard functionality to prevent authorization bypass.
Description check ✅ Passed The description includes motivation, detailed technical changes, and comprehensive testing results, but lacks completed checklist items and explicit classification of change type.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-wildcard-host-authorization-vulnerability

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@ReneWerner87 ReneWerner87 added this to v3 Jun 6, 2026
@ReneWerner87 ReneWerner87 added this to the v3 milestone Jun 6, 2026
@gaby gaby removed the aardvark label Jun 6, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a host syntax validation helper isValidHostSyntax to the host authorization middleware to prevent invalid hosts (such as those containing path or query delimiters, or spaces) from being accepted, along with corresponding unit tests. A review comment suggests optimizing isValidHostSyntax to avoid heap allocations and iterator overhead on the hot path by validating the host in a single pass.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +186 to +217
func isValidHostSyntax(host string) bool {
if host == "" {
return false
}

// IPv4 / IPv6 literals.
if net.ParseIP(host) != nil {
return true
}

if strings.HasPrefix(host, ".") || strings.HasSuffix(host, ".") {
return false
}

for label := range strings.SplitSeq(host, ".") {
if label == "" || len(label) > maxLabelLength {
return false
}
if label[0] == '-' || label[len(label)-1] == '-' {
return false
}
for i := 0; i < len(label); i++ {
ch := label[i]
if (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '-' {
continue
}
return false
}
}

return true
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current implementation of isValidHostSyntax uses strings.SplitSeq to split the host into labels. Since this middleware runs on the hot path of every incoming HTTP request, avoiding heap allocations and iterator overhead is crucial for performance. We can validate the host syntax in a single pass with zero allocations by iterating over the string characters directly.

func isValidHostSyntax(host string) bool {
	if host == "" {
		return false
	}

	// IPv4 / IPv6 literals.
	if net.ParseIP(host) != nil {
		return true
	}

	if strings.HasPrefix(host, ".") || strings.HasSuffix(host, ".") {
		return false
	}

	labelLen := 0
	for i := 0; i < len(host); i++ {
		ch := host[i]
		if ch == '.' {
			if labelLen == 0 || labelLen > maxLabelLength {
				return false
			}
			if host[i-labelLen] == '-' || host[i-1] == '-' {
				return false
			}
			labelLen = 0
			continue
		}

		if (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '-' {
			labelLen++
			continue
		}
		return false
	}

	if labelLen == 0 || labelLen > maxLabelLength {
		return false
	}
	if host[len(host)-labelLen] == '-' || host[len(host)-1] == '-' {
		return false
	}

	return true
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants