Security Fix: Preventing API Error Message Data Leakage (SCR-12)
Security Fix: Preventing API Error Message Data Leakage (SCR-12)
Version: 1.0.96 Control: SCR-12 Severity: Data Leak
Background
NurtureHub integrates with several external providers to deliver email campaigns and synchronise CRM data — including Resend, Gmail (via Google API), Microsoft Graph (for Outlook/Microsoft 365), and property CRM platforms such as agentOS, Reapit, Alto, Street, and Loop.
When these integrations encounter errors, they return HTTP responses that may contain detailed internal information: error codes specific to the provider's API, field-level validation messages, authentication failure details, or internal system identifiers.
The Problem
Prior to v1.0.96, the email dispatcher (src/lib/email/dispatcher.ts) constructed error messages by directly interpolating raw provider response bodies:
Resend API ${res.status}: ${text}
Gmail API ${res.status}: ${text}
Microsoft Graph API ${res.status}: ${text}
CRM adapters similarly included the full raw API response body inside CrmAdapterError message strings.
These error strings were not sanitised before they could propagate:
- Through Inngest step failures, appearing in job execution logs
- Into tRPC error responses, potentially reaching API consumers or client-side code
This meant that raw provider error text — which may reference internal API structure, reveal accepted field schemas, or expose authentication details — could be forwarded to callers without any filtering.
The Fix
From v1.0.96, error messages are sanitised at the point of construction before they can propagate outward.
What callers now receive
Normalised, generic error messages that convey only what is necessary:
Email delivery failed (provider error: 422)
The message includes:
- A human-readable description of the failure category
- The HTTP status code (sufficient for programmatic handling)
The message does not include:
- Raw response body text from the upstream provider
- Provider-specific error codes or internal identifiers
- Field-level validation detail from external APIs
What internal logs retain
Full error detail — including raw response bodies — continues to be written to server-side internal logs. No diagnostic information is lost for debugging and incident response purposes; it is simply no longer forwarded externally.
Impact on Integrations
| Provider | Previous error format | New error format |
|---|---|---|
| Resend | Resend API 422: <raw body> | Email delivery failed (provider error: 422) |
| Gmail | Gmail API 403: <raw body> | Email delivery failed (provider error: 403) |
| Microsoft Graph | Microsoft Graph API 401: <raw body> | Email delivery failed (provider error: 401) |
| CRM Adapters | CrmAdapterError: <full raw response> | Normalised category + status code |
What This Means for Developers
If your integration consumes tRPC error messages from email dispatch or CRM sync endpoints and parses provider-specific strings for error handling logic, those strings will no longer be present from v1.0.96 onwards.
Recommended approach: Handle errors based on HTTP status codes and normalised error categories rather than parsing raw provider message text. This is more resilient and consistent across all provider integrations.
Summary
This fix closes a data leakage path where internal API details from Resend, Microsoft Graph, Gmail, and property CRM providers could be exposed to callers through error message propagation. Full diagnostic detail is preserved in internal logs. No configuration or integration changes are required by users or agencies on the platform.