32942 - [BC - Low] The ChainID and URL parameters that can modify ...
Submitted on Jul 8th 2024 at 15:54:16 UTC by @infosec_us_team for Boost | Shardeum: Core
Report ID: #32942
Report type: Blockchain/DLT
Report severity: Low
Target: https://github.com/shardeum/shardus-core/tree/dev
Impacts:
Network not being able to confirm new transactions (total network shutdown)
Description
Brief/Intro
Shardus server provides two modes; Debug, which omits signature checks in sensitive endpoints for an easier developer experience, and Release which enforces them for security reasons.
In this report, we'll demonstrate how the authentication check on shardus-core/src/network/debugMiddleware.ts
can be bypassed, allowing several behaviors, for example: unauthorized modifications to the server configuration of a Shardus Validator making it unable to confirm new transactions.
Vulnerability Details
As a reference, below is the code of the flagged function that checks if requests to sensitive endpoints are authorized when running in release
mode - the original version is extensive so only the parts relevant to this report were kept.
Snippet of code from: https://github.com/shardeum/shardus-core/blob/dev/src/network/debugMiddleware.ts#L14-L71
The address with the correct authorization level must sign an object with the route of the request and a counter that prevents replay attacks.
The counter is provided as a param in the URL (& sig_counter=
) and the route is taken from the value of the _req.route.path
variable.
The problem: Signing only the path to the endpoint, instead of the full URL including the parameters
Let's use the URL that modifies the configuration of a running validator to demonstrate the bug.
In this URL: http://192.168.0.15:9001/debug-set-shardeum-flag?key=debugTraceLogs&value=false&sig_counter=xxxx&sig=yyyyy
The _req.route.path
is: /debug-set-shardeum-flag
The authorized address intends to set the value of debugTraceLogs to false, and sends the request with a signature of the route path (_req.route.path
) and a sig_counter
.
Unfortunately, because the key
and value
parameters of the URL were not signed a malicious actor can use the same signature and sig_counter to change any shardeum flag in the server, like the ChainID
which would render the server unable to process new transactions due to a ChainID mismatch.
The reason is that this malicious URL http://192.168.0.15:9001/debug-set-shardeum-flag?key=ChainID&value=9999&sig_counter=xxxx&sig=yyyyy which includes the same _req.route.path
, sig_counter
and sig
, passes all checks even though it modifies a value that was not intended to be touched.
Up to this point in the report, for the reader will seem like the "replay attack check" will prevent the same
sig_counter
value from being used twice, forcing the malicious actor to intercept, modify, and send his malicious HTTP request before the legit one is processed.In the next section we'll talk about one of the ways to deal with the replay attack check, making attacks more feasible.
Reusing signatures from "testnet"/"devnets" in "mainnet"
The ChainID should be required to be signed in every request to a sensitive Validator endpoint, assuring that signatures from testnets and development setups running the "Release" mode for testing purposes can't be re-used in mainnet.
Currently, the only requirement for the signature to be valid is to be signed with the route path and a sig_counter bigger than the previous one, therefore a request to a non-mainnet Validator in "Release" mode can have its parameters modified to cause unauthorized behaviors, and be used in mainnet against the same Validator.
Impact Details
There are many potential impacts, depending on the type of signature the attacker malleates, for example, using a signature to the path /debug-set-shardeum-flag
will render a validator unable to process new transactions.
Proof of Concept
As a proof of concept, create a Node JS project and use express to log the value of the req.route.path
. The output of the console shows it only includes the exact defined route, but no query params.
We don't believe that using
req.route.path
in the Shardus Core is a problem by itself, the problem is to not check any of the params sent within the transaction when calculating the signature, which allows for unintended results.
Last updated