Platform: Code4rena
Start Date: 14/04/2023
Pot Size: $90,500 USDC
Total HM: 7
Participants: 59
Period: 14 days
Judge: LSDan
Total Solo HM: 3
Id: 232
League: ETH
Rank: 17/59
Findings: 2
Award: $754.35
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: hihen
Also found by: Parad0x, bin2chen, chaduke, eierina, nobody2018, rvierdiiev
694.5552 USDC - $694.56
readKeyValue()
Possible incorrect read value
readKeyValue()
is used to read the key
and value
values and return the offset nextOffset
of the next key-value pair
The code is as follows:
function readKeyValue( bytes memory input, uint256 offset, uint256 len ) internal pure returns (bytes memory key, bytes memory value, uint256 nextOffset) { uint256 separator = input.find(offset, len, "="); if (separator == type(uint256).max) { return ("", "", type(uint256).max); } uint256 terminator = input.find( separator, len + offset - separator, " " ); if (terminator == type(uint256).max) { terminator = input.length; //<--------@audit Wrong use `input.length`, should use `offset+len` } key = input.substring(offset, separator - offset); value = input.substring(separator + 1, terminator - separator - 1); nextOffset = terminator + 1; }
As the above code comment, when terminator
cannot be found, the wrong setting terminator = input.length
, should use terminator= offset + len
Because input
is limited to find in the length of len
, the current protocol is to reuse bytes
to find in a specific range in many places
For example:
input
contains three blocks: flag, text, signdata
, []
which represents the length of each block, we want to get the second block text
inside the key/value
input = [4]flag|[3]a=b|[8]signdata
At this point if we execute readKeyValue(input,6,3)
, we expect to get key=a
and value=b
The current implementation will get key=a
and value=bsigndata
function readKeyValue( bytes memory input, uint256 offset, uint256 len ) internal pure returns (bytes memory key, bytes memory value, uint256 nextOffset) { uint256 separator = input.find(offset, len, "="); if (separator == type(uint256).max) { return ("", "", type(uint256).max); } uint256 terminator = input.find( separator, len + offset - separator, " " ); if (terminator == type(uint256).max) { - terminator = input.length; + terminator= offset + len; } key = input.substring(offset, separator - offset); value = input.substring(separator + 1, terminator - separator - 1); nextOffset = terminator + 1; }
#0 - c4-pre-sort
2023-05-01T10:38:51Z
thereksfour marked the issue as duplicate of #246
#1 - c4-judge
2023-05-08T14:44:45Z
dmvt marked the issue as satisfactory