Skip to content

API lacks request body size limits; file uploads and JSON bodies are effectively unbounded (DoS risk) #45

Description

@hanul93

💡 Summary

Apply configurable request body size limits to the API. Enforce:

  • a global default via DefaultBodyLimit::max(...) driven by config, and
  • per-route limits: JSON routes use request_size_limits.json, file/multipart routes use request_size_limits.data (with data = 0 meaning “no limit”).

Motivation and context

  • Currently the API disables the global body limit, making JSON requests and file uploads effectively unbounded, which poses resource-exhaustion/DoS risks.
  • This gives operators explicit, environment-overridable control of request sizes, aligning with best practices and improving cluster resilience.

Implementation notes

  • Example configuration (YAML, MiB units):
thorium:
  request_size_limits:
    json: 16     # JSON body limit (MiB)
    data: 256    # File/multipart upload limit (MiB). 0 disables this limit.
  • Environment overrides (examples):
    • THORIUM__THORIUM__REQUEST_SIZE_LIMITS__JSON=16
    • THORIUM__THORIUM__REQUEST_SIZE_LIMITS__DATA=256
  • How it would look/act:
    • Replace global disable with a config-driven limit:
      // global default (data cap; 0 => disable)
      let data_mib = conf.thorium.request_size_limits.data;
      let data_bytes = (data_mib * 1024 * 1024) as usize;
      let body_limit_layer =
        if data_mib == 0 { DefaultBodyLimit::disable() } else { DefaultBodyLimit::max(data_bytes) };
      app = app.layer(body_limit_layer);
    • Apply a per-route limit for JSON-only routes:
      let json_mib = conf.thorium.request_size_limits.json;
      if json_mib > 0 {
        let json_bytes = (json_mib * 1024 * 1024) as usize;
        api_router = api_router.layer(RequestBodyLimitLayer::new(json_bytes));
      }
      // File/multipart routes are mounted separately and governed by `data`
    • Behavior:
      • Requests exceeding limits return 413 Payload Too Large.
      • JSON routes adhere to json; upload routes adhere to data.
      • data = 0 is an explicit opt-out (unlimited uploads).
  • Related work:
    • Enforcement lives in thorium/api/src/lib.rs (router construction).
    • Limits are sourced from thorium/api/src/conf.rs (request_size_limits).

Acceptance criteria

  • Requests exceeding configured limits return 413 Payload Too Large.
  • JSON routes respect thorium.request_size_limits.json.
  • File/multipart routes respect thorium.request_size_limits.data; data = 0 disables upload limits.
  • Limits are configurable via YAML and environment variables and are documented.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions