Back to Home

Data Attack Surface Reduction

Back to Index

Data is often called “the new oil.” Stored, it behaves more like toxic waste: the more you keep, the more you have to lose. Data Attack Surface Reduction (ASR) means collecting less, keeping it for less time, and handing it to fewer systems than we do today.

“Do we actually need this data, now or ever?”

Some of these reductions shave the blast radius of a breach. Some remove the breach. Records you never collected cannot appear in the dump.


1. Collect Less Data by Default

The most secure data is data you never collected. Every field in the database, every API parameter, every log entry is a liability you have to defend for as long as you hold it. Make data minimalism the default posture, not a review item.

The Principle

Collect only what the product or service cannot function without. Speculative “future-use” fields are security debt with no payoff.

Implementation

Challenge every field in design review. Do we need birth dates, or just age verification (yes/no)? Full addresses, or postal codes for shipping zones? Exact locations, or city-level data for the feature to work?

Bad example: An e-commerce site collects full date of birth, mother’s maiden name, and security questions “in case we need them for support.”

Good example: The same site collects only an “age over 18” flag and uses email-based verification for account recovery. No PII that could be weaponized in social engineering attacks.

Code Example

# BAD: Collecting more than needed
class UserProfile:
    email: str
    full_name: str
    date_of_birth: date
    phone_number: str
    address_line_1: str
    address_line_2: str
    city: str
    postal_code: str
    ssn_last_4: str  # Why???

# GOOD: Minimal collection
class UserProfile:
    email: str
    display_name: str  # Not necessarily real name
    shipping_postal_code: str  # Only if they order physical goods

Real-World Impact

The Equifax breach exposed sensitive data of 147 million people including Social Security numbers, birth dates, and addresses. Much of this data was collected for credit checks but retained indefinitely, creating a massive target.

Data you never collected cannot be subpoenaed.

Case studies: Signal answered a grand jury subpoena with account timestamps and nothing else · DoorDash stored four digits of a bank account, so its breach was not a payments breach · The CNIL ordered KASPR to delete what it had collected, and KASPR deleted the database · Italy’s Garante fined Poste Italiane for monitoring apps it did not need to see · GitHub stopped handing out the list of everyone who starred a repository · Sentry removed the advertising cookies from its own site and left them off

Why this matters: less collected is less to protect, less to lose, and a smaller bill for both storage and fines.

Further reading:


2. Reduce Data Retention

Every day you keep data is another day it can be stolen, leaked, or misused. Delete data as soon as its utility ends.

The Problem

Organizations hoard data indefinitely “just in case”, usually without a justification anyone wrote down. The benefits are hypothetical and the costs are not: compliance risk under GDPR’s storage limitation principle, backups that grow and then have to be secured, a larger blast radius, and debt in the data pipelines.

Implementation Strategy

Apply aggressive time-based purging by default.

Application logs: Keep 30-90 days maximum unless required otherwise

# Example: Automated log cleanup
# In your cron or systemd timer
find /var/log/app/ -type f -mtime +30 -delete

Database backups: Retain only what your disaster recovery plan requires (typically 30 days, not 5 years)

Inactive user data: Delete accounts inactive for 2+ years

-- Example deletion policy
DELETE FROM users 
WHERE last_login < NOW() - INTERVAL '2 years'
  AND account_status = 'inactive';

Temporary data: Session data, cache, uploaded files should all get TTLs.

Real-World Example

Leaked S3 buckets full of old database backups are a common breach source.

In 2020, Wattpad breach exposed account data, including old records that should have been purged years earlier.

Retention is now a regulated decision rather than an internal preference.

Case studies: Capital One’s over-broad credentials turned an SSRF flaw into 106 million records · The FTC ordered Illuminate Education to delete student data it did not need · SafePal’s cleanup job failed for seven months, and the breach reached back to March 2025

Compliance Bonus

GDPR requires “storage limitation” — data should be kept only as long as necessary. Automatic deletion is how that gets satisfied without anyone having to remember it.

Case studies: India’s DPDP Rules put a three-year ceiling and a one-year floor on retention · California’s DROP platform makes data brokers delete on a 45-day clock · Background Alert was ordered to stop operating as a data broker until 2028 · Datamasters was ordered to stop selling Californians’ personal information · Let’s Encrypt deleted the millions of subscriber email addresses it had kept beside issuance records

Further reading:


3. Limit Data Propagation and Transformation

The more you move or copy data, the more risk you create. Every pipeline, integration and environment sync is somewhere else the data can leave from.

Common Anti-Patterns

Copying production data to dev/staging: shockingly common, and dangerous for the same reason every time — production database dumps on developer laptops, staging environments with real customer PII, test environments without proper access controls.

Uncontrolled ETL pipelines: data lakes ingesting everything “just in case”, real-time streams with scopes far wider than the use case, analytics pipelines that copy full datasets.

Third-party integration overload: marketing platforms receiving full customer profiles, support tools with access to payment info, analytics trackers collecting more than the feature needs.

Best Practices

Do analytics in-place where possible:

-- GOOD: Query prod read-replica with aggregation
SELECT DATE(created_at), COUNT(*), AVG(order_value)
FROM orders
WHERE created_at > NOW() - INTERVAL '30 days'
GROUP BY DATE(created_at);

-- BAD: Exporting full orders table to data warehouse daily
EXPORT orders TO 's3://analytics-bucket/full-dump/';

Mask or anonymize dev/test data:

# Example: Data masking for development
def mask_for_dev(user_data):
    return {
        'email': hashlib.sha256(user_data['email'].encode()).hexdigest()[:8] + '@example.com',
        'name': 'Test User ' + str(user_data['id']),
        'phone': 'XXX-XXX-' + user_data['phone'][-4:],
        # Retain structure, remove actual PII
    }

Restrict third-party data sharing: review what the analytics tags collect, what the CRM integration actually needs, and the OAuth scopes granted to third parties. Remove what nothing uses.

Real-World Incident

Case studies: Hospital websites sent appointment details to Facebook through a tracking pixel · Codecov’s modified uploader lifted the secrets out of customer build pipelines · The CNIL fined a loyalty programme €3.5 million for a transfer nobody agreed to

Why this matters: every copy is a chance to expose it, every transformation a place to leak it, every integration a trust decision.

Further reading:


4. Don’t Over-Engineer Analytics

A data lake, a Kafka pipeline, a wall of real-time dashboards. Each one arrives with access controls broader than the data deserves, an intermediate store nobody hardened, and logs full of sensitive fields. The complexity is the vulnerability.

The Problem

Modern analytics infrastructure tends to collect far more than anyone analyzes, run with read access to everything, have no clear owner, and keep it forever because storage is cheap.

ASR Principle

Just because you can analyze it doesn’t mean you should store it.

Store metrics rather than individual events. A 1% sample usually tells the same story as 100%. A simpler pipeline has fewer moving parts and fewer places to leak.

Implementation Examples

Instead of this:

# Collecting everything
analytics_events:
  - user_id
  - session_id
  - ip_address
  - user_agent
  - page_url
  - referrer
  - timestamp
  - custom_properties  # Unbounded object

Do this:

# Collect aggregates
analytics_metrics:
  - page_path  # Not full URL with query params
  - country_code  # Not IP address
  - browser_family  # Not full user agent
  - timestamp_hour  # Not exact timestamp
  - event_count

Real architecture shift:

Old approach: Stream all events → Kafka → Data lake → Multiple analytics tools New approach: Process events at edge → Aggregate → Store only summaries

Case Study

Case studies: Facebook logged hundreds of millions of passwords in plaintext

Further reading:


5. Real-World Breach Patterns

Pattern 1: Public Cloud Storage Exposure

The vulnerability: Misconfigured S3 buckets, Azure Blob containers, or Google Cloud Storage with public read access.

Real incidents: 2019, Capital One’s over-broad credentials turned an SSRF flaw into 106 million records.

ASR approach:

# AWS: Block public access by default (organizationally)
aws s3control put-public-access-block \
  --public-access-block-configuration \
  BlockPublicAcls=true,IgnorePublicAcls=true,\
  BlockPublicPolicy=true,RestrictPublicBuckets=true \
  --account-id 123456789012

# Regular audit
aws s3api list-buckets --query 'Buckets[*].[Name]' \
  | xargs -I {} aws s3api get-bucket-acl --bucket {}

Pattern 2: Log Leaks

The vulnerability: API tokens, passwords, or PII included in logs and shipped to centralized logging solutions.

Common mistakes: authorization headers logged in web server logs, database query logs containing sensitive WHERE clauses, error messages revealing internal system details, debug logs pushed to production.

Example bad logging:

# BAD
logger.info(f"User login: {email} with password {password}")
logger.debug(f"API call: {full_request_including_auth_header}")

# GOOD
logger.info(f"User login attempt: {email[:3]}***")
logger.debug(f"API call to {endpoint} - status {status_code}")

Pattern 3: Stale Environments

The vulnerability: Old production data retained in test environments without sufficient access control.

Scenario: Company creates “staging-2020”, “staging-2021”, “staging-2022” databases. The old ones still contain production data but nobody remembers to secure them or delete them.

ASR approach: Automated cleanup policies

# Example: Tag and auto-delete old environments
aws rds describe-db-instances \
  --query 'DBInstances[?TagList[?Key==`Environment` && Value==`staging`]]' \
  | jq -r '.[] | select(.InstanceCreateTime < "2023-01-01") | .DBInstanceIdentifier' \
  | xargs -I {} aws rds delete-db-instance --db-instance-identifier {} --skip-final-snapshot

Pattern 4: Third-Party Exfiltration

The vulnerability: Overly permissive tracking scripts, SDKs, or tags sending data externally without proper review.

Real incidents: 2022, Meta Pixel healthcare leaks.

ASR approach: Content Security Policy (CSP)

<meta http-equiv="Content-Security-Policy" 
      content="default-src 'self'; 
               script-src 'self' https://trusted-cdn.com; 
               connect-src 'self' https://api.yoursite.com;">

Further reading:


6. Guidelines for Practicing Data ASR

PrincipleActionHow to Implement
Minimal CollectionAsk “why do we need this?” before collecting any new dataAdd data collection reviews to design process; require written justification
Retention LimitsAutomate expiry and deletion policiesImplement TTLs in databases; schedule cleanup jobs; use lifecycle policies
Access ControlLeast privilege on data systemsAudit who can read/write data; remove unused permissions; use IAM policies
AnonymizationUse tokenization or hashing where PII isn’t neededImplement pseudonymization for analytics; hash email addresses in logs
Tag & Tracker ReviewAudit and limit third-party scripts collecting user infoRegular review of all external JavaScript; implement CSP headers
Incident SimulationRun tabletop scenarios assuming your logs, exports, or staging DBs are leakedQuarterly exercises asking “what if X database was public?”

7. Shift the Culture: Less Data Is a Win

Data minimization is a cultural change before it is a technical one.

Benefits of Collecting Less

Regulatory compliance gets easier. GDPR, CCPA, DPDP and HIPAA all favor minimal data collection: fewer data subject access requests (DSARs) to handle, a smaller scope for breach notification requirements, lower fines when incidents do occur.

Breach costs go down. The IBM Cost of a Data Breach Report 2023 shows average cost per record is $165. Fewer records, smaller bill.

User trust goes up. Privacy-conscious users prefer services that collect less. Apple has built a brand around this principle.

Engineers get clarity. When you only store what matters, data models become clearer and queries become simpler.

How to Shift Mindset

  1. Data deletion as a metric: Track and celebrate data removed
  2. Privacy by default: Make “collect less” the default in design docs
  3. Cost visibility: Show teams the storage and compliance costs of data hoarding
  4. Regular audits: Quarterly reviews of what data exists and why

“Data is radioactive. Store only what you can shield. And only for as long as you need it.”

Further reading:


Final Thought

Anything you never collected cannot be stolen; anything you deleted cannot leak; any integration you removed is one fewer exfiltration path.

None of this cripples the product. It only forces an honest answer about what you need versus what you are hoarding “just in case.”

Start today:

  1. Identify your oldest dataset
  2. Ask if anyone has used it in the past 6 months
  3. If not, delete it
  4. Repeat weekly

The best defense against data breaches is having less data to breach.