Skip to content

/calculate has no schema, size, or rate-limit validation #1470

@MaxGhenis

Description

@MaxGhenis

Summary

/calculate has no request-schema validation, no payload-size limits, and no rate limit. household["axes"] in particular is unbounded, so a caller can submit arbitrarily large axes arrays that force the country model to allocate enormous numpy grids and block a worker for minutes.

Location

policyengine_household_api/endpoints/household.py:20-22

payload = request.json
household_json = payload.get("household", {})
policy_json = payload.get("policy", {})

What goes wrong

  • No Pydantic (or equivalent) schema validates household, policy, or enable_ai_explainer.
  • axes in the household is passed directly into country.calculate; the country model then builds a cartesian grid across the specified axes. With no upper bound on axis count or per-axis count, a single request can trigger huge numpy allocations and long simulation runs.
  • No @limiter.limit(...) decorator is attached to /calculate (only /calculate_demo has one).

Suggested fix

  1. Add a Pydantic model for the request payload (CalculateRequest) and validate request.json against it before calling country.calculate. Reject payloads exceeding app.config["MAX_CONTENT_LENGTH"] or an explicit size budget.
  2. Constrain axes: max_length on the axes list, max on per-axis count, and possibly a cap on the product of axis counts.
  3. Apply a reasonable @limiter.limit("N per minute") decorator on /calculate (auth-tenant-aware key if possible).

Severity

Low/medium - DoS vector via unauthenticated-friendly payload shapes; belongs in a general-hardening pass.

Relates to

#1460 / #1461 (fail-closed auth)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    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