IPFS Gateway Security
TL;DR: Path-based IPFS gateways have a critical flaw: They effectively disable one of the essential security features of modern browsers: the same-origin policy.
What is IPFS?
A peer-to-peer hypermedia protocol designed to make the web faster, safer, and more open. – ipfs.io
IPFS is a peer-to-peer protocol for a distributed filesystem. It allows anyone to become a node in a distributed system to share resources via a content-based addressing scheme. IPFS is built and maintained by Protocol Labs and open-source.
Resource Access on IPFS
Resources on IPFS can either be accessed by running a local node or relying on a gateway: A hosted service that routes requests through IPFS and serves the response content. There are a lot of IPFS gateway providers and plenty to choose from.
Let’s illustrate the interaction with a gateway server in a small example.
You would like to visit https://app.uniswap.org to swap some tokens.
The website is served via HTTP port
443 (HTTPS) from the domain
<scheme>://<host>:<port> is what the browser defines as an origin.
Certain security restrictions are put in place to protect one origin from interacting or accessing/modifying data from another one.
We now want to access the Uniswap website in a decentralized way through a gateway of our choice.
Luckily, the folks at Uniswap also made their UI available on IPFS.
There is a content ID (CID) from the Uniswap releases page that an end-user can use to navigate to the Uniswap front-end via IPFS:
Here comes the moment of truth. There are two ways a CID can be passed to a gateway:
Caught the difference? Both URLs work just fine. IPFS web gateways may serve content in two different modes:
- Subdomain gateway mode: e.g.
- Path gateway mode: e.g.
Remembering the definition of a domain’s origin, the big difference here lies in who is authorized to access the served site’s data. From a web browsers perspective, the subdomain addressing scheme (1) puts every CID into a unique origin, preserving the same-origin policy. With the path addressing scheme (2), all CID’s you navigate to will share the exact origin (e.g. ipfs.io). A global origin like this allows any content hosted under a certain CID to access/modify another CID’s data.
What would that look like in practice? For Uniswap (and its forked friends), the local storage looks like this:
We can see the key
It contains a JSON object containing the key
In there, we find a list of token lists that are activated by default.
An attacker may exploit a shared origin by enabling a malicious token list that a user cannot distinguish from a legitimate one unless they inspect their local storage.
In the worst case, this can result in a loss of funds for the user.
Similarly, settings such as slippage, trade deadlines, and more can be changed using the
redux_localstorage_simple_user storage key.
Generally, an attacker can use this flaw to de-anonymize users of decentralized exchanges.
The flaw can be critical even for static pages like Uniswap: Not only because the information is shared and therefore leaked with all other CID’s (Information Leakage/User Fingerprinting and De-Anonymization) but also because one CID can manipulate data stored in the browser by another application.
Hosters should stop running public path-based IPFS gateways.
At the very least, gateway servers should enforce a redirection to a domain-based access URL.
Developers should stop providing path-based gateway links in their projects.
A shoutout goes to the folks at Uniswap, who already wrote a warning on path-based gateways in their release docs. They now also consider completely removing insecure direct links. To properly secure end-users, a warning in the docs might not be enough, however.
Things to keep in mind
Do not consume websites hosted on IPFS via path-based gateways, as this completely bypasses the same-origin policy. Do not get misled by a shiny ✅ on the public IPFS gateway checker list. The ✅ next to CORS means that the gateways wildcard allows all CORS access. This can be a security issue.
Be aware that public gateways may default to enabling CORS for all domains, allowing one CID to interact with resources from another CID (and potentially data stored for that CID). You are trusting the gateway to deliver the content you requested. There is no way for your browser to verify whether the content received is what is stored in the IPFS distributed filesystem. You are trusting the gateway to not alter the CID before delivering it to you. Therefore, we can only recommend running a self-hosted gateway. Your connection to the IPFS gateway may be transport secured (HTTPS), but it is terminated at the gateway. The gateway may keep a protocol of your connection details and the data you have requested.
Thinking about smart contract security? We can provide training, ongoing advice, and smart contract auditing. Contact us.