Skip to content

Conversation

sixcolors
Copy link
Member

@sixcolors sixcolors commented Sep 29, 2025

🐛 Bug Fix & Security Hardening

Fixes a panic in CopyContextToFiberContext when handling non-pointer context structs, adds comprehensive test coverage, and hardens the adaptor middleware against security vulnerabilities and performance issues.

📝 Changes

Bug Fixes

  • Fixed panic in CopyContextToFiberContext: Added proper handling for both pointer and non-pointer context types with minimal unsafe usage for unexported fields.
  • Added nil pointer checking: Prevents crashes when nil contexts are passed.
  • Improved type validation: Gracefully handles non-struct context types.

Security Hardening

  • Added body size limit: Enforces 10MB maximum request body size to prevent resource exhaustion (CWE-400, CVSS 3.1: 5.3).
  • Input validation in resolveRemoteAddr: Validates remote addresses to block malformed inputs and excessive lengths.
  • Safe reflection in context copying: Limits unsafe operations to necessary cases, reducing attack surface.

Performance Improvements

  • Bounded body copying: Limits memory usage in hot paths to 10MB, mitigating O(n) hotspots.
  • Maintained benchmarks: No degradation in existing performance tests.

Test Coverage Improvements

  • new comprehensive tests covering all error paths, edge cases, and security validations.
  • Unit tests for helper functions: resolveRemoteAddr, isUnixNetwork, body size limits.
  • Error handling tests: IO errors, invalid addresses, context conversion failures, oversized bodies.
  • Unix socket integration test: Full end-to-end Unix domain socket testing.
  • Benchmark tests: Performance validation for different payload sizes.
  • DRY improvements: Helper functions createTestRequest, executeHandlerTest for maintainable tests.

Test Functions Added

  • Test_ConvertRequest - Comprehensive conversion testing with error handling.
  • Test_CopyContextToFiberContext - Context copying with edge cases.
  • Test_HTTPMiddleware_ErrorHandling - Middleware error path testing.
  • Test_FiberHandler_IOError - IO failure scenarios.
  • Test_FiberHandler_WithErrorInHandler - Handler error propagation.
  • Test_resolveRemoteAddr - Address resolution unit tests with security validations.
  • Test_isUnixNetwork - Network type validation.
  • Test_FiberHandler_ErrorFallback - Invalid address fallback behavior.
  • Test_FiberHandler_WithUnixSocket - Unix socket context handling.
  • Test_FiberHandler_BodySizeLimit - Body size enforcement.
  • Test_CopyContextToFiberContext_Safe - Safe handling of unexported fields.
  • TestUnixSocketAdaptor - Full Unix socket integration test.
  • Comprehensive benchmarks for performance validation.

🧪 Testing

All tests pass and provide comprehensive coverage of:

  • ✅ Panic prevention in context copying.
  • ✅ Unix socket address resolution.
  • ✅ Error handling and fallback mechanisms.
  • ✅ Body size limits and resource protection.
  • ✅ Integration testing with real Unix sockets.
  • ✅ Performance benchmarking under various conditions.

📊 Coverage

This PR significantly improves test coverage and security for the adaptor middleware, ensuring robust handling of:

  • Context type validation and copying.
  • Unix socket network detection and address resolution.
  • Error scenarios, graceful fallbacks, and input sanitization.
  • Performance characteristics and resource limits.

…rehensive test coverage

- Fix panic when CopyContextToFiberContext receives non-pointer context structs
- Add proper nil pointer checking and type validation
- Add comprehensive test suite with 297+ lines covering all error paths
- Include unit tests for resolveRemoteAddr, isUnixNetwork helper functions
- Add Unix socket integration tests and error handling scenarios
- Improve test maintainability with DRY helper functions
- Add benchmarks for performance validation
@Copilot Copilot AI review requested due to automatic review settings September 29, 2025 14:55
@sixcolors sixcolors requested a review from a team as a code owner September 29, 2025 14:55
Copy link
Contributor

coderabbitai bot commented Sep 29, 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

CopyContextToFiberContext now safely handles pointers/nil and only processes structs; middleware enforces a 10MB request-body cap and tightens remote-address validation and error paths. Tests expanded to cover conversions, context copying, error flows, body limits, Unix sockets, and address resolution.

Changes

Cohort / File(s) Summary
Adaptor runtime
middleware/adaptor/adaptor.go
Changed CopyContextToFiberContext(src any, requestContext *fasthttp.RequestCtx) to handle pointer dereference, nil checks, and require struct kinds; avoid unsafe access for unsupported kinds; add 10MB request-body limit on net/http→fasthttp conversion; add input validation and explicit errors in resolveRemoteAddr.
Adaptor tests
middleware/adaptor/adaptor_test.go
Added parallelized tests (t.Parallel()), helpers (createTestRequest, executeHandlerTest, failingReader); expanded tests for ConvertRequest success/error, CopyContextToFiberContext edge cases (nil, pointers, non-addressable, unknown/unexported fields), IO/read errors, Fiber handler error paths, Unix-socket adaptor flows, remote-address parsing, and body-size limits.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Client
  participant NetHTTP as net/http Handler
  participant Adaptor as Middleware/Adaptor
  participant Resolver as resolveRemoteAddr
  participant Fiber as fasthttp Handler

  Client->>NetHTTP: send request (body)
  NetHTTP->>Adaptor: ConvertRequest
  Adaptor->>Adaptor: enforce 10MB body limit (return 413 if exceed)
  Adaptor->>Resolver: resolveRemoteAddr(remoteAddr)
  alt resolved
    Resolver-->>Adaptor: host:port
  else error (empty/long/invalid)
    Resolver-->>Adaptor: error
  end
  Adaptor->>Adaptor: CopyContextToFiberContext(src)
  note right of Adaptor #D3F6D9: CopyContextToFiberContext:\n- deref pointers\n- nil & kind checks\n- safe field handling
  Adaptor->>Fiber: forward converted request
  Fiber-->>Client: response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

☢️ Bug, v3

Suggested reviewers

  • gaby
  • ReneWerner87
  • efectn

Poem

I twitch my whiskers at pointer fright,
Hop-hop—nil shadows yield to light.
Ten megabytes I happily cap,
Ports and sockets get a careful tap.
I copy fields with gentle paws—hip hooray for passing laws!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.34% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title succinctly follows conventional commit style by specifying the component (“adaptor”) and clearly summarizing the two primary contributions—preventing a panic in CopyContextToFiberContext and adding comprehensive test coverage—without extraneous detail.
Description Check ✅ Passed The pull request description is clear, concise, and provides a thorough overview of the bug fix, security hardening, performance improvements, and test coverage enhancements, including specific sections for changes, testing, and coverage. It addresses the problem being solved, outlines the benefits, and lists new tests and benchmarks in detail. Though it diverges from the repository’s template by omitting a top-level “Description” heading, the “Fixes #” issue reference, explicit checkboxes for benchmarks, documentation updates, changelog entries, migration guide, API alignment, examples, and the “Type of change” and checklist sections, the core information is present and well organized.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/adaptor-context-panic-and-test-coverage

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.

Copy link
Contributor

Summary of Changes

Hello @sixcolors, 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 addresses a critical panic in the CopyContextToFiberContext function by implementing robust handling for various context types, including pointers, non-pointers, and nil values. Concurrently, it vastly improves the test suite for the adaptor middleware, adding extensive coverage for error conditions, Unix socket interactions, and performance, ensuring greater stability and reliability of the component.

Highlights

  • Context Copying Robustness: The CopyContextToFiberContext function has been made more robust by correctly handling both pointer and non-pointer context structs, preventing panics.
  • Nil Pointer Safety: Added explicit nil pointer checking within CopyContextToFiberContext to prevent crashes when nil contexts are inadvertently passed.
  • Improved Type Validation: Enhanced type validation in CopyContextToFiberContext to gracefully manage non-struct context types, ensuring the function returns early without error.
  • Comprehensive Test Coverage: Significantly expanded test coverage for the adaptor middleware, including new tests for error paths, edge cases, Unix socket integration, and performance benchmarks.
  • New Test Utilities: Introduced helper functions createTestRequest and executeHandlerTest to improve test maintainability and reduce redundancy.
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 by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

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 pull request 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 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 fixes a panic in CopyContextToFiberContext when handling non-pointer context structs and adds comprehensive test coverage for the adaptor middleware. The main issue was that the original code assumed contexts were always pointers, causing panics with non-pointer context types.

Key changes:

  • Fixed context type handling to support both pointer and non-pointer structs with nil checking
  • Added 297+ lines of comprehensive test coverage including error paths, edge cases, and Unix socket testing
  • Introduced helper functions for cleaner and more maintainable tests

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
middleware/adaptor/adaptor.go Fixed panic in CopyContextToFiberContext by adding proper pointer/non-pointer handling and nil checking
middleware/adaptor/adaptor_test.go Added comprehensive test suite with helper functions, error handling tests, Unix socket tests, and benchmarks

Copy link

codecov bot commented Sep 29, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.64%. Comparing base (e58fec7) to head (1848384).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3770      +/-   ##
==========================================
+ Coverage   91.54%   91.64%   +0.10%     
==========================================
  Files         113      113              
  Lines       11912    11937      +25     
==========================================
+ Hits        10905    10940      +35     
+ Misses        740      733       -7     
+ Partials      267      264       -3     
Flag Coverage Δ
unittests 91.64% <100.00%> (+0.10%) ⬆️

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.

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 effectively addresses a panic in CopyContextToFiberContext by correctly handling both pointer and non-pointer context types. The addition of comprehensive test coverage, including numerous edge cases and error scenarios, significantly improves the robustness and maintainability of the adaptor middleware. The changes are well-structured, and the new test helpers improve the test suite's clarity. I have one minor suggestion to simplify the reflection logic in CopyContextToFiberContext.

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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
middleware/adaptor/adaptor_test.go (1)

731-807: Refactor parallel benchmark to avoid shared bytes.Buffer data race
Shared bytes.Buffer is reused across goroutines, causing a data race and stale reader—allocate a fresh reader inside each pb.Next() iteration:

@@ Benchmark_FiberHandlerFunc_Parallel(b *testing.B) {
-           b.RunParallel(func(pb *testing.PB) {
-               w := httptest.NewRecorder()
-               r := http.Request{Method: http.MethodPost}
-               r.Body = io.NopCloser(bodyBuffer)
-               defer r.Body.Close() //nolint:errcheck
-               for pb.Next() {
-                   handlerFunc(w, &r)
-               }
-           })
+           b.RunParallel(func(pb *testing.PB) {
+               for pb.Next() {
+                   w := httptest.NewRecorder()
+                   r := http.Request{Method: http.MethodPost}
+                   if bm.bodyContent != nil {
+                       r.Body = io.NopCloser(bytes.NewReader(bm.bodyContent))
+                   } else {
+                       r.Body = http.NoBody
+                   }
+                   handlerFunc(w, &r)
+                   if r.Body != http.NoBody {
+                       _ = r.Body.Close()
+                   }
+               }
+           })
🧹 Nitpick comments (4)
middleware/adaptor/adaptor.go (1)

56-56: Avoid shadowing the context package in parameter names

Rename the first parameter to src or ctxAny for clarity and to prevent accidental confusion with the imported context package.

middleware/adaptor/adaptor_test.go (3)

493-537: Strengthen “no panic” assertion in conversion error test

Current logic only asserts if an error exists. Make the intent explicit by asserting non-panicking behavior and accepting either error/no-error.

-		_, err := ConvertRequest(ctx, true) // Use forServer=true which does more validation
-		if err == nil {
-			// If the above doesn't fail, try a different approach
-			ctx.Request().SetRequestURI("\x00\x01\x02") // Invalid characters in URI
-			_, err = ConvertRequest(ctx, true)
-		}
-		// Note: This test may pass if fasthttpadaptor is very permissive
-		// The important thing is that our function doesn't panic
-		if err != nil {
-			require.Error(t, err, "Expected error from fasthttpadaptor.ConvertRequest")
-		}
+		require.NotPanics(t, func() {
+			_, _ = ConvertRequest(ctx, true)
+			// If permissive, try a clearly invalid URI as a second attempt
+			ctx.Request().SetRequestURI("\x00\x01\x02")
+			_, _ = ConvertRequest(ctx, true)
+		})

539-567: Add a nil-pointer context case to validate new guard

Given the new nil checks in CopyContextToFiberContext, add an explicit nil-pointer test to lock in behavior.

 t.Run("unsupported context type", func(t *testing.T) {
@@
 })
 
 t.Run("context with unknown field", func(t *testing.T) {
@@
 })
+
+t.Run("nil pointer context", func(t *testing.T) {
+	t.Parallel()
+	var fctx fasthttp.RequestCtx
+	var ptr *struct{ key, val any } // nil
+	require.NotPanics(t, func() {
+		CopyContextToFiberContext(ptr, &fctx)
+	})
+})

656-729: Benchmark correctness: reuse of request/recorder skews results

  • Body is consumed on first iteration and reused thereafter.
  • Single httptest.NewRecorder() reused across iterations accumulates state.

Refactor to create a fresh request/recorder per iteration and reset the body.

-			w := httptest.NewRecorder()
-			var bodyBuffer *bytes.Buffer
-			// Handle the "No Content" case where bodyContent is nil
-			if bm.bodyContent != nil {
-				bodyBuffer = bytes.NewBuffer(bm.bodyContent)
-			} else {
-				bodyBuffer = bytes.NewBuffer([]byte{}) // Empty buffer for no content
-			}
-			r := http.Request{
-				Method: http.MethodPost,
-				Body:   nil,
-			}
-			// Replace the empty Body with our buffer
-			r.Body = io.NopCloser(bodyBuffer)
-			defer r.Body.Close() //nolint:errcheck // not needed
-			b.ReportAllocs()
-			for b.Loop() {
-				handlerFunc.ServeHTTP(w, &r)
-			}
+			b.ReportAllocs()
+			b.ResetTimer()
+			for b.Loop() {
+				w := httptest.NewRecorder()
+				var r http.Request
+				r.Method = http.MethodPost
+				if bm.bodyContent != nil {
+					r.Body = io.NopCloser(bytes.NewReader(bm.bodyContent))
+				} else {
+					r.Body = http.NoBody
+				}
+				handlerFunc.ServeHTTP(w, &r)
+				if r.Body != http.NoBody {
+					_ = r.Body.Close()
+				}
+			}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e58fec7 and aa21c3f.

📒 Files selected for processing (2)
  • middleware/adaptor/adaptor.go (1 hunks)
  • middleware/adaptor/adaptor_test.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/adaptor/adaptor.go
  • middleware/adaptor/adaptor_test.go
🧠 Learnings (3)
📓 Common learnings
Learnt from: gaby
PR: gofiber/fiber#3193
File: middleware/adaptor/adaptor.go:111-111
Timestamp: 2024-11-10T23:44:13.704Z
Learning: In the `middleware/adaptor/adaptor.go` file of the Fiber framework, when updating context handling, replacing `c.Context()` with `c.RequestCtx()` is appropriate to access the `fasthttp.RequestCtx`.
Learnt from: gaby
PR: gofiber/fiber#3193
File: middleware/cache/cache_test.go:897-897
Timestamp: 2024-11-08T04:10:42.990Z
Learning: In the Fiber framework, `Context()` is being renamed to `RequestCtx()`, and `UserContext()` to `Context()` to improve clarity and align with Go's context conventions.
📚 Learning: 2024-11-10T23:44:13.704Z
Learnt from: gaby
PR: gofiber/fiber#3193
File: middleware/adaptor/adaptor.go:111-111
Timestamp: 2024-11-10T23:44:13.704Z
Learning: In the `middleware/adaptor/adaptor.go` file of the Fiber framework, when updating context handling, replacing `c.Context()` with `c.RequestCtx()` is appropriate to access the `fasthttp.RequestCtx`.

Applied to files:

  • middleware/adaptor/adaptor.go
  • middleware/adaptor/adaptor_test.go
📚 Learning: 2024-11-08T04:10:42.990Z
Learnt from: gaby
PR: gofiber/fiber#3193
File: middleware/cache/cache_test.go:897-897
Timestamp: 2024-11-08T04:10:42.990Z
Learning: In the Fiber framework, `Context()` is being renamed to `RequestCtx()`, and `UserContext()` to `Context()` to improve clarity and align with Go's context conventions.

Applied to files:

  • middleware/adaptor/adaptor.go
🧬 Code graph analysis (1)
middleware/adaptor/adaptor_test.go (1)
middleware/adaptor/adaptor.go (4)
  • ConvertRequest (47-53)
  • CopyContextToFiberContext (56-104)
  • HTTPMiddleware (107-137)
  • FiberHandlerFunc (145-147)
⏰ 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). (5)
  • GitHub Check: unit (1.25.x, windows-latest)
  • GitHub Check: unit (1.25.x, macos-latest)
  • GitHub Check: unit (1.25.x, macos-13)
  • GitHub Check: repeated
  • GitHub Check: Compare
🔇 Additional comments (9)
middleware/adaptor/adaptor.go (1)

125-126: Nice: using RequestCtx() for adaptor interop

Using c.RequestCtx() here aligns with Fiber v3’s renaming (Context()RequestCtx(), UserContext()Context()), and matches prior guidance. Looks good.

Based on learnings

middleware/adaptor/adaptor_test.go (8)

437-454: Helpers look good

createTestRequest and executeHandlerTest reduce duplication and improve clarity. LGTM.


569-594: Middleware error propagation coverage looks solid

This verifies HTTP middleware interactions and Fiber error handler mapping correctly. LGTM.


595-621: Good IO error simulation

The failingReader path ensures io.Copy errors return 500 without panics. LGTM.


622-644: Good handler error coverage

Asserting the status from fiber.NewError is propagated as expected. LGTM.


838-899: Remote addr resolver cases are comprehensive

The tests cover unix sockets, missing ports, and invalid formats. Nicely done.


901-926: Unix network detection test is straightforward and clear

LGTM.


928-944: Good fallback assertion when addr resolution fails

Ensures handler still runs when resolveRemoteAddr returns error. LGTM.


946-974: Unix socket adaptor test is valuable

End-to-end check via real UDS, with timeouts and graceful shutdown. LGTM.

}

// CopyContextToFiberContext copies the values of context.Context to a fasthttp.RequestCtx.
// This function safely handles struct fields without using unsafe operations where possible.
Copy link
Member

@nickajacks1 nickajacks1 Sep 29, 2025

Choose a reason for hiding this comment

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

without using unsafe operations

and

This function uses reflection and unsafe pointers

This sounds contradictory, maybe should reword.

Copy link
Member Author

Choose a reason for hiding this comment

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

Better?

@sixcolors sixcolors changed the title or): prevent CopyContextToFiberContext panic and add comprehensive test coverage feat(adaptor): prevent CopyContextToFiberContext panic and add comprehensive test coverage Sep 29, 2025
@sixcolors sixcolors changed the title feat(adaptor): prevent CopyContextToFiberContext panic and add comprehensive test coverage fix(adaptor): prevent CopyContextToFiberContext panic and add comprehensive test coverage Sep 29, 2025
@gaby gaby added this to v3 Sep 30, 2025
@gaby gaby added this to the v3 milestone Sep 30, 2025
@gaby
Copy link
Member

gaby commented Sep 30, 2025

/gemini review

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 is an excellent pull request that significantly improves the adaptor middleware. The fix for the panic in CopyContextToFiberContext is robust and well-tested, handling various edge cases gracefully. The security hardening measures, such as adding a body size limit and validating remote addresses, are valuable additions. The test coverage is impressively comprehensive, covering new functionality, error paths, and edge cases, which greatly increases confidence in the changes.

I have one suggestion regarding the implementation of the request body size limit to further enhance security by preventing potential HTTP request smuggling vulnerabilities. Overall, this is a high-quality contribution.

@gaby gaby requested a review from nickajacks1 September 30, 2025 01:08
@sixcolors
Copy link
Member Author

@gemini-code-assist what is your suggestion egarding the implementation of the request body size limit to further enhance security by preventing potential HTTP request smuggling vulnerabilities?

Copy link
Contributor

Hello @sixcolors,

That's an excellent question, and it highlights a critical aspect of web security. The current implementation of the request body size limit in handlerFunc (lines 202-209 in middleware/adaptor/adaptor.go) already provides a significant layer of defense against HTTP request smuggling vulnerabilities, primarily through:

  1. Explicit Content-Length check: By immediately returning 413 Request Entity Too Large if r.ContentLength exceeds maxBodySize, it prevents a class of smuggling attacks that rely on oversized Content-Length headers to hide subsequent requests.
  2. io.LimitReader: This is a robust mitigation. Even if r.ContentLength is absent or manipulated, io.LimitReader ensures that the fasthttp request body writer will only consume up to maxBodySize bytes from the net/http.Request's body. This prevents the backend from inadvertently reading past the intended end of the first request, which could expose the beginning of a smuggled request.

To further enhance security by preventing potential HTTP request smuggling vulnerabilities, beyond just mitigating their impact, my suggestion would be to add an explicit check for ambiguous message length headers within the handlerFunc.

HTTP request smuggling often arises from discrepancies in how different components (e.g., a frontend proxy and the backend application server) interpret HTTP message length headers, specifically Content-Length and Transfer-Encoding. While Go's net/http server is generally robust in its parsing, an explicit check within the adaptor can add an extra layer of defense against potential misconfigurations or edge cases.

Specific Suggestion:

Consider adding a check to explicitly reject requests that contain both a Content-Length header and a Transfer-Encoding header, especially if Transfer-Encoding is chunked. According to RFC 7230, Transfer-Encoding should take precedence. However, if an upstream proxy or load balancer incorrectly prioritizes Content-Length, it can lead to smuggling.

Here's a conceptual example of how this could be implemented in handlerFunc (around line 201, before body processing):

		// ... existing code ...

		// Convert net/http -> fasthttp request with size limit
		const maxBodySize = 10 * 1024 * 1024 // 10MB limit

		// --- BEGIN SUGGESTION FOR FURTHER SMUGGLING PREVENTION ---
		transferEncoding := r.Header.Get("Transfer-Encoding")
		if transferEncoding != "" {
			// If Transfer-Encoding is present, it should ideally be the only message length indicator.
			// If Content-Length is also present and not -1 (meaning net/http didn't ignore it due to TE),
			// this could indicate an ambiguous situation exploitable by request smuggling.
			if r.ContentLength != -1 {
				http.Error(w, "Ambiguous Content-Length and Transfer-Encoding headers detected. Rejecting to prevent HTTP request smuggling.", http.StatusBadRequest)
				return
			}
			// Further check: if Transfer-Encoding is present but not "chunked", it might be malformed or unexpected.
			// The net/http server usually handles this, but an explicit check adds robustness.
			if strings.ToLower(transferEncoding) != "chunked" {
				http.Error(w, "Unsupported or malformed Transfer-Encoding header. Rejecting to prevent HTTP request smuggling.", http.StatusBadRequest)
				return
			}
		}
		// --- END SUGGESTION ---

		if r.Body != nil {
			// ... existing body size limit and copy logic ...

Rationale for this check:

  • Proactive Prevention: Instead of just limiting the read, this explicitly rejects requests that present an ambiguous interpretation challenge to the HTTP parsing stack.
  • Defense in Depth: While net/http is generally secure, adding this check provides an additional layer of defense, especially if the application is deployed behind various proxies or load balancers that might have different parsing behaviors.
  • Clear Error Signaling: Immediately rejecting such requests with a 400 Bad Request status clearly signals an issue with the request's framing.

It's also crucial to ensure that all components in your application's request path (load balancers, proxies, and the application server itself) are configured to parse HTTP headers, particularly Content-Length and Transfer-Encoding, in a consistent and RFC-compliant manner. This holistic approach is key to effectively preventing HTTP request smuggling.

@gaby
Copy link
Member

gaby commented Sep 30, 2025

@sixcolors llm making stuff up 😂

@ReneWerner87 ReneWerner87 merged commit b25339d into main Sep 30, 2025
15 checks passed
@github-project-automation github-project-automation bot moved this to Done in v3 Sep 30, 2025
@ReneWerner87 ReneWerner87 deleted the fix/adaptor-context-panic-and-test-coverage branch September 30, 2025 08:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

4 participants