← Back to API Security for AI-Assisted Development
API10:20234 min read read

Unsafe Consumption of APIs

Validate third-party API responses instead of trusting external data that flows into your application.

URL: trusteed.io/academy/api-security/unsafe-consumption-of-apis

Unsafe Consumption of APIs occurs when an application trusts data or behavior from third-party and partner APIs without applying the same validation, sanitization, and security scrutiny it applies to input from its own users — treating "it came from an API we integrate with" as equivalent to "it's safe," when it should be treated as untrusted input like any other.

What Is Unsafe Consumption of APIs?

Modern applications are built on chains of third-party integrations — payment processors, mapping services, weather data, social login providers, AI/LLM APIs, and countless SaaS webhooks. Developers routinely apply rigorous input validation to data coming directly from their own users, while implicitly trusting data returned by these third parties: parsing a partner API's JSON response directly into a database without schema validation, rendering a third-party API's text field into HTML without sanitization, following redirects from an external API without limit, or disabling TLS certificate verification "temporarily" to work around an integration issue and never re-enabling it.

The category also covers weaker security practices specifically at integration boundaries — using outdated or unencrypted protocols for a "trusted" partner connection, or skipping authentication/authorization checks on webhook receivers because "only our partner calls this."

Why AI Coding Assistants Get This Wrong

Integration code is often generated to match a third-party API's own documentation examples, which frequently show the simplest possible happy-path usage — parse the response, use the fields, move on — without demonstrating validation, because the documentation's purpose is showing the integration works, not modeling a threat scenario where the third party's response is malformed, unexpectedly large, or (in the case of a compromised or spoofed integration) actively malicious. Assistants asked to "integrate with this API" will typically mirror that same trust level.

Vulnerable Pattern

// Third-party response parsed directly into the database and into HTML, unvalidated
app.post('/api/webhooks/partner-update', async (req, res) => {
  // no verification this request actually came from the partner
  const data = req.body;
  await Product.findByIdAndUpdate(data.productId, {
    name: data.name,
    description: data.description, // rendered later without sanitization — stored XSS risk
  });
  res.sendStatus(200);
});

// Disabling TLS verification to "fix" a partner integration issue
const axios = require('axios');
const client = axios.create({
  httpsAgent: new (require('https').Agent)({ rejectUnauthorized: false }), // never do this
});

Secure Pattern

const crypto = require('crypto');
const Joi = require('joi');

// Verify webhook authenticity via signature, exactly like verifying any external input
function verifyWebhookSignature(req) {
  const signature = req.headers['x-partner-signature'];
  const expected = crypto
    .createHmac('sha256', process.env.PARTNER_WEBHOOK_SECRET)
    .update(JSON.stringify(req.body))
    .digest('hex');
  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}

const productUpdateSchema = Joi.object({
  productId: Joi.string().uuid().required(),
  name: Joi.string().max(200).required(),
  description: Joi.string().max(5000).required(),
});

app.post('/api/webhooks/partner-update', async (req, res) => {
  if (!verifyWebhookSignature(req)) return res.status(401).json({ error: 'Invalid signature' });

  const { error, value } = productUpdateSchema.validate(req.body); // validate like any external input
  if (error) return res.status(400).json({ error: 'Invalid payload' });

  await Product.findByIdAndUpdate(value.productId, {
    name: sanitizeHtml(value.name),
    description: sanitizeHtml(value.description), // sanitized before storage/render, same as user input
  });
  res.sendStatus(200);
});

// TLS verification always enabled — fix integration issues at the source, never by disabling it
const client = axios.create({
  timeout: 10000,
  maxRedirects: 3, // bounded, not unlimited
});

Copy-Paste Rules for Cursor, Claude Code, and Codex

---
description: Unsafe consumption prevention — treating third-party API data as untrusted input
alwaysApply: true
---

# Third-Party API Consumption Rules

- Treat every response from a third-party or partner API as untrusted input,
  identical in principle to user-submitted input — validate its schema,
  types, and value ranges before use, and sanitize before storage or rendering.
- Never disable TLS certificate verification to work around an integration
  issue, even temporarily. Fix the underlying certificate/configuration
  problem instead.
- Every webhook receiver MUST verify the authenticity of the caller
  (signature verification, shared secret, mTLS, or provider-specific
  verification mechanism) before processing the payload — "only the partner
  knows this URL" is not authentication.
- Set explicit timeouts and a bounded redirect limit on all outbound calls
  to third-party APIs. Never allow unlimited redirect following.
- Do not assume a third-party API's data is safe to render as HTML,
  interpolate into a database query, or pass to a shell/eval context without
  the same sanitization applied to any other untrusted input.
- Apply the same authentication strength and protocol security (TLS,
  current cipher suites) to third-party integrations as to your own
  user-facing endpoints — do not weaken security "because it's a trusted
  partner."
- When integrating a new third-party API, define and validate an explicit
  expected response schema in the same pass as writing the integration code
  — do not defer validation to "add it later."

Verification Checklist

  • All third-party API responses are validated against an explicit schema before use
  • Data from third-party APIs is sanitized before rendering or storage, identical to user input handling
  • TLS certificate verification is enabled on all outbound integration calls, with no exceptions
  • Every webhook receiver verifies caller authenticity via signature or equivalent mechanism
  • Timeouts and bounded redirect limits are set on all third-party API calls
  • Integration security standards match, not lag, the application's own user-facing security standards
  • Third-party integration points are included in regular security testing — see Trusteed's vulnerability scanner and WAAP for continuous testing across integration surfaces

Frequently asked questions

Is signature verification necessary for webhooks even over HTTPS?

Yes. HTTPS/TLS protects data in transit from interception and tampering, but it doesn't verify that the request actually originated from the claimed partner — anyone who discovers or guesses the webhook URL can send a request to it unless the payload's authenticity is independently verified via signature.

What's the risk of disabling TLS certificate verification "temporarily"?

Disabling certificate verification removes protection against man-in-the-middle attacks on that connection entirely, and "temporary" workarounds have a strong tendency to remain in place indefinitely once the immediate integration problem is resolved — the safer fix is almost always addressing the actual certificate or configuration issue.

How does this category relate to SSRF (API7)?

They're related but distinct: SSRF (API7) is about your API being tricked into making unintended outbound requests based on client-supplied URLs. Unsafe Consumption (API10) is about how your API handles the *response* data it receives from third parties it intentionally integrates with — the direction and trust boundary are different.