How OpenSea allows Cross-Site-Scripting Attacks (XSS)

Hagen Hübel
3 min readJan 27, 2022

--

Did you know that OpenSea allows us to inject any custom code into their StoreFront via MetaData returned by a SmartContract, virtually performing an XSS attack, even without requiring advanced XSS techniques?

Crypto-Twitter was running wild today when someone told us that OpenSea allows the embedding of custom JavaScript:

Opening this URL (be always careful with that!, I used a secured browser environment for this) actually executes a JavaScript within the OpenSea-StoreFront, that, in this example, detects my current IP address. In the same way, we could also inject some other code used to mine cryptocurrencies like Monero. Wait! Really? Yes.

What is cross-site scripting?

Cross-site scripting (also known as XSS) is a web security vulnerability that allows an attacker to compromise the interactions that users have with a vulnerable application. In the current example with OpenSea, any artist or publisher could feed custom code without having to use any major tricks

That’s when I got curious and wanted to take a look. Here we go.

The SmartContract behind this particular token was deployed on Rinkeby Testnet at https://rinkeby.etherscan.io/token/0x2f3ee0ace02c71bc82863a28633c0f983a5435bb:

Unfortunately, this Contract was not verified on etherscan.io so we have to write some Code in order to find out how they actually made it to inject JavaScript code into the OpenSea Storefront.

According to OpenSea, this contract is based on ERC721. This standard defines a function that will be used to get the real token-Data: tokenUri.

The quickest way I could think of was to write a few lines of JavaScript-code that would allow us to execute the tokenURI function on the SmartContract with token ID “1”. Using ethers.js and Infura makes things as simple as possible:

The tokenURI function returns the following URL to IPFS. IPFS is an immutable and distributed file storage system commonly used in the NFT space to protect the actual image files and their corresponding data:

ipfs://QmYoXDtLZwTG4pcv9yV5SroDv1qrS3evtVJtorvuCyhWS5

… which will point to a JSON document that contains the following data:

It turns out, that OpenSea allows indeed injecting custom Code and even whole HTML pages, running custom JavaScript with only one single Attribute called “animation_url” in the MetaData of an NFT:

The injected JavaScript-Code can be found here: https://everlasting-clever-meter.glitch.me/script.js and will determine your IP-Adress and inject this value into a Span-Element of the embedded HTML-Page (which gets injected by OpenSea Storefront as an IFrame).

How to avoid these attacks?

Since this topic is far beyond the scope of this blog post, I refer to the experts (and every web developer should read this if they haven’t already):

https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html

--

--