Security

    NSURLCache: when sensitive responses get cached on disk

    A 2026 view of NSURLCache writing a sensitive API response to a plaintext cache file on disk, contrasted with an ephemeral session and a no-store directive preventing caching

    Your app makes an API call, gets back a response full of the user's data, and shows it. Behind the scenes, iOS may have quietly written that response to a cache file on disk, in plaintext, so it can serve it faster next time. NSURLCache, part of the URL loading system, does this automatically, which is great for performance and a problem if the responses contain sensitive data. A cached response holding personal information or anything confidential becomes data at rest you did not intend to store, recoverable on a compromised device or from a backup. Here is what NSURLCache does, where the leak happens, and how to keep sensitive responses out of the cache.

    Short answer

    NSURLCache is the iOS URL loading system's HTTP response cache, which can store responses your app receives in memory and on disk to speed up repeat requests. Per Apple, this caching is automatic, so if a response contains sensitive data, it can be written to a cache file on disk in plaintext, where it persists and can be recovered on a compromised device or swept into a backup. The fix is to keep sensitive responses out of the cache: use an ephemeral session configuration or disable caching for sensitive requests, have the server send no-store cache directives, and clear the cache on logout. Treat cached responses as part of your data-at-rest surface, and do not let sensitive API data be cached on disk.

    What you should know

    • NSURLCache caches HTTP responses: in memory and on disk, automatically.
    • Cached responses can hold sensitive data: written to disk in plaintext.
    • It persists and can leak: recoverable on a compromised device or backup.
    • Disable caching for sensitive requests: ephemeral sessions or per-request policy.
    • Clear the cache on logout: and have the server send no-store.

    What is NSURLCache, and what is the risk?

    It is the cache behind the URL loading system, storing responses so repeated requests can be served without hitting the network. When your app makes HTTP requests through the standard networking APIs, the system can cache the responses according to cache policy and the response's headers, keeping them in memory and writing them to a cache store on disk in the app's container. For performance this is helpful, a repeated request can be answered from the cache. The risk is that this happens automatically and indiscriminately unless you control it, so a response carrying sensitive data, an API result with personal information, account details, or other confidential content, can be written to the on-disk cache in plaintext. That cached copy persists beyond the moment it was shown, joining your app's data-at-rest footprint, where it could be read on a jailbroken or compromised device or included in a device backup. So the issue is not that caching exists, but that sensitive responses get cached by default when you have not told the system otherwise.

    Where does sensitive data leak?

    Into the cache store and anywhere it travels. The table lists the paths.

    PathExposure
    On-disk cache storeSensitive responses written to disk in plaintext
    PersistenceThe cached copy outlives its display
    Device backupsThe cache included in a backup
    Compromised deviceCache files read on a jailbroken device
    WKWebView cacheWeb content cached separately by a web view

    The primary leak is the on-disk cache store: responses written there sit in plaintext in the app's container, so any sensitive content in a cached API response is now stored, and it persists past the moment it was needed, which is the essence of an unintended data-at-rest exposure. From there it can travel: the cache can be included in device backups, and on a compromised or jailbroken device the cache files can be read directly. If your app shows web content, a WKWebView maintains its own cache as well, a separate store with the same kind of concern. In every case the underlying problem is the same, sensitive data persisted on the device through caching you did not intend, so the response that was meant to be transient is actually retained.

    How do you prevent caching sensitive responses?

    Tell the system not to cache them, on both the client and the server. On the client, for requests that return sensitive data, avoid the default caching: use an ephemeral session configuration, which keeps no persistent cache on disk, for sensitive traffic, or disable the cache for those requests by setting an appropriate cache policy or removing the cache from the session configuration. On the server, send cache-control directives such as no-store on responses with sensitive content, so the system does not cache them regardless of client defaults, which is a clean, declarative control. Clear the cache when it matters, calling the cache's remove-all on logout so a previous user's cached responses do not linger for the next person or on the device. If you use a WKWebView for sensitive content, manage its data store too, since it caches separately. The principle is to decide which responses are sensitive and ensure those are never written to disk, through ephemeral or non-caching sessions and no-store directives, while letting ordinary, non-sensitive responses cache for performance. Match caching to sensitivity, rather than letting everything cache by default.

    What to watch out for

    The first trap is relying on default caching for sensitive API responses, which writes them to disk in plaintext where they persist; use ephemeral or non-caching sessions and no-store for sensitive requests. The second is forgetting the cache is included in backups and readable on a compromised device. The third is overlooking the separate WKWebView cache and not clearing cached responses on logout. Caching behavior is configured in your networking and on your server, so a pre-submission scan such as PTKD.com (https://ptkd.com), which reads the compiled IPA against OWASP MASVS, assesses your app's data-at-rest posture, the storage surface the response cache belongs to, while the cache configuration is yours to set.

    What to take away

    • NSURLCache automatically caches HTTP responses in memory and on disk, so sensitive responses can be written to disk in plaintext and persist as unintended data at rest.
    • The cached data can be read on a compromised device, included in backups, and a WKWebView caches separately, all extending the exposure.
    • Prevent it by using ephemeral or non-caching sessions for sensitive requests, sending no-store directives from the server, and clearing the cache on logout.
    • Treat cached responses as part of your data-at-rest surface, and use a pre-submission scan such as PTKD.com to assess your storage posture.
    • #ios
    • #nsurlcache
    • #url-cache
    • #data-at-rest
    • #caching
    • #owasp-masvs
    • #app-security

    Frequently asked questions

    What is NSURLCache?
    It is the cache behind the iOS URL loading system, storing HTTP responses so repeated requests can be served without hitting the network. When your app makes requests through the standard networking APIs, the system can cache responses according to cache policy and the response headers, keeping them in memory and writing them to a cache store on disk in the app's container. This is helpful for performance, but it happens automatically, so without your controlling it, responses, including sensitive ones, can be written to the on-disk cache in plaintext.
    Why is response caching a security risk?
    Because sensitive responses can be written to disk in plaintext and persist. A response carrying personal information, account details, or other confidential content gets cached automatically unless you say otherwise, and that cached copy sits in the app's container past the moment it was shown, joining your data-at-rest footprint. From there it can be read on a jailbroken or compromised device and included in device backups. So a response meant to be transient is actually retained on disk, which is an unintended data-at-rest exposure created by default caching.
    How do I stop sensitive responses from being cached?
    Tell the system not to cache them, on both sides. On the client, for requests returning sensitive data, use an ephemeral session configuration, which keeps no persistent disk cache, or disable the cache for those requests via an appropriate cache policy or by removing the cache from the session configuration. On the server, send cache-control directives like no-store on sensitive responses so they are not cached regardless of client defaults. And clear the cache on logout so a previous user's cached responses do not linger. Let non-sensitive responses cache for performance.
    Does WKWebView cache separately from NSURLCache?
    Yes. If your app displays web content in a WKWebView, it maintains its own data store and cache, separate from NSURLCache, with the same kind of concern: sensitive web content can be cached on disk. So if you show sensitive content in a web view, manage its data store too, clearing or scoping it as appropriate, rather than only handling the NSURLCache used by your native networking. Both are part of your app's on-device caching surface, and sensitive data should not persist in either store unintentionally.
    How do I check for cached sensitive data?
    Scan the build for its storage posture. A pre-submission scan such as PTKD.com reads the compiled IPA against OWASP MASVS and assesses your app's data-at-rest posture, which is the storage surface the response cache belongs to, helping you think about where data persists on the device. The caching configuration itself, using ephemeral or non-caching sessions for sensitive requests, sending no-store from the server, and clearing the cache on logout, is set in your networking code and on your server, which the scan points you toward reviewing for sensitive data at rest.

    Keep reading

    Scan your app in minutes

    Upload an APK, AAB, or IPA. PTKD returns an OWASP-aligned report with copy-paste fixes.

    Try PTKD free