Skip to content

Security: No rate limiting, no JSON body size limit, unbounded query limit parameter #14

Description

@cuibonobo

Overview

The server has no defenses against denial-of-service via request flooding or oversized payloads.

1. No rate limiting on any endpoint (High)

Every route — including token lookup on each authenticated request, record queries, and write operations — is completely unmetered. This allows:

  • Brute-force attacks against Bearer tokens (the lookup hits the DB every request)
  • Query flooding that saturates the SQLite adapter
  • Write amplification via rapid POST /records calls

Fix: Add rate-limiting middleware. At minimum, apply a per-IP limit on all routes and a stricter limit on auth-sensitive paths. Hono has community rate-limiter middleware, or this can be handled at the reverse proxy layer (which should be documented as a deployment requirement).

2. No request body size limit on JSON routes (High)

Binary uploads check maxAttachmentBytes at src/routes/attachments.ts:15-22, but JSON write routes have no body size limit:

  • POST /records
  • POST /records/query
  • PATCH /records/:id
  • POST /records/:id/associations
  • DELETE /records/:id/associations
  • PUT /records/:id/permissions
  • POST /types
  • POST /tokens
  • PATCH /entity

A single multi-megabyte JSON payload can exhaust memory or cause the process to stall parsing.

Fix: Add Hono's bodyLimit middleware to all JSON routes, e.g.:

import { bodyLimit } from 'hono/body-limit';
app.use('/records/*', bodyLimit({ maxSize: 1 * 1024 * 1024 })); // 1 MB

3. Unbounded limit query parameter (High)

Location: src/routes/records.ts:139

query.limit = parseInt(limit, 10);

No upper bound is enforced. A caller can pass ?limit=9999999 and cause the stack to attempt loading and serializing an arbitrarily large result set into memory.

Fix: Cap the limit at a reasonable maximum before passing it to the stack:

const MAX_LIMIT = 1000;
query.limit = Math.min(parseInt(limit, 10) || MAX_LIMIT, MAX_LIMIT);

Metadata

Metadata

Assignees

No one assigned

    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