The XSS inside your favorite iOS app
How a default WKWebView implementation makes thousands of apps vulnerable to sandboxed HTML/CSS injection or XSS.
Summary
The default configuration of a WKWebView honors Content-Disposition as a sandbox instead of a download, rendering the file’s contents inside the WebView, which allows HTML/CSS spoofing and in some cases XSS, whatever filename the server suggests. This makes any downloadable file render in the context of the hosting origin.
Technical Details
RFC 6266 §4.2 states “If the disposition type matches “attachment” (case-insensitively), this indicates that the recipient should prompt the user to save the response locally, rather than process it normally (as per its media type).” What this means is that if the Content-Disposition response header had “attachment” in the application should tell the user to save the file instead of rendering, about all modern browsers follow this but what about WebKit?
To create a simple WebKit webview that shows contents of a url inside your browser is something like this:
import UIKitimport WebKit
class VC: UIViewController { override func loadView() { let web = WKWebView() view = web web.load(URLRequest(url: URL(string: "https://example.com")!)) }}This simple usage of WKWebView() is vulnerable to sandboxed HTML/CSS rendering without JS when Content-Disposition is present or in some cases even XSS.
Impact
If a website hosted user uploads to the same-origin site or a subdomain and it’s opened inside a vulnerable application; the severity would be Medium and could lead to:
- HTML/CSS spoofing inside a trusted origin
- Same-origin GET request CSRF using
<img src=>
But in some rare cases we saw that JS execution was also possible which would lead to a full XSS on the origin inside the vulnerable application.
POC
Open in any vulnerable iOS or other WebKit app:
Suggested Patch
Manually override the default behavior to download the file or just cancel it
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) { let cd = (navigationResponse.response as? HTTPURLResponse)? .value(forHTTPHeaderField: "Content-Disposition")?.lowercased() ?? "" if cd.contains("attachment") || !navigationResponse.canShowMIMEType { decisionHandler(.download) // or .cancel return } decisionHandler(.allow)}Responsible Disclosure
Before writing this blog we contacted tens of vendors and informed them about the vulnerability, some of them acted responsibly and patched the bug but unfortunately most of them didn’t acknowledge the issue which was disappointing. It was either they didn’t understand the bug or just didn’t care. Cases that make this attack a deliverable payload and risk to the user along with some reported and patched cases:
iOS dApp Browser Wallets
Almost every mobile wallet nowadays has a dApp explorer which allows you to browse dApps and connect your wallet within the app, these web browsers are just embedded webviews and are vulnerable to this attack. An attacker could use this vulnerability to create a spoofing airdrop campaign by hosting a malicious file on a trusted site and pretending to be from that project by matching the origin with the spoofing claim.

Social Media apps
Most social media apps are using embedded browsers, when you send a link to a friend and they tap on it the link will be opened inside the app and not the default web browser, these so called in-app browsers are also using WKWebView and vulnerable too. An attacker would post a malicious file on Facebook, Snapchat, Pinterest, Instagram… and whenever a user opens the link they will get the file rendered on the trusted site instead of downloading or showing an error.

PlayStation 5 and PlayStation 4 browsers
The PlayStation browser also uses WebKit engine, which we found the same vulnerability in, reported and was awarded $10,000 for a high severity console bug. In the POC below we upload a malicious .html file to Discord which will be hosted on cdn.discordapp.com then send it to the victim to steal their credentials. Patched in PS5 software version 25.06-12 and now you get an error instead of rendering the downloadable file.
Firefox iOS and Firefox Focus
Both Firefox iOS browsers were also vulnerable, these were assigned CVE-2025-55030 and CVE-2025-55032 with a bounty of $6,000

Vulnerable Applications (reported and NOT patched)
- Twitter (X)
- Google Gemini
- Snapchat
- Messenger
- OKX
- Binance
- Trust Wallet
- Zeal Wallet
- TikTok
- Telegram
- YouTube
- TronLink
- OneKey Wallet
- MyEtherWallet
- Threads
- Petra Wallet