Skip to content

🧹 chore: Improve BasicAuth middleware RFC compliance#3743

Merged
ReneWerner87 merged 6 commits intomainfrom
review-basicauth-middleware-for-rfc-compliance-qtl6hw
Sep 18, 2025
Merged

🧹 chore: Improve BasicAuth middleware RFC compliance#3743
ReneWerner87 merged 6 commits intomainfrom
review-basicauth-middleware-for-rfc-compliance-qtl6hw

Conversation

@gaby
Copy link
Member

@gaby gaby commented Sep 13, 2025

Summary

  • enforce space-only separation in Authorization header and reject any whitespace within credentials
  • restrict BasicAuth charset to canonical UTF-8 value and validate decoded credentials for control characters
  • add regression test covering credential tokens containing spaces
  • handle optional whitespace around the Basic scheme, allowing multiple spaces while rejecting tabs or spaces inside credentials

Copilot AI review requested due to automatic review settings September 13, 2025 01:37
@gaby gaby requested a review from a team as a code owner September 13, 2025 01:37
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 13, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Reworks BasicAuth to strictly parse/validate Authorization headers (length limit, invalid chars, exact "Basic " scheme), distinguish 400/401/431 error paths, accept unpadded Base64, require UTF-8 (canonicalized), NFC-normalize credentials, add a configurable BadRequest handler, and expand docs/tests.

Changes

Cohort / File(s) Summary
Middleware: parsing & validation
middleware/basicauth/basicauth.go
Enforces header presence & length limit (431), rejects invalid header/control chars, requires "Basic " with single space, disallows internal spaces in payload, decodes Base64 (Std → RawStd fallback to accept unpadded), validates UTF-8 and applies NFC normalization, requires colon in credentials, rejects CTL chars in username/password, calls Authorizer on valid creds, returns 400 for malformed inputs and 401 for auth failures; adds helpers containsCTL and containsInvalidHeaderChars.
Config: public API & defaults
middleware/basicauth/config.go
Adds public BadRequest fiber.Handler to Config and sets default handler (400) when nil; enforces UTF-8-only Charset (canonicalizes to "UTF-8", panics on other non-empty values); updates ConfigDefault to include BadRequest: nil.
Tests: expanded coverage
middleware/basicauth/basicauth_test.go
Adds extensive edge-case tests: header whitespace and control-char handling, invalid/Non-ASCII UTF-8, UTF-8 normalization (NFC), unpadded Base64 acceptance, missing colon, oversized header (431), charset panic behavior, and expectations for 400 vs 401 outcomes; refactors whitespace tests to table-driven form.
Docs: middleware behavior & API
docs/middleware/basicauth.md
Documents distinct error codes (400/401/431), UTF-8-only charset requirement and canonicalization, support for optional Base64 padding omission, and new BadRequest config field and default behavior.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant C as Client
  participant S as Server (Fiber)
  participant BA as BasicAuth Middleware
  participant H as Authorizer

  C->>S: HTTP request with Authorization header
  S->>BA: Invoke middleware
  rect rgb(245,250,255)
    BA->>BA: Check header presence & length
    alt Missing header
      BA-->>C: 401 Unauthorized + WWW-Authenticate
    else Header too large
      BA-->>C: 431 Request Header Fields Too Large
    else Validate scheme & chars (Basic + single space)
      alt Malformed (invalid chars/CTLs/format/Base64/UTF‑8/no colon)
        BA-->>C: 400 Bad Request (cfg.BadRequest or default)
      else Decode Base64 (Std → RawStd fallback) & NFC normalize
        BA->>H: Call Authorizer(username, password)
        alt Authorized
          BA->>S: Next()
          S-->>C: Handler response
        else Unauthorized
          BA-->>C: 401 Unauthorized + WWW-Authenticate
        end
      end
    end
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • sixcolors
  • efectn
  • ReneWerner87

Poem

I nibble headers, tidy bytes with care,
I normalize accents floating in the air.
A 400 nibble here, a 431 hop—
I guard the creds till the checks all stop. 🥕🐇

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The PR description gives a clear, concise summary of the functional changes (Authorization header separation, charset restriction, and added tests) but does not follow the repository's required template: it omits the "Fixes #" field, the "Changes introduced" section with detailed entries (docs, changelog, migration guide, benchmarks), the "Type of change" selection, and the completed checklist items. Because the repository expects the template to be filled for review and release planning, the current description is incomplete for maintainers to verify documentation, migration, and testing coverage. Please update the description to match the template and include links to any changed docs or issues. Update the PR description to follow the provided template: add "Fixes #" if applicable, populate the "Changes introduced" section with explicit entries and links to updated docs/changelog/migration notes, mark the appropriate "Type of change", and complete the checklist items (tests, docs, benchmarks, dependency rationale) so reviewers can confirm coverage and release impact before final review.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title Check ✅ Passed Title "🧹 chore: Improve BasicAuth middleware RFC compliance" succinctly captures the primary intent of the changes—bringing BasicAuth behavior into closer RFC alignment—and directly maps to the header parsing, charset, and error-handling updates described in the changeset. It is concise and clearly related to the main change, making it easy for reviewers to understand the PR purpose at a glance. The emoji and "chore" prefix are minor noise but do not make the title misleading.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch review-basicauth-middleware-for-rfc-compliance-qtl6hw

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.

@gaby gaby changed the title fix: differentiate bad Authorization headers and charset handling 🧹 chore: Improve BasicAuth middleware RFC compliance Sep 13, 2025
Copy link
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.

Summary of Changes

Hello @gaby, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the robustness and security of the BasicAuth middleware by implementing stricter validation for the 'Authorization' header and its contents. It introduces more granular error handling for malformed requests, ensuring that only properly formatted and encoded credentials are processed. These changes aim to prevent potential vulnerabilities arising from ambiguous or non-standard header formats and improve the overall reliability of authentication.

Highlights

  • Stricter Authorization Header Parsing: The BasicAuth middleware now enforces space-only separation between the 'Basic' scheme and credentials, rejecting any whitespace within the credentials themselves. This improves adherence to RFC standards and security.
  • Enhanced Credential Validation: Decoded BasicAuth credentials are now validated for canonical UTF-8 encoding and checked for control characters. Any invalid characters or non-UTF-8 content will result in a '400 Bad Request' response.
  • Specific Error Responses: The middleware now differentiates between various types of malformed 'Authorization' headers, returning '400 Bad Request' for syntax errors or invalid content, and '431 Request Header Fields Too Large' for headers exceeding the configured limit, instead of a generic '401 Unauthorized'.
  • Charset Enforcement: The Charset configuration for BasicAuth is now strictly enforced to 'UTF-8'. Configuring any other charset will cause the application to panic, ensuring consistent and secure credential interpretation.
  • Updated Go Dependencies: Several Go dependencies, including golang.org/x/crypto, golang.org/x/net, golang.org/x/sys, and golang.org/x/text, have been updated to their latest versions.
  • New BadRequest Handler: A new BadRequest handler option has been added to the BasicAuth configuration, allowing custom responses for requests with malformed 'Authorization' headers.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR enhances the BasicAuth middleware to enforce stricter validation of Authorization headers and improve charset handling for security and RFC compliance.

  • Adds comprehensive header validation to reject malformed Authorization headers with appropriate 400 Bad Request responses
  • Restricts charset configuration to only allow UTF-8 and adds Unicode normalization support
  • Implements extensive test coverage for edge cases including control characters, whitespace handling, and invalid encodings

Reviewed Changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
middleware/basicauth/config.go Adds BadRequest handler config and enforces UTF-8-only charset with validation
middleware/basicauth/basicauth.go Implements strict Authorization header parsing with control character detection and Unicode normalization
middleware/basicauth/basicauth_test.go Adds comprehensive test coverage for malformed headers, charset validation, and edge cases
go.mod Updates golang.org/x dependencies to newer versions
docs/middleware/basicauth.md Updates documentation to reflect new validation behavior and UTF-8 charset restriction

Copy link
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 significantly improves the BasicAuth middleware by enhancing its RFC compliance and security. The changes introduce stricter validation for the Authorization header, such as enforcing space-only separation, rejecting whitespace within credentials, and validating for control characters. The middleware now also correctly handles different response statuses like 400 Bad Request and 431 Request Header Fields Too Large. Support for unpadded Base64 credentials and UTF-8 normalization are excellent additions. The test suite has been substantially expanded to cover these new features and edge cases, which is great to see. The documentation and configuration have also been updated accordingly. Overall, this is a high-quality contribution that makes the middleware more robust and secure.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (10)
docs/middleware/basicauth.md (4)

7-10: Tighten wording on whitespace semantics (SP-only between scheme and token).

To prevent ambiguity: explicitly say that only SP (0x20) may separate "Basic" and the token; leading/trailing SP/HTAB are trimmed; any HTAB or SP inside the token is rejected.

Apply this doc tweak:

-Basic Authentication middleware for [Fiber](https://github.com/gofiber/fiber) that provides HTTP basic auth. It calls the next handler for valid credentials and returns [`401 Unauthorized`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401) for missing or invalid credentials, [`400 Bad Request`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400) for malformed `Authorization` headers, or [`431 Request Header Fields Too Large`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/431) when the header exceeds size limits. Credentials may omit Base64 padding as permitted by RFC 7235's `token68` syntax.
+Basic Authentication middleware for [Fiber](https://github.com/gofiber/fiber) that provides HTTP basic auth. It calls the next handler for valid credentials and returns [`401 Unauthorized`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401) for missing or invalid credentials, [`400 Bad Request`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400) for malformed `Authorization` headers, or [`431 Request Header Fields Too Large`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/431) when the header exceeds size limits. Only SP (0x20) may separate the `Basic` scheme and token (one or more SPs allowed); leading/trailing SP/HTAB are ignored; any whitespace inside the token is rejected. Credentials may omit Base64 padding as permitted by RFC 7235 `token68`.

9-9: Clarify panic timing for invalid charset.

Note it panics during middleware setup (New/configDefault), not at request time.

-Only the `UTF-8` charset is supported; any other value will panic.
+Only the `UTF-8` charset is supported; any other value will panic during middleware initialization.

101-106: Disambiguate “case-insensitive” to exclude utf8 (no hyphen).

Readers may assume utf8 is allowed. The code only accepts UTF-8 (case-insensitive, hyphen required).

-| Charset         | `string`                    | Charset sent in the `WWW-Authenticate` header. Only `"UTF-8"` is supported (case-insensitive). | `"UTF-8"` |
+| Charset         | `string`                    | Charset sent in the `WWW-Authenticate` header. Only `"UTF-8"` is supported (case-insensitive; `"utf8"` without hyphen is not allowed). | `"UTF-8"` |

109-120: Mention default BadRequest behavior explicitly.

You list BadRequest: nil in the example, but the runtime default returns bare 400 without WWW-Authenticate. Spell that out for users.

 var ConfigDefault = Config{
@@
-    BadRequest:      nil,
+    BadRequest:      nil, // when nil, the middleware responds with 400 without WWW-Authenticate
 }
middleware/basicauth/config.go (2)

107-113: Charset enforcement is correct; consider explicitly rejecting utf8 in docs, not code.

Code canonically accepts only UTF-8 (case-insensitive) and panics otherwise—good. No change needed here; just ensure docs call out that utf8 (no hyphen) is invalid (see docs comment).


131-141: Micro: precompute the WWW-Authenticate header string once.

Avoids rebuilding the header on every 401 while keeping behavior identical.

-	if cfg.Unauthorized == nil {
-		cfg.Unauthorized = func(c fiber.Ctx) error {
-			header := "Basic realm=" + strconv.Quote(cfg.Realm)
-			if cfg.Charset != "" {
-				header += ", charset=" + strconv.Quote(cfg.Charset)
-			}
-			c.Set(fiber.HeaderWWWAuthenticate, header)
+	if cfg.Unauthorized == nil {
+		header := "Basic realm=" + strconv.Quote(cfg.Realm)
+		if cfg.Charset != "" {
+			header += ", charset=" + strconv.Quote(cfg.Charset)
+		}
+		cfg.Unauthorized = func(c fiber.Ctx) error {
+			c.Set(fiber.HeaderWWWAuthenticate, header)
 			c.Set(fiber.HeaderCacheControl, "no-store")
 			c.Set(fiber.HeaderVary, fiber.HeaderAuthorization)
 			return c.SendStatus(fiber.StatusUnauthorized)
 		}
 	}
middleware/basicauth/basicauth.go (1)

95-100: Tiny simplification: use strings.Cut for the colon split.

Same behavior, slightly clearer.

-	index := strings.Index(creds, ":")
-	if index == -1 {
+	if index := strings.Index(creds, ":"); index == -1 {
 		return cfg.BadRequest(c)
-	}
-
-	// Get the username and password
-	username := creds[:index]
-	password := creds[index+1:]
+	} else {
+		// Get the username and password
+		username := creds[:index]
+		password := creds[index+1:]
+		// existing CTL check + authorizer continue below...
+		_ = username
+		_ = password
+	}

(Alternatively: u, p, ok := strings.Cut(creds, ":").)

middleware/basicauth/basicauth_test.go (3)

227-259: Whitespace matrix is comprehensive.

Nice coverage of SP vs HTAB and internal-space rejection.

Add a case with leading/trailing HTAB only (no SP) to assert trimming still succeeds:

{"\tBasic " + creds + "\t", fiber.StatusTeapot},

(You already have it; consider also "Basic "+creds+"\t\t".)


396-402: Charset panic tests are good; consider adding utf8 (no hyphen) as a negative.

 require.Panics(t, func() { New(Config{Charset: "ISO-8859-1"}) })
+require.Panics(t, func() { New(Config{Charset: "utf8"}) }) // no hyphen should panic
 require.NotPanics(t, func() { New(Config{Charset: "utf-8"}) })
 require.NotPanics(t, func() { New(Config{Charset: "UTF-8"}) })
 require.NotPanics(t, func() { New(Config{}) })

227-259: Add a test for custom BadRequest handler.

To lock in the no-challenge behavior and allow custom body/status, add a small test where BadRequest writes a body or different status.

app := fiber.New()
app.Use(New(Config{
  Users: map[string]string{"john": sha256Hash("doe")},
  BadRequest: func(c fiber.Ctx) error {
    c.Set("X-Bad", "1")
    return c.Status(fiber.StatusBadRequest).SendString("bad auth")
  },
}))
// send malformed header and assert status/body/header and no WWW-Authenticate.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ba701cd and f2a6390.

⛔ Files ignored due to path filters (2)
  • go.mod is excluded by !**/*.mod
  • go.sum is excluded by !**/*.sum, !**/*.sum
📒 Files selected for processing (4)
  • docs/middleware/basicauth.md (3 hunks)
  • middleware/basicauth/basicauth.go (4 hunks)
  • middleware/basicauth/basicauth_test.go (6 hunks)
  • middleware/basicauth/config.go (5 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: Format Go code using gofumpt (enforced via make format)
Ensure code passes golangci-lint checks (enforced via make lint)
Optimize struct field alignment using betteralign (enforced via make betteralign)
Modernize Go code using gopls modernize (enforced via make modernize)

Files:

  • middleware/basicauth/config.go
  • middleware/basicauth/basicauth.go
  • middleware/basicauth/basicauth_test.go
docs/**

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Review and update the contents of the docs folder if necessary when modifying code

Files:

  • docs/middleware/basicauth.md
🧠 Learnings (3)
📚 Learning: 2024-10-02T23:03:31.727Z
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/store.go:164-167
Timestamp: 2024-10-02T23:03:31.727Z
Learning: Unit tests in this project use testify require.

Applied to files:

  • middleware/basicauth/basicauth_test.go
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
PR: gofiber/fiber#2922
File: middleware/cors/utils.go:63-71
Timestamp: 2024-10-08T19:06:06.583Z
Learning: The project uses the testify/assert package for assertions in unit tests.

Applied to files:

  • middleware/basicauth/basicauth_test.go
📚 Learning: 2024-11-15T07:56:21.623Z
Learnt from: ReneWerner87
PR: gofiber/fiber#3161
File: app.go:923-932
Timestamp: 2024-11-15T07:56:21.623Z
Learning: In the Fiber framework, breaking changes are acceptable when moving from version 2 to version 3, including modifications to method signatures such as in the `Test` method in `app.go`.

Applied to files:

  • middleware/basicauth/basicauth_test.go
🧬 Code graph analysis (3)
middleware/basicauth/config.go (3)
app.go (1)
  • Handler (40-40)
ctx_interface_gen.go (1)
  • Ctx (18-430)
constants.go (1)
  • StatusBadRequest (73-73)
middleware/basicauth/basicauth.go (1)
constants.go (2)
  • HeaderAuthorization (163-163)
  • StatusRequestHeaderFieldsTooLarge (100-100)
middleware/basicauth/basicauth_test.go (3)
middleware/basicauth/basicauth.go (1)
  • New (26-118)
middleware/basicauth/config.go (1)
  • Config (19-73)
constants.go (6)
  • StatusUnauthorized (74-74)
  • HeaderWWWAuthenticate (166-166)
  • StatusBadRequest (73-73)
  • HeaderAuthorization (163-163)
  • StatusTeapot (91-91)
  • StatusRequestHeaderFieldsTooLarge (100-100)
🔇 Additional comments (24)
middleware/basicauth/config.go (2)

46-51: Good addition: dedicated BadRequest handler (400) without WWW-Authenticate.

This cleanly separates malformed headers from auth failures and avoids misleading challenges.


151-191: Password hash parsing/verifiers look solid.

Covers bcrypt, {SHA512}, {SHA256}, and raw SHA-256 (hex/base64) with constant-time compares. Nice.

middleware/basicauth/basicauth.go (4)

38-69: Header validation and SP-only separation are correctly enforced.

ASCII-only header check, trimming outer SP/HTAB, scheme match, and SP-only separation after Basic all look correct and align with tests/docs.


71-79: Base64 fallback to RawStdEncoding is appropriate.

Covers token68 unpadded credentials; invalid inputs route to 400 via BadRequest.


80-85: UTF-8 validation and NFC normalization are well-chosen.

Ensures credentials are valid and normalized before processing.


106-109: CTL filter is correct (blocks C0/C1 controls).

Prevents embedded control chars in decoded credentials and avoids invoking the authorizer on malformed data.

middleware/basicauth/basicauth_test.go (18)

150-161: UTF-8 header canonicalization test is on point.


174-176: Correct to expect 400 for non-base64 token.


178-193: 401 for missing Basic scheme plus challenge header—good coverage.


194-208: 400 on missing colon is correct and prevents authorizer invocation.


261-289: CTLs in decoded creds correctly yield 400 and skip authorizer.


291-307: Unpadded Base64 acceptance test—great.


308-323: Non-ASCII in header value returns 400 without challenge—good negative path.


324-344: Invalid UTF-8 rejection test ensures authorizer is not called.


345-369: NFC normalization test is excellent.


370-393: CR/LF edge cases: good defensive tests.


404-431: HeaderLimit tests properly exercise 431 vs allowed path.


545-572: Hash variant acceptance test suite is solid.

Covers bcrypt, SHA-512, and SHA-256 encodings.


574-602: Negative hash-variant tests look good.


111-135: AuthorizerCtx test validates context propagation—nice.


210-225: Empty Authorization cases yield 401—good baseline.


495-512: Immutable mode coverage is appreciated.


433-462: Benchmarks retained—no concerns.


464-493: Upper-case scheme benchmark retained—LGTM.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (2)
middleware/basicauth/basicauth.go (2)

59-59: Past nit addressed: replaced manual loop with TrimLeft.

You adopted TrimLeft for skipping spaces after the scheme, which improves readability.


118-122: Past nit addressed and a tiny micro-optimization idea.

You extracted a named helper (nice). If you want, scan bytes to avoid rune decoding, since non-ASCII is rejected anyway.

-func containsInvalidHeaderChars(s string) bool {
-  return strings.IndexFunc(s, func(r rune) bool {
-    return (r < 0x20 && r != '\t') || r == 0x7F || r >= 0x80
-  }) != -1
-}
+func containsInvalidHeaderChars(s string) bool {
+  for i := 0; i < len(s); i++ {
+    b := s[i]
+    if (b < 0x20 && b != '\t') || b == 0x7F || b >= 0x80 {
+      return true
+    }
+  }
+  return false
+}
🧹 Nitpick comments (4)
middleware/basicauth/basicauth.go (4)

65-73: Minor: pick encoding once to avoid a second decode attempt.

You can choose RawStdEncoding upfront when no '=' padding is present to skip the initial failing decode.

Apply:

- raw, err := base64.StdEncoding.DecodeString(rest)
- if err != nil {
-   if _, ok := err.(base64.CorruptInputError); ok {
-     raw, err = base64.RawStdEncoding.DecodeString(rest)
-   }
-   if err != nil {
-     return cfg.BadRequest(c)
-   }
- }
+ enc := base64.StdEncoding
+ if !strings.ContainsRune(rest, '=') {
+   enc = base64.RawStdEncoding
+ }
+ raw, err := enc.DecodeString(rest)
+ if err != nil {
+   return cfg.BadRequest(c)
+ }

83-87: Optional: avoid UnsafeString to reduce secret lifetime coupling.

Using UnsafeString ties the password string to the mutable backing array. Prefer an explicit copy and wipe the byte slice afterward for a modest hardening, at the cost of one alloc.

- if c.App().Config().Immutable {
-   creds = string(raw)
- } else {
-   creds = utils.UnsafeString(raw)
- }
+ creds = string(raw) // copy
+ for i := range raw { // best-effort wipe
+   raw[i] = 0
+ }

If perf is critical, keep current behavior but add a short comment documenting the trade-off.


91-99: Use strings.Cut for first-colon split.

Improves clarity and avoids manual index handling.

- index := strings.Index(creds, ":")
- if index == -1 {
-   return cfg.BadRequest(c)
- }
- // Get the username and password
- username := creds[:index]
- password := creds[index+1:]
+ username, password, ok := strings.Cut(creds, ":")
+ if !ok {
+   return cfg.BadRequest(c)
+ }

100-103: Consider rejecting Unicode format controls (Cf) too.

You currently block Cc controls. Adding Cf (e.g., bidi markers, zero-width) reduces spoofing risk in credentials.

-func containsCTL(s string) bool {
-  return strings.IndexFunc(s, unicode.IsControl) != -1
-}
+func containsCTL(s string) bool {
+  return strings.IndexFunc(s, func(r rune) bool {
+    return unicode.IsControl(r) || unicode.Is(unicode.Cf, r)
+  }) != -1
+}

And keep the existing call sites.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f2a6390 and 55aa60e.

⛔ Files ignored due to path filters (1)
  • .github/workflows/benchmark.yml is excluded by !**/*.yml
📒 Files selected for processing (1)
  • middleware/basicauth/basicauth.go (4 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: Format Go code using gofumpt (enforced via make format)
Ensure code passes golangci-lint checks (enforced via make lint)
Optimize struct field alignment using betteralign (enforced via make betteralign)
Modernize Go code using gopls modernize (enforced via make modernize)

Files:

  • middleware/basicauth/basicauth.go
🧬 Code graph analysis (1)
middleware/basicauth/basicauth.go (1)
constants.go (2)
  • HeaderAuthorization (163-163)
  • StatusRequestHeaderFieldsTooLarge (100-100)
🔇 Additional comments (4)
middleware/basicauth/basicauth.go (4)

38-44: Good: Early presence/size gating with correct 431 response.

Missing header → 401 and oversize header → 431 is a solid split and matches the intent of rejecting malformed/abusive inputs early.


45-62: Spec-aligned SP-only separation; tabs and internal WSP correctly rejected.

The sequence (trim OWS, require at least one SP after “Basic”, TrimLeft spaces, then forbid any SP/HTAB in the token) matches RFC 9110/7617 expectations. Nice.


74-79: Good: UTF-8 validation and NFC normalization.

Validating UTF-8 and normalizing to NFC before splitting credentials is the right call to prevent confusables and decoding surprises.


37-62: BadRequest defaulted in configDefault — no action needed.

middleware/basicauth/config.go sets cfg.BadRequest to return StatusBadRequest when nil (middleware/basicauth/config.go:143–145), so the BadRequest calls are safe.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (2)
middleware/basicauth/basicauth.go (2)

114-116: Resolved prior suggestion: concise control-char check.

Using strings.IndexFunc with unicode.IsControl addresses earlier feedback to streamline this check.


118-122: Resolved prior suggestion: header-char validation extracted.

Encapsulating invalid header rune filtering into containsInvalidHeaderChars improves readability and reuse.

🧹 Nitpick comments (5)
middleware/basicauth/basicauth.go (3)

55-62: Clarify and align whitespace policy after the scheme (exactly one space vs. multiple).

Code enforces exactly one space; tests mirror that, but PR objectives say “allow multiple spaces.” Please confirm intent. If multiple spaces should be allowed, consider:

-	rest := auth[len(basicScheme):]
-	if len(rest) < 2 || rest[0] != ' ' || rest[1] == ' ' {
-		return cfg.BadRequest(c)
-	}
-	rest = rest[1:]
-	if strings.IndexFunc(rest, unicode.IsSpace) != -1 {
-		return cfg.BadRequest(c)
-	}
+	rest := auth[len(basicScheme):]
+	orig := rest
+	rest = strings.TrimLeft(rest, " ")
+	if len(rest) == len(orig) || rest == "" { // require at least one space, then payload
+		return cfg.BadRequest(c)
+	}
+	// no whitespace inside token68
+	if strings.ContainsAny(rest, " \t") {
+		return cfg.BadRequest(c)
+	}

60-62: Nit: prefer ASCII check for payload whitespace.

Since non-ASCII was already rejected, unicode.IsSpace is heavier than needed. Use strings.ContainsAny(rest, " \t").

-	if strings.IndexFunc(rest, unicode.IsSpace) != -1 {
+	if strings.ContainsAny(rest, " \t") {
 		return cfg.BadRequest(c)
 	}

100-103: Consider whether to also reject Unicode “format” characters (Cf) in creds.

unicode.IsControl covers Cc; if you want to prevent invisible format characters (e.g., ZWJ) in usernames/passwords, extend the predicate.

-	if containsCTL(username) || containsCTL(password) {
+	if containsCTLOrFormat(username) || containsCTLOrFormat(password) {
 		return cfg.BadRequest(c)
 	}

Additional helper (outside this hunk):

func containsCTLOrFormat(s string) bool {
	return strings.IndexFunc(s, func(r rune) bool { return unicode.IsControl(r) || unicode.In(r, unicode.Format) }) != -1
}
middleware/basicauth/basicauth_test.go (2)

237-260: Augment whitespace table for coverage (leading multiples and case-insensitive scheme).

Add a few benign-accept cases to cement intent and guard regressions.

  cases := []struct {
  	header string
  	status int
  }{
  	{"Basic " + creds, fiber.StatusTeapot},
  	{" Basic " + creds, fiber.StatusTeapot},
+  {"   Basic " + creds, fiber.StatusTeapot},    // multiple leading spaces
+  {"\t  Basic " + creds, fiber.StatusTeapot},   // mixed leading ws
+  {"basic " + creds, fiber.StatusTeapot},       // scheme case-insensitive
  	{"Basic  " + creds, fiber.StatusBadRequest},
  	{"Basic   " + creds, fiber.StatusBadRequest},
  	{"Basic\t" + creds, fiber.StatusBadRequest},
  	{"Basic \t" + creds, fiber.StatusBadRequest},
  	{"Basic\u00A0" + creds, fiber.StatusBadRequest},
  	{"Basic\u3000" + creds, fiber.StatusBadRequest},
  	{"\tBasic " + creds + "\t", fiber.StatusTeapot},
  	{"Basic " + creds[:4] + " " + creds[4:], fiber.StatusBadRequest},
  }

405-433: Add exact-boundary case for HeaderLimit.

Minor: include a test where header length equals the limit to document inclusivity.

 t.Run("allowed", func(t *testing.T) {
   t.Parallel()
   app := fiber.New()
-  app.Use(New(Config{Users: map[string]string{"john": hashedJohn}, HeaderLimit: 100}))
+  // exact boundary
+  limit := len("Basic ") + len(creds)
+  app.Use(New(Config{Users: map[string]string{"john": hashedJohn}, HeaderLimit: limit}))
   app.Get("/", func(c fiber.Ctx) error { return c.SendStatus(fiber.StatusTeapot) })
   req := httptest.NewRequest(fiber.MethodGet, "/", nil)
   req.Header.Set(fiber.HeaderAuthorization, "Basic "+creds)
   resp, err := app.Test(req)
   require.NoError(t, err)
   require.Equal(t, fiber.StatusTeapot, resp.StatusCode)
 })
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 55aa60e and 2013baf.

📒 Files selected for processing (2)
  • middleware/basicauth/basicauth.go (4 hunks)
  • middleware/basicauth/basicauth_test.go (6 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: Format Go code using gofumpt (enforced via make format)
Ensure code passes golangci-lint checks (enforced via make lint)
Optimize struct field alignment using betteralign (enforced via make betteralign)
Modernize Go code using gopls modernize (enforced via make modernize)

Files:

  • middleware/basicauth/basicauth_test.go
  • middleware/basicauth/basicauth.go
🧠 Learnings (3)
📚 Learning: 2024-10-02T23:03:31.727Z
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/store.go:164-167
Timestamp: 2024-10-02T23:03:31.727Z
Learning: Unit tests in this project use testify require.

Applied to files:

  • middleware/basicauth/basicauth_test.go
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
PR: gofiber/fiber#2922
File: middleware/cors/utils.go:63-71
Timestamp: 2024-10-08T19:06:06.583Z
Learning: The project uses the testify/assert package for assertions in unit tests.

Applied to files:

  • middleware/basicauth/basicauth_test.go
📚 Learning: 2024-11-15T07:56:21.623Z
Learnt from: ReneWerner87
PR: gofiber/fiber#3161
File: app.go:923-932
Timestamp: 2024-11-15T07:56:21.623Z
Learning: In the Fiber framework, breaking changes are acceptable when moving from version 2 to version 3, including modifications to method signatures such as in the `Test` method in `app.go`.

Applied to files:

  • middleware/basicauth/basicauth_test.go
🧬 Code graph analysis (2)
middleware/basicauth/basicauth_test.go (3)
middleware/basicauth/basicauth.go (1)
  • New (26-112)
middleware/basicauth/config.go (1)
  • Config (19-73)
constants.go (6)
  • StatusUnauthorized (74-74)
  • HeaderWWWAuthenticate (166-166)
  • StatusBadRequest (73-73)
  • HeaderAuthorization (163-163)
  • StatusTeapot (91-91)
  • StatusRequestHeaderFieldsTooLarge (100-100)
middleware/basicauth/basicauth.go (1)
constants.go (2)
  • HeaderAuthorization (163-163)
  • StatusRequestHeaderFieldsTooLarge (100-100)
🔇 Additional comments (13)
middleware/basicauth/basicauth.go (2)

42-44: Good: header length guard mapped to 431.

Early limit check with StatusRequestHeaderFieldsTooLarge is correct and RFC-aligned.


65-79: Good: robust Base64 handling + UTF-8 validation + NFC normalization.

Fallback to RawStdEncoding, explicit BadRequest on decode failure, UTF-8 check, and NFC normalization look solid.

middleware/basicauth/basicauth_test.go (11)

150-161: LGTM: canonicalize charset in WWW-Authenticate.

Verifies canonical “UTF-8” even when config is “utf-8”.


174-176: LGTM: malformed token yields 400.

Matches middleware’s BadRequest path for decode failures.


178-192: LGTM: wrong scheme → 401 with challenge.

Confirms presence of WWW-Authenticate on 401.


194-208: LGTM: missing colon → 400 and no authorizer call.

Tracks malformed creds distinctly from auth failures.


262-290: LGTM: control chars → 400, no challenge, no authorizer.

Clear separation of malformed vs. unauthorized flows.


292-307: LGTM: unpadded Base64 accepted.

Covers token68 padding variations.


309-323: LGTM: non-ASCII in header value → 400.

Matches header ASCII-only policy.


325-344: LGTM: invalid UTF-8 in creds → 400 and authorizer not invoked.

Prevents downstream confusion with invalid text.


346-369: LGTM: NFC normalization path verified.

Ensures authorizer receives normalized username/password.


371-395: LGTM: CR/LF edges produce 400.

Good low-level coverage with fasthttp handler.


397-404: LGTM: charset guardrails.

Panics on non-UTF-8; accepts canonical and lowercased UTF-8; default OK.

@ReneWerner87 ReneWerner87 added this to v3 Sep 16, 2025
@ReneWerner87 ReneWerner87 added this to the v3 milestone Sep 16, 2025
@codecov
Copy link

codecov bot commented Sep 16, 2025

Codecov Report

❌ Patch coverage is 98.18182% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 92.06%. Comparing base (7265515) to head (6ddba6e).
⚠️ Report is 179 commits behind head on main.

Files with missing lines Patch % Lines
middleware/basicauth/basicauth.go 97.77% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3743      +/-   ##
==========================================
- Coverage   92.08%   92.06%   -0.02%     
==========================================
  Files         115      114       -1     
  Lines       11771    11799      +28     
==========================================
+ Hits        10839    10863      +24     
- Misses        675      678       +3     
- Partials      257      258       +1     
Flag Coverage Δ
unittests 92.06% <98.18%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ReneWerner87
Copy link
Member

ReneWerner87 commented Sep 16, 2025

@gaby
image
linting

  Error: middleware/basicauth/basicauth.go:67:16: type assertion on error will fail on wrapped errors. Use errors.As to check for specific errors (errorlint)
  			if _, ok := err.(base64.CorruptInputError); ok {
  			            ^
  Error: middleware/basicauth/basicauth_test.go:267:20: unused-parameter: parameter 'u' seems to be unused, consider removing or renaming it as _ (revive)
  		Authorizer: func(u, p string, _ fiber.Ctx) bool {
  		                 ^
  Error: middleware/basicauth/basicauth_test.go:331:20: unused-parameter: parameter 'u' seems to be unused, consider removing or renaming it as _ (revive)
  		Authorizer: func(u, p string, _ fiber.Ctx) bool {
  		                 ^
  Error: middleware/basicauth/config.go:107:2: ifElseChain: rewrite if-else to switch statement (gocritic)
  	if cfg.Charset == "" {
  	^

@gaby
Copy link
Member Author

gaby commented Sep 18, 2025

Fixing lint issues

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
middleware/basicauth/basicauth_test.go (3)

227-261: Whitespace matrix is thorough; add 1 trailing-space case?

Optional: add {"Basic " + creds + " ", fiber.StatusTeapot} to cover right-trim behavior for a plain space (you already cover tabs).


262-290: Fix unused parameter in Authorizer (revive).

Rename p to _ to satisfy lint without changing behavior.

Apply this diff:

-    Authorizer: func(_, p string, _ fiber.Ctx) bool {
+    Authorizer: func(_, _ string, _ fiber.Ctx) bool {
       called = true
       return true
     },

325-345: Fix unused parameter in Authorizer (revive).

Same lint as above; rename p to _.

Apply this diff:

-    Authorizer: func(_, p string, _ fiber.Ctx) bool {
+    Authorizer: func(_, _ string, _ fiber.Ctx) bool {
       called = true
       return true
     },
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2013baf and e231250.

📒 Files selected for processing (3)
  • middleware/basicauth/basicauth.go (5 hunks)
  • middleware/basicauth/basicauth_test.go (6 hunks)
  • middleware/basicauth/config.go (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • middleware/basicauth/config.go
  • middleware/basicauth/basicauth.go
🧰 Additional context used
📓 Path-based instructions (1)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: Format Go code using gofumpt (enforced via make format)
Ensure code passes golangci-lint checks (enforced via make lint)
Optimize struct field alignment using betteralign (enforced via make betteralign)
Modernize Go code using gopls modernize (enforced via make modernize)

Files:

  • middleware/basicauth/basicauth_test.go
🧠 Learnings (3)
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/store.go:164-167
Timestamp: 2024-10-08T19:06:06.583Z
Learning: Unit tests in this project use testify require.

Applied to files:

  • middleware/basicauth/basicauth_test.go
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
PR: gofiber/fiber#2922
File: middleware/cors/utils.go:63-71
Timestamp: 2024-10-08T19:06:06.583Z
Learning: The project uses the testify/assert package for assertions in unit tests.

Applied to files:

  • middleware/basicauth/basicauth_test.go
📚 Learning: 2024-11-15T07:56:21.623Z
Learnt from: ReneWerner87
PR: gofiber/fiber#3161
File: app.go:923-932
Timestamp: 2024-11-15T07:56:21.623Z
Learning: In the Fiber framework, breaking changes are acceptable when moving from version 2 to version 3, including modifications to method signatures such as in the `Test` method in `app.go`.

Applied to files:

  • middleware/basicauth/basicauth_test.go
🧬 Code graph analysis (1)
middleware/basicauth/basicauth_test.go (3)
middleware/basicauth/basicauth.go (1)
  • New (27-115)
middleware/basicauth/config.go (1)
  • Config (19-73)
constants.go (6)
  • StatusUnauthorized (74-74)
  • HeaderWWWAuthenticate (166-166)
  • StatusBadRequest (73-73)
  • HeaderAuthorization (163-163)
  • StatusTeapot (91-91)
  • StatusRequestHeaderFieldsTooLarge (100-100)
🪛 GitHub Check: lint
middleware/basicauth/basicauth_test.go

[failure] 331-331:
unused-parameter: parameter 'p' seems to be unused, consider removing or renaming it as _ (revive)


[failure] 267-267:
unused-parameter: parameter 'p' seems to be unused, consider removing or renaming it as _ (revive)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: repeated
  • GitHub Check: lint
  • GitHub Check: unit (1.25.x, windows-latest)
  • GitHub Check: Compare
🔇 Additional comments (11)
middleware/basicauth/basicauth_test.go (11)

11-11: Import addition looks good.

"strings" is used for unpadded Base64 trimming; import grouping/order is fine.


150-161: Good validation of charset canonicalization in WWW-Authenticate.

Ensures "utf-8" config yields uppercase "UTF-8" in header.


174-176: Correctly classifies invalid base64 as 400 Bad Request.

Matches stricter header parsing behavior.


178-193: Missing scheme path tested well.

401 with proper WWW-Authenticate header is correct.


194-208: No-colon credentials → 400 is correct.

Covers malformed "username:password" shape.


292-308: Accepting unpadded Base64 covered nicely.

Good use of TrimRight("=") to simulate missing padding.


309-323: Non-ASCII in header value correctly yields 400.

Direct fasthttp path ensures header-char validation is exercised.


346-369: Great UTF-8 NFC normalization test.

Confirms normalized username is passed to Authorizer.


371-395: CR/LF around header properly rejected.

Good low-level coverage using RequestCtx.


397-404: Charset config guardrails are well tested.

Panic on non-UTF-8 and acceptance of UTF-8/default look correct.


418-418: 431 expectation for over-limit header is correct.

Matches HeaderLimit enforcement.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (7)
middleware/basicauth/basicauth_test.go (7)

174-176: Also assert no WWW-Authenticate header on 400.

Strengthen the BadRequest contract.

Apply:

   require.NoError(t, err)
   require.Equal(t, fiber.StatusBadRequest, resp.StatusCode)
+  require.Empty(t, resp.Header.Get(fiber.HeaderWWWAuthenticate))

194-208: Add header absence check for malformed credentials.

Ensure 400 responses don’t include WWW-Authenticate.

Apply:

   require.NoError(t, err)
   require.Equal(t, fiber.StatusBadRequest, resp.StatusCode)
+  require.Empty(t, resp.Header.Get(fiber.HeaderWWWAuthenticate))

227-260: Name subcases for easier debugging; add trailing-whitespace cases.

Current table is good; subtests will pinpoint failures and a couple more cases close gaps.

Apply:

- for _, tt := range cases {
+ for i, tt := range cases {
+   t.Run(fmt.Sprintf("case_%d", i), func(t *testing.T) {
      req := httptest.NewRequest(fiber.MethodGet, "/", nil)
      req.Header.Set(fiber.HeaderAuthorization, tt.header)
      resp, err := app.Test(req)
      require.NoError(t, err)
      require.Equal(t, tt.status, resp.StatusCode)
- }
+   })
+ }

And extend the cases:

   cases := []struct {
     header string
     status int
   }{
     {"Basic " + creds, fiber.StatusTeapot},
     {" Basic " + creds, fiber.StatusTeapot},
+    {"Basic " + creds + " ", fiber.StatusTeapot},
+    {"Basic " + creds + "\t", fiber.StatusTeapot},
     {"Basic  " + creds, fiber.StatusBadRequest},

309-324: Non‑ASCII bytes in header should also assert no challenge.

Mirror the 400-no-header contract.

Apply:

 handler(fctx)
 require.Equal(t, fiber.StatusBadRequest, fctx.Response.StatusCode())
+require.Empty(t, string(fctx.Response.Header.Peek(fiber.HeaderWWWAuthenticate)))

325-345: Invalid UTF‑8 test: add absence of challenge header.

Small assertion to lock in behavior.

Apply:

 require.NoError(t, err)
 require.Equal(t, fiber.StatusBadRequest, resp.StatusCode)
 require.False(t, called)
+require.Empty(t, resp.Header.Get(fiber.HeaderWWWAuthenticate))

346-369: Normalization path looks right.

Optional: also assert UsernameFromContext(c) is the normalized form to exercise locals-setting.

If desired, change the route:

- app.Get("/", func(c fiber.Ctx) error { return c.SendStatus(fiber.StatusTeapot) })
+ app.Get("/", func(c fiber.Ctx) error { return c.SendString(UsernameFromContext(c)) })

And assert:

 require.NoError(t, err)
- require.Equal(t, fiber.StatusTeapot, resp.StatusCode)
+ require.Equal(t, fiber.StatusOK, resp.StatusCode)
+ body, _ := io.ReadAll(resp.Body)
+ require.Equal(t, "é", string(body))
 require.True(t, called)

371-395: Header CR/LF edges: also assert no challenge.

Keeps 400 semantics consistent.

Apply inside the loop:

 handler(fctx)
 require.Equal(t, fiber.StatusBadRequest, fctx.Response.StatusCode())
+require.Empty(t, string(fctx.Response.Header.Peek(fiber.HeaderWWWAuthenticate)))
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e231250 and 6ddba6e.

📒 Files selected for processing (1)
  • middleware/basicauth/basicauth_test.go (6 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: Format Go code using gofumpt (enforced via make format)
Ensure code passes golangci-lint checks (enforced via make lint)
Optimize struct field alignment using betteralign (enforced via make betteralign)
Modernize Go code using gopls modernize (enforced via make modernize)

Files:

  • middleware/basicauth/basicauth_test.go
🧠 Learnings (3)
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/store.go:164-167
Timestamp: 2024-10-08T19:06:06.583Z
Learning: Unit tests in this project use testify require.

Applied to files:

  • middleware/basicauth/basicauth_test.go
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
PR: gofiber/fiber#2922
File: middleware/cors/utils.go:63-71
Timestamp: 2024-10-08T19:06:06.583Z
Learning: The project uses the testify/assert package for assertions in unit tests.

Applied to files:

  • middleware/basicauth/basicauth_test.go
📚 Learning: 2024-11-15T07:56:21.623Z
Learnt from: ReneWerner87
PR: gofiber/fiber#3161
File: app.go:923-932
Timestamp: 2024-11-15T07:56:21.623Z
Learning: In the Fiber framework, breaking changes are acceptable when moving from version 2 to version 3, including modifications to method signatures such as in the `Test` method in `app.go`.

Applied to files:

  • middleware/basicauth/basicauth_test.go
🧬 Code graph analysis (1)
middleware/basicauth/basicauth_test.go (3)
middleware/basicauth/basicauth.go (1)
  • New (27-115)
middleware/basicauth/config.go (1)
  • Config (19-73)
constants.go (6)
  • StatusUnauthorized (74-74)
  • HeaderWWWAuthenticate (166-166)
  • StatusBadRequest (73-73)
  • HeaderAuthorization (163-163)
  • StatusTeapot (91-91)
  • StatusRequestHeaderFieldsTooLarge (100-100)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Compare
  • GitHub Check: unit (1.25.x, macos-latest)
  • GitHub Check: unit (1.25.x, windows-latest)
  • GitHub Check: repeated
🔇 Additional comments (7)
middleware/basicauth/basicauth_test.go (7)

11-11: Import of strings is correct and necessary.

Used in the unpadded Base64 test; no lint issues.


150-161: Canonicalize charset to UTF-8 — good coverage.

Confirms header normalization when config sets "utf-8".


178-193: Missing scheme path looks correct.

401 with proper WWW-Authenticate header is asserted.


262-290: Control character rejection and authorizer short‑circuit — solid.

Covers ASCII CTLs and C1 bytes; verifies no WWW-Authenticate and no authorizer call.


292-308: Unpadded Base64 acceptance — good regression coverage.

Exercise fallback to RawStdEncoding.


397-404: Charset tests vs docs — confirm intended casing behavior.

Tests allow "utf-8" (case-insensitive). Ensure config.go/docs state that casing is ignored and header is emitted as "UTF-8".


418-418: 431 on header size limit — correct expectation.

Matches new limit check path.

@ReneWerner87 ReneWerner87 merged commit b176062 into main Sep 18, 2025
15 checks passed
@ReneWerner87 ReneWerner87 deleted the review-basicauth-middleware-for-rfc-compliance-qtl6hw branch September 18, 2025 12:02
@github-project-automation github-project-automation bot moved this to Done in v3 Sep 18, 2025
Abhirup-99 pushed a commit to Abhirup-99/fiber that referenced this pull request Nov 3, 2025
@gaby gaby added the 📜 RFC Compliance Feature, implementation, or contribution adheres to relevant RFC standards. label Nov 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

☢️ Bug codex 📜 RFC Compliance Feature, implementation, or contribution adheres to relevant RFC standards. v3

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants