Credentials and integrations
Treat third-party API data as untrusted
Validate upstream responses, constrain redirects and destinations, set timeouts and size limits, and avoid inheriting a provider’s compromise.
A trusted provider can fail, change, or become compromised. Its response still crosses a trust boundary. TLS authenticates the connection, not the schema or business meaning of its response.
Validate the response like user input
Validate response status, content type, schema, size, and meaning. A tax provider may return HTML during an outage or redirect to a private address after compromise:
const res = await fetch('https://tax-api.example.net/v2/rates?country=IT', {
redirect: 'error', // an unexpected redirect is a failure
signal: AbortSignal.timeout(3000),
})
if (!res.ok) throw new Error(`tax api returned ${res.status}`)
const contentType = res.headers.get('content-type') ?? ''
if (!contentType.includes('application/json')) {
throw new Error('tax api returned non-JSON') // the outage-page case
}
Then parse the body into a bounded schema, exactly as you would a client request. A tax rate of -2 or 9999 should fail validation, not flow into invoice totals because “the provider is trusted”.
Cap the size before reading everything into memory:
const length = res.headers.get('content-length')
if (length && Number(length) > 100_000) {
throw new Error('tax api response too large')
}
For chunked responses without a length header, enforce the same cap while streaming.
Keep upstream text out of interpreters
Do not pass upstream text into SQL, HTML, shell commands, or AI tools without the same controls as user input. A provider’s “company name” field rendered unescaped into your dashboard is stored XSS with an extra hop. Parameterize and escape regardless of origin — a paid API contract changes nothing about the bytes.
Bound the failure, not just the request
Set short timeouts and bounded retries. Bound retries as well as individual requests: five automatic retries can multiply an outage into resource exhaustion, while a controlled fallback keeps the failure visible to operators.
The realistic failure mode is quiet. The provider starts responding slowly, your retries stack up, and your own API exhausts its worker pool serving requests that were never going to succeed.
Stub normal, oversized, slow, redirected, malformed, and hostile provider responses. Record the timeout and size evidence, then prove no bad response reaches storage, HTML, SQL, or shell execution.
Lesson completed