---
title: Set Anti-cache Headers
impact: MEDIUM
impactDescription: prevents sensitive data from being cached in browsers or intermediate proxies
tags: headers, cache, sensitive-data, security, php
---

## Set Anti-cache Headers

Pages containing sensitive user information (like bank statements, personal details, or private messages) should not be cached by browsers or intermediate proxy servers (CDNs). If cached, this information might be accessible to subsequent users of the same device or shared network.

**Incorrect (no cache control for sensitive data):**

```php
// Sensitive data returned without cache instructions
$balance = getBalance($userId);
echo json_encode(['balance' => $balance]);
```

**Correct (anti-cache headers):**

```php
// 1. Plain PHP
header('Cache-Control: no-store, no-cache, must-revalidate, private');
header('Pragma: no-cache');
header('Expires: 0');

echo json_encode($sensitiveData);

// 2. In Laravel Middleware
public function handle($request, Closure $next) {
    $response = $next($request);
    
    // Check if the response is for an authenticated user
    if (auth()->check()) {
        $response->headers->set('Cache-Control', 'no-store, no-cache, must-revalidate, private');
        $response->headers->set('Pragma', 'no-cache');
        $response->headers->set('Expires', '0');
    }
    
    return $response;
}
```

**When to use anti-cache:**
- User profile pages.
- Financial transactions and history.
- Admin dashboard pages.
- Any API endpoint returning non-public, authenticated data.

**Key Header Meanings:**
- `no-store`: Do not store any part of this response on disk (most important for security).
- `no-cache`: Must re-validate with the server before using a cached copy.
- `private`: Only intended for the single user, do not store in shared caches (proxies).

**Tools:** Header Audit Tools, Browser Developer Tools (Network Tab), SonarQube
