Sensitive Data Exposure Explained

Share

TL;DR

Sensitive data exposure occurs when applications fail to protect confidential information like passwords, credit cards, personal data, or health records. This happens through unencrypted transmission (no HTTPS), improper storage (plain text passwords), oversharing in API responses, or inadequate access controls. Protect sensitive data with encryption (TLS for transit, AES for storage), minimize data collection, and never return more data than needed.

What Is Sensitive Data Exposure?

Sensitive data exposure is a broad category covering any situation where confidential information becomes accessible to unauthorized parties. This includes:

  • Personal Identifiable Information (PII): Names, addresses, phone numbers, SSNs
  • Financial data: Credit card numbers, bank accounts, transaction history
  • Authentication data: Passwords, session tokens, API keys
  • Health information: Medical records, prescriptions, diagnoses
  • Business secrets: Internal documents, algorithms, customer lists

How Data Gets Exposed

1. No HTTPS (Data in Transit)

Unencrypted transmission
// User submits login form over HTTP
// Anyone on the network can see:
POST http://yoursite.com/login
Content-Type: application/x-www-form-urlencoded

email=user@example.com&password=secret123

// This is visible to:
// - ISPs, network operators
// - Anyone on the same WiFi
// - Government surveillance

2. API Oversharing

Returning too much data
// VULNERABLE: Returns entire user object
app.get('/api/users/:id', async (req, res) => {
  const user = await db.user.findUnique({ where: { id: req.params.id } });
  res.json(user);
});

// Response includes sensitive fields:
{
  "id": 123,
  "email": "user@example.com",
  "name": "John Doe",
  "passwordHash": "$2b$12$...",     // Should never expose!
  "ssn": "123-45-6789",              // Definitely not!
  "creditCard": "4111111111111111",  // Catastrophic!
  "internalNotes": "VIP customer"    // Business sensitive
}
SECURE: Select only needed fields
app.get('/api/users/:id', async (req, res) => {
  const user = await db.user.findUnique({
    where: { id: req.params.id },
    select: {
      id: true,
      name: true,
      avatarUrl: true
      // Only public fields
    }
  });
  res.json(user);
});

3. Logging Sensitive Data

Accidentally logging secrets
// DANGEROUS: Logging request bodies
app.use((req, res, next) => {
  console.log('Request:', JSON.stringify(req.body));
  // Logs passwords, credit cards, etc.
  next();
});

// DANGEROUS: Logging user objects
console.log('User logged in:', user);
// May include sensitive fields

4. Client-Side Storage

Storing sensitive data in browser
// VULNERABLE: Sensitive data in localStorage
localStorage.setItem('user', JSON.stringify({
  id: 123,
  email: 'user@example.com',
  creditCard: '4111111111111111'  // Never store this client-side!
}));

// Anyone with browser access can see this
// XSS attacks can steal this data

Data Exposure in Vibe-Coded Apps

AI-generated code often returns complete database records without filtering:

Common AI patterns that leak data: Returning full user objects from login, including all fields in list views, logging full request/response bodies, and storing user data in localStorage without filtering.

How to Prevent Data Exposure

1. Always Use HTTPS

Enforce HTTPS in Next.js
// next.config.js
const securityHeaders = [
  {
    key: 'Strict-Transport-Security',
    value: 'max-age=63072000; includeSubDomains; preload'
  }
];

module.exports = {
  async headers() {
    return [{ source: '/:path*', headers: securityHeaders }];
  }
};

2. Minimize Data Collection

Only collect data you actually need. If you don't store it, you can't leak it.

3. Use DTOs (Data Transfer Objects)

Create response shapes
// Define what data can be returned
interface PublicUserDTO {
  id: string;
  name: string;
  avatarUrl: string;
}

function toPublicUser(user: User): PublicUserDTO {
  return {
    id: user.id,
    name: user.name,
    avatarUrl: user.avatarUrl
  };
}

// Use in API
app.get('/api/users/:id', async (req, res) => {
  const user = await getUser(req.params.id);
  res.json(toPublicUser(user));
});

4. Encrypt Sensitive Data at Rest

Field-level encryption
import crypto from 'crypto';

const ENCRYPTION_KEY = process.env.ENCRYPTION_KEY;

function encrypt(text: string): string {
  const iv = crypto.randomBytes(16);
  const cipher = crypto.createCipheriv('aes-256-cbc', ENCRYPTION_KEY, iv);
  let encrypted = cipher.update(text, 'utf8', 'hex');
  encrypted += cipher.final('hex');
  return iv.toString('hex') + ':' + encrypted;
}

// Store SSN encrypted
await db.user.create({
  data: {
    name: 'John Doe',
    ssnEncrypted: encrypt(ssn)
  }
});

What counts as sensitive data?

Passwords, financial information, social security numbers, health records, authentication tokens, and any personal data that could identify an individual or cause harm if exposed.

Is HTTPS enough to protect data?

HTTPS protects data in transit but not at rest or in your application logic. You also need proper access controls, encryption for stored data, and careful handling in your code.

Do I need to encrypt all data in my database?

Not all data, but highly sensitive fields (SSN, credit cards, health info) should be encrypted at the application level. Regular data is typically protected by database access controls and backups encryption.

Find Data Exposure Issues

Our scanner detects sensitive data in API responses and client-side code.

Start Free Scan
Vulnerability Guides

Sensitive Data Exposure Explained