---
# System prepended metadata

title: Astar Portal Report

---

# Astar Portal Report

This post contains the 2 vulnerabilities that I've found on the [Astar Portal](https://portal.astar.network) while I was at [DupH0use](https://twitter.com/duph0use).

These vulnerabilities were categorized with *Medium* and *Critical* severities respectively, and were:

**1. Stored Cross-Site Scripting (XSS)**
**2. Firebase Misconfiguration**


## Who is ASTAR?

According to their website:
> "Astar is a multi-chain smart contract platform that supports multiple blockchains and virtual machines. Astar Network connects the Polkadot ecosystem to Ethereum, Cosmos, and all major Layer 1 Blockchains." - [Astar](https://astar.network/) 

Shortly, Astar is a [Polkadot Parachain](https://wiki.polkadot.network/docs/learn-parachains) that allows users to interact with a variety of decentralized applications (dApps) also called Smart Contracts, which can have different purposes, such as staking, delegating, Trading, sending or bridging tokens between users and blockchains. 

These interactions can be made via their [Astar Portal](https://portal.astar.network) which is a platform where users can stake, transfer or withdraw their funds.

## 1. Stored Cross-Site Scripting (XSS)

### 1.1 Short Story
This vulnerability was found while I was looking into the portal and reported via their Discord channel.

Shortly after reported, I received a message saying that the vulnerability will not be considered because the portal is in the "MVP" stage and will not be rewarded. This also occurs because the current scope of the bug bounty has only their Blockchain/DLT application. 

*PS: At the moment of the report, the portal contained little less than 3 Billion ASTR (their own token) and 176 million USD, as shown in the image below:*
![](https://i.imgur.com/kw4MUUt.png)

After some discussion, I could convince them to accept the vulnerability (as I could manipulate the entire information on the page, and possibly steal the user's funds by changing the address of another dApps that will receive the funds), and posteriorly, I receive a message saying that they will insert the portal inside the scope at Immunefi!!!

But, let's hack!!!

### 1.2 HackStage

On the *dApp Staking* page, users can register a new dApp (an application in which users will stake their funds) with some information about the dApp itself (Name, Description, Image, Links, etc.).
![](https://i.imgur.com/OHCeOXE.png)

The problem here is that the *Description* field doesn't sanitize the Markdown text, and incorporate it directly on the page, allowing the XSS.

In this example, I used the payload *&lt;details open ontoggle=alert(document.cookie)>rapt00r&lt;/details>*.
![](https://i.imgur.com/0ETEf0x.png)

By clicking on preview, the alert will be prompted:
![](https://i.imgur.com/VH6Ji0n.jpg)

So, when the users visit this dApp, the XSS will be executed.

*PS: At the moment, only whitelisted developers (KYC'd and voted by the community) can create new dApps, difficulting (but not mitigating) the exploitation of this vulnerability*

## 3. Firebase Misconfiguration

The portal uses the Firebase as a back-end infrastructure to store the data (dApps names, addresses, and so on). For those who don't know what is Firebase, there is a short resume about it:

*Firebase is a powerful platform for building mobile and web applications. It offers real-time data synchronization, user authentication, and static hosting for your web app. Firebase is built on the Google Cloud Platform and uses the same infrastructure that powers Google’s own products.* 

It means that if an attacker has access to this firebase instance, it can modify the entire data, such as the dApps addresses (the address that users will send their funds), and again (:P), steal all user's funds.

#### 3.1 Identifying the Firebase

When I accessed the dApps Staking page, I noticed the following request made by the application:
![](https://i.imgur.com/jLsDmKQ.png)

As we can see, the application fetched all information about the dApps on the Firebase project called *astarnetwork-a4924*, and the collection *astar-dapps*. The remaining information is self-explained.

(The Authorization token will be explained at the end).

In response, we can see all information of the dApps, such as name, description, emails, and the address.

*I'll pass into the Firebase queries fastly (probably I'll write more about later :])*

It's very simple to deal with Firebase, you just need the project name, collection id, the document id, and the necessary fields to read, write or modify the data.

Let's look how a query to fetch all data looks like (we already saw it above, but let's see again):

> POST https://firestore.googleapis.com/v1/projects/PROJECT_NAME/databases/(default)/documents:runQuery
> {"structuredQuery":{"from":[{"collectionId":"COLLECTION_NAME"}]}}

Here, we are fetching all data from the collection *COLLECTION_NAME* inside the project *PROJECT_NAME*.

The next query looks like:

> GET https://firestore.googleapis.com/v1/projects/PROJECT_NAME/databases/(default)/documents/COLLECTION_ID/ID

The query above will fetch the data from a specific document.

One more:

> POST https://firestore.googleapis.com/v1/projects/PROJECT_NAME/databases/(default)/documents/COLLECTION_NAME
> {"fields":{"name":{"stringValue":"rapt00r"}}}

The query above will create a new document containing the field *name* with the value *rapt00r* on the collection *COLLECTION_NAME* inside the Firebase project *PROJECT_NAME*. After created, the response will contain all information about the new document, in this case, the name and the ID.

To delete a document, simply execute the query:
> DELETE https://firestore.googleapis.com/v1/projects/PROJECT_NAME/databases/(default)/documents/COLLECTION_NAME/ID

To update a document is a bit complex:
> PATCH https://firestore.googleapis.com/v1/projects/PROJECT_NAME/databases/(default)/documents/COLLECTION_NAME/ID?updateMask.fieldPaths=FIELD_NAME&updateMask.fieldPaths=ANOTHER_FIELD_NAME
> {"fields":{"FIELD_NAME":{"stringValue":"VALUE"}, "ANOTHER_FIELD_NAME":{"stringValue":"VALUE"}}}

The fields passed on the query must be the same at the body, and the fields that are not present will not be updated!


So simple :), now, let's see this in action...

### 3.2 Exploitation

During the recon phase, I noticed that the portal has some networks (Astar [Polkadot], Shiden Network [Kusama], Shibuya [Testnet], Local and Custom Network) to be used (In this exploitation, I'll use the *Shibuya* Network).
![](https://i.imgur.com/tap1QQa.png)

The first step was to identify the collection name for the project on the *Shibuya Network*:
![](https://i.imgur.com/s2AHjXX.png)

By looking into the requests after changing the network I found it, **shibuya-testnet-dapps**

Let's create a new document inside this collection?
![](https://i.imgur.com/QpFLxgu.png)

Looking into the portal, we can see that the dApp was been created:
![](https://i.imgur.com/Gyfc9ZX.png)

So, let's change the data from another project?

First, let's fetch the current data from the project called `DeCus`:
![](https://i.imgur.com/bNVg5yw.png)

Let's update the address of this project to another one, I chose the 0x0 :P
![](https://i.imgur.com/4StoVUc.png)

Looking on the Portal:
![](https://i.imgur.com/kLnvkGv.png)

### 3.3 And the Authentication Token?

Well, in this case, the Authentication Token was provided when the user accessed the application, no login/password, no sign with the wallet, just visit the website and you will get a token.

The image below illustrates the request made to generate a new token:
![](https://i.imgur.com/aK6QLZj.png)

The `localId` is the "user id" in this case.

The problem here is that the Firebase project is not configured the permissions correctly, allowing anonymous users to modify the data... In this case, anonymous users must have access only to read the data inside the project.

The portal also needs to implement an authentication mechanism (login/password or a message signature with whitelisted wallets) to generate a token with read/write permissions.

## Bounties

XSS: $2500
Database Takeover: $1000
Total: $3500