Fix XSS in API Responses in Meteor
Meteor's `WebApp.connectHandlers` allows developers to bypass the standard DDP framework to create custom REST endpoints. The danger lies in reflecting user input back in these responses without forcing a strict JSON MIME type. If the `Content-Type` header is missing or generic, browsers perform MIME-sniffing, potentially executing injected HTML/JavaScript payloads embedded in the API response.
The Vulnerable Pattern
import { WebApp } from 'meteor/webapp';// VULNERABLE: Reflecting URL parameters directly into the response body // without setting a secure Content-Type. WebApp.connectHandlers.use(‘/api/v1/status’, (req, res, next) => { const url = new URL(req.url,
http://${req.headers.host}); const userId = url.searchParams.get(‘id’);
// If id is ‘’, the browser may execute it. res.end({"status": "active", "user": "${userId}"}); });
The Secure Implementation
The exploit relies on the browser's willingness to interpret a raw string as HTML if it sees tags. By default, some middleware might not set a `Content-Type`, leading to 'Reflected XSS via API'. To remediate: First, use `JSON.stringify()` to ensure that any special characters in the user input are properly escaped within the JSON string. Second, explicitly set the `Content-Type` to `application/json`. Third, and most importantly, set the `X-Content-Type-Options: nosniff` header. This instructs the browser to strictly follow the provided MIME type, preventing it from executing the response as HTML even if it detects script tags.
import { WebApp } from 'meteor/webapp';// SECURE: Enforcing application/json and disabling MIME-sniffing. WebApp.connectHandlers.use(‘/api/v1/status’, (req, res, next) => { const url = new URL(req.url,
http://${req.headers.host}); const userId = url.searchParams.get(‘id’);const data = JSON.stringify({ status: ‘active’, user: userId });
// 1. Force JSON content type res.setHeader(‘Content-Type’, ‘application/json; charset=utf-8’); // 2. Prevent the browser from guessing the content type res.setHeader(‘X-Content-Type-Options’, ‘nosniff’);
res.writeHead(200); res.end(data); });
Your API Responses API
might be exposed to XSS
74% of API Responses apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.