Skip to content

bug: gateway POST /api/ai/summarize has no request body size limit β€” a client can send a multi-MB text payload that the gateway forwards to the AI provider, causing slow responses and excessive token costsΒ #256

Description

@divyanshim27

πŸ› Problem Statement

The gateway (gateway/ Go/Gin) processes POST /api/ai/summarize requests and forwards the text field to OpenRouter or Ollama for summarization. The README documents per-request timeout middleware and rate limiting, but there is no documented maximum request body size limit on the summarize endpoint.

A client can send:

# Generate 500KB of text and send to summarize
python3 -c "print('x ' * 250000)" | \
  curl -X POST http://localhost:3000/api/ai/summarize \
    -H "Content-Type: application/json" \
    -H "X-402-Signature: ..." \
    -d "{\"text\": \"$(cat -)\"}"

This creates three problems:

  1. Token cost explosion: A 250,000-word text sent to OpenRouter's GPT-4 class models would cost ~$1.50+ per request at standard rates β€” far above the 0.001 USDC payment amount in the demo
  2. Timeout amplification: Even with the request timeout middleware, the gateway may spend the full timeout window on a single oversized request, degrading availability for all other users
  3. Memory pressure: The Go gateway buffers the JSON body before forwarding it; very large bodies can cause significant GC pressure

Fix Required

In gateway/ β€” add body size limiting middleware:

// gateway/internal/middleware/body_limit.go (or add to existing middleware chain)

package middleware

import (
    "net/http"
    "github.com/gin-gonic/gin"
)

const MaxSummarizeBodyBytes = 32 * 1024 // 32KB β€” reasonable max for a summarizable text

func BodySizeLimit(maxBytes int64) gin.HandlerFunc {
    return func(c *gin.Context) {
        c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, maxBytes)
        c.Next()
    }
}

Apply specifically to the summarize route with a configurable limit:

// In the router setup
summarize := r.Group("/api/ai")
summarize.Use(BodySizeLimit(MaxSummarizeBodyBytes))
summarize.POST("/summarize", handlers.Summarize)

Also add an input character count limit at the application layer (after JSON parsing):

// In the summarize handler
if len(req.Text) > 8000 {
    c.JSON(http.StatusRequestEntityTooLarge, gin.H{
        "error": "text_too_long",
        "message": fmt.Sprintf("Text must be %d characters or fewer.", 8000),
        "max_length": 8000,
    })
    return
}

Add the limit to the OpenAPI spec (gateway/openapi.yaml) and .env.example:
MAX_SUMMARIZE_TEXT_LENGTH=8000 # Characters. Adjust for your AI provider token budget.

Files to Modify

File Change
gateway/ (middleware or handler) Add body size limit middleware + text length validation
gateway/openapi.yaml Document text field max length
.env.example Add MAX_SUMMARIZE_TEXT_LENGTH
gateway/ (router setup) Apply body limit to summarize route

Suggested labels: bug, security, gateway, level: beginner

Metadata

Metadata

Assignees

Labels

documentationImprovements or additions to documentationgoPull requests that update go codetriageNeeds maintainer triage.type:docsDocumentation, API docs, examples, or contributor docs.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions