Closed code423n4 closed 2 years ago
Note that this assumes that untrusted input will be passed to the conduit; for the purposes of this competition we require that Seaport is the sole conduit, and so this is not vulnerable (though it is still an informative finding!)
Given this scenario falls out of scope, lowing to a Low severity and grouping with the warden's QA report #203
Lines of code
https://github.com/code-423n4/2022-05-opensea-seaport/blob/9d7ce4d08bf3c3010304a0476a785c70c0e90ae7/contracts/lib/TokenTransferrer.sol#L570-L597
Vulnerability details
Impact
The
_performERC1155BatchTransfers
function manually ABI decodesConduitBatch1155Transfer[]
. While doing so it does not verify that the expected array length is within the bounds of what is supplied. We believe this is not the intended behaviour. The Solidity ABI decoder would do such a check usingcalldatasize
and correctly revert. Moreover, it is also missing bounds checks on the length, i.e. high values of length can overflow some calculations leading to reading from incorrectcalldata
offsets.(This part is similar to the other issue using this as a griefing attack (in QA report) -- however, here we describe a malicious case.)
It is possible to submit a truncated array such that some fields in
amounts
is missing (but the array length must be present).Seaport tries to be extremely cautious about preventing any transfers of
0
amount. This is extensively checked in Executor.sol#L224, Executor.sol#L269 and Executor.sol#L373.Proof of Concept
Context:
The test below can be placed inside
foundry/conduit/ConduitExecuteBatch1155.t.sol
and run viaforge test -m "testExecuteBatch1155" -vvvv
:Case 1
The following test below how to transfer
0
amount. This is because data read from out-of-bounds access ofcalldata
. A high level implementation of the above in solidity would have additional checks that prevents such out-of-bounds read, i.e., the samecalldata
in high level code would revert.Case 2
There are additional issues around overflowing of the length. See: TokenTransferrer.sol#L530.
Here
mul(idsLength, TwoWords)
can overflow. Note: this issue is similar to a low severity issue titled "Assertions.sol is missing an assertion about bounds for array length", however in that case, such transactions would eventually revert because the length is used in afor
loop leading to OOG. However, that is not the case here. It's likely that the overflowing case can succeed by carefully picking the parameters.Tools Used
Manual review
Recommended Mitigation Steps
calldatasize
to validate the input to prevent any out-of-bounds access.calldata
locations. For high level solidity code, this check islength < 2**64
, which would correctly prevent the overflowing cases.ids.length == amounts.length
.