GuardAPI Logo
GuardAPI

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); });

System Alert • ID: 5013
Target: API Responses API
Potential Vulnerability

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.

RUN FREE SECURITY DIAGNOSTIC
GuardLabs Engine: ONLINE

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.