#39913 [BC-Medium] No rate Limiting in resource-intensive endpoint

Submitted on Feb 10th 2025 at 17:35:57 UTC by @gladiator111 for Audit Comp | Shardeum: Core III

  • Report ID: #39913

  • Report Type: Blockchain/DLT

  • Report severity: Medium

  • Target: https://github.com/shardeum/shardeum/tree/bugbounty

  • Impacts:

    • Increasing network processing node resource consumption by at least 30% without brute force actions, compared to the preceding 24 hours

Description

Brief/Intro

query-certificate endpoint has no rate-limiting in place unlike other similar resource intensive endpoints

Vulnerability Details

In the following endpoint there is no rate limiting implemented

// @audit - No rate Limiting
shardus.registerExternalPut(
    'query-certificate',
    externalApiMiddleware,
    async (req: Request, res: Response) => {
      try {
        nestedCountersInstance.countEvent('shardeum-penalty', 'called query-certificate')
        const queryCertRes = await queryCertificateHandler(req, shardus)
        if (ShardeumFlags.VerboseLogs) console.log('queryCertRes', queryCertRes)
        if (queryCertRes.success) {
          const successRes = queryCertRes as CertSignaturesResult
          stakeCert = successRes.signedStakeCert
          /* prettier-ignore */ nestedCountersInstance.countEvent('shardeum-staking', `queryCertificateHandler success`)
        } else {
          /* prettier-ignore */ nestedCountersInstance.countEvent('shardeum-staking', `queryCertificateHandler failed with reason: ${(queryCertRes as ValidatorError).reason}`)
        }

       res.json(Utils.safeJsonParse(Utils.safeStringify(queryCertRes)))
      } catch (error) {
        /* prettier-ignore */ if (logFlags.error) console.error('Error in processing query-certificate request:', error)
        res.status(500).json({ error: 'Internal Server Error' })
      }
    }
  )

If we look at similar endpoints, rate limiting is applied. For example in the following endpoint : -

The 'query-certificate' endpoint calls queryCertificateHandler which is a massive function, which verifies everything first, then queries the certificate and then gathers signatures from the nearest peers. This endpoint can be used for performing a DOS and increasing load on the node by continously querying certificate using the same request.

There is a second weakpoint also. The request can be sent by anybody, he just needs to sign it, as in the verification it only checks if the signature matches the payload and not if owner==nominee (Although this can be a design feature by shardeum so I am not heavily focusing on this point).

Recommendation

Use trySpendServicePoints function to implement rate limiting in this endpoint.

Impact Details

-> Increased strain on the node -> Endpoint can be used for DOS/DDOS

References

https://github.com/shardeum/shardeum/blob/167e48478403918468410dd7562929653d5b9f6b/src/index.ts#L2341-L2363

Proof of Concept

Proof of Concept

The Proof of concept has the following flow - -> Spin up a node -> Stake for the node (on bb-testnet) -> Call the 'query-certificate' endpoint continously on any of the active node on the testnet

So first we have to spin up a node on the bb-testnet. We need to modify config.json in the shardeum repo first

We also need to add a get endpoint for easy signing, add the following to shardeum/src/index.ts

Now let us spin up our node, compile the project and run node ./dist/src/index.js. This will spin up the node and will produce a secrets.json which contains our node's public and private key. Now let us stake some SHM.

ok, so now staking done, now let us sign the payload. Signing the payload and sending requests can be done in one step but I did these separately, you can do it all at one time.

Now, we've got the signed payload, copy the payload from the terminal (from console.log) . Now run the following test with the following command

Note that this is just a simple script written in node, more sophisticated/specialized tools can also be used for greater effect.

Was this helpful?