Skip to content

[CRITICAL] Fix: Add payload size limits and landmark validation to prevent unauthenticated resource exhaustion (#573)#574

Open
namann5 wants to merge 1 commit into
Somil450:mainfrom
namann5:fix/ws-payload-limits-resource-exhaustion
Open

[CRITICAL] Fix: Add payload size limits and landmark validation to prevent unauthenticated resource exhaustion (#573)#574
namann5 wants to merge 1 commit into
Somil450:mainfrom
namann5:fix/ws-payload-limits-resource-exhaustion

Conversation

@namann5
Copy link
Copy Markdown
Contributor

@namann5 namann5 commented May 29, 2026

📌 Related Issue

Fixes #573


📝 Description

This PR fixes a critical resource exhaustion vulnerability (CVSS 7.5) in the WebSocket frame handler. The server accepted unauthenticated connections with no upper bound on landmarks array size and no per-message size limit, allowing an attacker to exhaust server memory and disk space.

🔹 What has been changed?

  1. server/src/config/socket.js — Added \maxHttpBufferSize: 100000\ (~100 KB) to Socket.IO configuration to cap per-message payload size. Previously the Socket.IO default (1 MB) was used, enabling 60 MB/s throughput per connection.

  2. server/src/modules/pose/pose.validator.js

    • Added \LANDMARK_COUNT_MAX = 33\ (MediaPipe Pose uses exactly 33 landmarks). The validator previously only checked a minimum of 29 with no maximum, so attacker could send arrays with 100K+ elements.
    • Added \hasValidLandmarkObject()\ to validate each landmark has numeric \x\ and \y\ properties, preventing malformed NaN values from propagating to angle computation.
    • Updated \hasPoseLandmarks()\ to enforce both bounds and schema.
  3. Updated test — \pose.validator.test.js\ now tests upper bound (rejects 34), lower bound (rejects 28), landmark shape validation (rejects missing/non-numeric properties), and valid 29–33 range.

🔹 Why are these changes needed?

Without these limits:

  • Any unauthenticated client can connect (default \SOCKET_AUTH_TOKEN\ is empty)
  • Each connection can send 60 fps × 1 MB = 60 MB/s
  • With 10 concurrent connections/IP, an attacker can consume 600 MB/s bandwidth
  • Session buffer stores 300 frames × oversized payloads = up to 300 MB/connection
  • On \session:end, all oversized data is persisted to disk

🛠️ Type of Change

  • 🐛 Bug Fix (critical security vulnerability)

🧪 Testing

  • All 40 backend Vitest tests pass
  • Integration tests (socket flow, health, auth) pass
  • Validator correctly rejects: arrays >33 elements, arrays <29 elements, objects without numeric x/y

…a validation

Adds three security hardening measures for WebSocket payload limits:

1. maxHttpBufferSize: 100000 (~100 KB) in Socket.IO config to cap
   per-message size (prevents oversized frame payloads).

2. Landmarks array upper bound (LANDMARK_COUNT_MAX=33) in
   pose.validator.js to reject oversized arrays. Also adds
   hasValidLandmarkObject() to validate each landmark has
   numeric x/y properties, preventing malformed data from
   reaching angle computation and session storage.

3. Updated tests to reflect new validation requirements.

Fixes Somil450#573
@vercel
Copy link
Copy Markdown

vercel Bot commented May 29, 2026

@namann5 is attempting to deploy a commit to the somiljain2024-4175's projects Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[CRITICAL] Unauthenticated WebSocket resource exhaustion via missing payload limits in pose validator and Socket.IO config

1 participant