Skip to main content

Free 30-min security demo  — We'll scan your real code and show live findings, no commitment Book Now

Offensive360
Academy Excessive Data Exposure
Intermediate · 20 min

Excessive Data Exposure

Learn why returning full database objects and filtering client-side exposes sensitive fields to API consumers.

1 Returning Full DB Objects

Excessive data exposure (OWASP API3) occurs when an API returns more data than necessary, relying on the client to filter what it displays. The sensitive data is still accessible in the raw API response.

Vulnerable pattern:

// Returns ALL user fields including password hash, MFA secret, admin flag
app.get("/api/users/:id", async (req, res) => {
  const user = await User.findById(req.params.id);
  res.json(user);  // Sends: { id, email, passwordHash, mfaSecret, isAdmin, creditCard, ssn, ... }
});

// Frontend "hides" sensitive fields:
if (!currentUser.isAdmin) {
  delete userObject.isAdmin;  // Too late — already sent over the wire!
}

An attacker simply inspects the raw API response in browser dev tools or Burp Suite to see all fields, regardless of what the UI displays.

Real-world impact: This pattern has led to mass exposure of password hashes, internal admin flags, credit card numbers, and personal data in APIs across major platforms.

2 Response DTOs and Field Filtering

Return only the minimum required fields from API endpoints. Use Data Transfer Objects (DTOs) to explicitly define what is safe to expose.

Explicit field selection:

// Safe — only expose what the UI needs
app.get("/api/users/:id", async (req, res) => {
  const user = await User.findById(req.params.id)
    .select("id name email avatarUrl bio createdAt")  // Explicit allowlist
    .lean();
  res.json(user);
});

Response DTO (TypeScript):

interface PublicUserDTO {
  id: string;
  name: string;
  email: string;
  avatarUrl?: string;
  bio?: string;
  // NO: passwordHash, mfaSecret, isAdmin, ssn, creditCard
}

function toPublicDTO(user: UserDocument): PublicUserDTO {
  return {
    id: user.id,
    name: user.name,
    email: user.email,
    avatarUrl: user.avatarUrl,
    bio: user.bio,
  };
}

res.json(toPublicDTO(user));

Knowledge Check

0/3 correct
Q1

Why is client-side filtering of API response fields insufficient?

Q2

What is a Data Transfer Object (DTO) in the context of API security?

Q3

What Mongoose method can limit which fields are returned from a database query?

Code Exercise

Return Only Public Fields

The user endpoint returns the complete user document including password hash and admin flag. Fix it to only return name, email, and bio.

javascript