# Max message payload size enforced server-side; oversized frames rejected with error

- **Pattern:** `ab-000744` (`community-realtime.message-delivery.max-payload-enforced`)
- **Severity:** medium
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000744
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000744)

## Why it matters

Without a server-side payload cap, any client can send multi-megabyte WebSocket frames. Processing an oversized frame allocates that memory per connection, and if multiple clients do this simultaneously, the server runs out of heap before the OS-level connection limit is reached. CWE-770 (Allocation of Resources Without Limits) and CWE-400 (Uncontrolled Resource Consumption) both apply. This is a trivial denial-of-service vector in community platforms where registration is open and any user can author a message.

## Severity rationale

Medium because oversized frames cause unbounded memory allocation per connection, enabling a low-effort denial-of-service by any authenticated user.

## Remediation

Enforce a payload size limit in the message handler before any processing occurs. Reject oversized frames with an error response and do not process their contents.

```ts
const MAX_PAYLOAD = 65_536; // 64 KB

socket.on('send_message', (data: unknown) => {
  const size = Buffer.byteLength(JSON.stringify(data));
  if (size > MAX_PAYLOAD) {
    socket.emit('error', { code: 413, message: `Payload too large: ${size} > ${MAX_PAYLOAD}` });
    return;
  }
  // proceed
});
```

Socket.IO also exposes a `maxHttpBufferSize` server option that enforces this at the transport layer — set it in the `Server` constructor as a belt-and-suspenders complement to the per-handler check.

## Detection

- **ID:** `max-payload-enforced`
- **Severity:** `medium`
- **What to look for:** Count all message validation paths. For each, check for payload size enforcement. Quote the actual limit value if found. Enumerate: frame size configuration, message size checks in handlers.
- **Pass criteria:** The server enforces a maximum message payload size of no more than 1048576 bytes (1MB). Oversized messages are rejected with an error response. At least 1 size enforcement mechanism must be present.
- **Fail criteria:** No payload size limit is enforced, or the limit exceeds 1MB.
- **Skip (N/A) when:** Never — payload size limits are essential for server stability.
- **Detail on fail:** `"No maximum payload size enforced. A client could send multi-MB messages, causing memory exhaustion."`
- **Remediation:** Enforce payload size limits:

  ```ts
  const MAX_PAYLOAD_SIZE = 65536; // 64KB

  socket.on('send_message', (data) => {
    const payloadSize = JSON.stringify(data).length;
    if (payloadSize > MAX_PAYLOAD_SIZE) {
      socket.emit('error', { message: `Payload too large (${payloadSize} > ${MAX_PAYLOAD_SIZE})` });
      return;
    }
    // Process message
  });
  ```

---

## External references

- cwe CWE-770
- cwe CWE-400

Taxons: cost-efficiency

HTML version: https://auditbuffet.com/patterns/ab-000744
