CWE-525 is a web application that does not use an appropriate caching policy specifying how much each page and its form fields may be cached. The browser then keeps what it should not.
How it happens
Browsers store pages, and sometimes form field values, in a client side cache, so the next visit is faster. Without instructions from the server, that cache may hold account pages, statements, search results and filled forms. Using the back button can show a signed out user the last page they saw.
The record lists two CVEs that match this.
- CVE-2024-30127: a product does not set the no-cache option in the HTTP Cache-Control header, allowing sensitive information to be cached.
- CVE-2024-45314: the login form for an application development framework does not set no-cache and other options in the Cache-Control header.
The fix in both is a missing response header.
HTTP/1.1 200 OK
Content-Type: text/html
(no Cache-Control header, browser decides on its own)
What an attacker gains
MITRE lists reading application data. Browsers often store information like passwords or credit card numbers in the client cache, which leaves it for other users to find. The locations most at risk are public terminals, such as those in libraries and Internet cafes. A shared family computer or a borrowed laptop has the same issue.
How to find it
The record lists no detection methods, but this is easy to test.
- Load a sensitive page and read the response headers in the browser tools. Look for
Cache-Control,PragmaandExpires. - Sign in, visit an account page, sign out and press Back. If the page shows, it was cached.
- Check the browser cache folder on a test machine for HTML from sensitive pages.
- Run a dynamic web scan, which usually reports missing cache headers on pages with forms.
How to fix it
MITRE lists these steps.
- Protect information stored in the cache.
- Use a restrictive caching policy for forms and pages that may carry sensitive information, such as no-cache in the Cache-Control header.
- Do not store unnecessarily sensitive information in the cache.
- Consider encryption in the cache.
For most apps, set the header on every authenticated response, not only the login page.
# Flask example
@app.after_request
def no_store(resp):
if current_user.is_authenticated:
resp.headers["Cache-Control"] = "no-store"
return resp
no-store tells browsers and shared caches not to keep the response at all. no-cache allows storing but forces revalidation, which is weaker for sensitive pages. For form fields that hold card numbers or one time codes, also set autocomplete="off".
Apply the policy by default and open it up only for static assets. That way a new page cannot forget the header.
Try it yourself
Click through it at your own pace, or open it full screen.
Quick check
Why does the back button matter?
If the page was cached, a later user of the same browser can see an earlier user's page after sign out.
Which header does MITRE name?
Cache-Control, set restrictively, for example with no-cache.