Summary
The public QR code generation endpoint accepts arbitrary size values without enforcing any upper bound before generating raster images.
An unauthenticated attacker can supply extremely large dimensions and force excessive memory allocation or event-loop blocking during QR generation.
Affected File
apps/backend/src/routes/public.ts
Root Cause
The route currently parses the requested QR size directly from user input:
const size = parseInt((request.query as any).size || '400', 10);
and passes it directly into the QR generation flow:
const png = await generateQRBuffer(profileUrl, {
width: size
});
No maximum limit is enforced before passing the value into the QR rendering library.
Security Impact
An attacker can trigger extremely large image allocations using requests such as:
GET /api/u/testuser/qr?size=50000
Large raster generation can:
- exhaust server memory,
- block the Node.js event loop,
- trigger OOM crashes,
- severely degrade request throughput.
The endpoint:
- is public,
- requires no authentication,
- and currently has no rate limiting.
Reproduction
Send:
GET /api/u/testuser/qr?size=50000
Observe:
- excessive CPU usage,
- memory spikes,
- request stalls,
- or process instability depending on runtime limits.
Proposed Fix
Add strict upper-bound validation before QR generation.
Suggested approach:
const MAX_QR_SIZE = 2048;
Reject:
- negative sizes,
- zero,
- NaN values,
- and excessively large dimensions.
Return:
for invalid values.
Additional recommendation:
- apply IP-based rate limiting to public QR routes.
Acceptance Criteria
- QR size values are validated before image generation.
- Excessively large dimensions are rejected safely.
- Invalid numeric inputs return 400 responses.
- Legitimate QR generation behavior remains unchanged.
- Endpoint remains stable under malicious requests.
Severity
Medium
This creates an unauthenticated denial-of-service vector against a public endpoint.
Summary
The public QR code generation endpoint accepts arbitrary
sizevalues without enforcing any upper bound before generating raster images.An unauthenticated attacker can supply extremely large dimensions and force excessive memory allocation or event-loop blocking during QR generation.
Affected File
apps/backend/src/routes/public.tsRoot Cause
The route currently parses the requested QR size directly from user input:
and passes it directly into the QR generation flow:
No maximum limit is enforced before passing the value into the QR rendering library.
Security Impact
An attacker can trigger extremely large image allocations using requests such as:
Large raster generation can:
The endpoint:
Reproduction
Send:
Observe:
Proposed Fix
Add strict upper-bound validation before QR generation.
Suggested approach:
Reject:
Return:
for invalid values.
Additional recommendation:
Acceptance Criteria
Severity
Medium
This creates an unauthenticated denial-of-service vector against a public endpoint.