sherlock-audit / 2024-02-tapioca-judging

3 stars 2 forks source link

ComposableSecurity - OFT can be impersonated through `_lzCompose` with multiple compose messages #135

Closed sherlock-admin3 closed 4 months ago

sherlock-admin3 commented 4 months ago

ComposableSecurity

high

OFT can be impersonated through _lzCompose with multiple compose messages

Summary

The _lzCompose function in TapiocaOmnichainReceiver contract handles the cross-chain messages retrieved from different chains. The first parameter srcChainSender_ represents the sender of the message on the source chain.

The issue is the following: if the message contains the next compose message, the _lzCompose function is called with address(this) as the srcChainSender_. This allows anyone to make a cross-chain calls with multiple compose messages, and execute the messages (all except the first one) as the OFT contract.

The user can send a message with multiple compose messages using sendPacket function in OTF tokens.

Vulnerability Detail

The OFT tokens (USDO, TOFT, mTOFT) delegate the lzReceive() execution to the Omnichain receiver that inherits from TapiocaOmnichainReceiver. This means that the cross-chain messages (send via Layer Zero) are handled by _lzCompose function from TapiocaOmnichainReceiver.

https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/gitmodule/tapioca-periph/contracts/tapiocaOmnichainEngine/TapiocaOmnichainReceiver.sol#L146-L184

The first parameter of the function (srcChainSender_) represents the sender of the message on the source chain. The main compose message is executed with correct value of srcChainSender_ parameter.

However, the nested messages will be executed with address(this) as the srcChainSender_ - it means that the operation will be executed on behalf of OFT token.

The next message is retrieved by the decodeToeComposeMsg function:

https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/gitmodule/tapioca-periph/contracts/tapiocaOmnichainEngine/TapiocaOmnichainEngineCodec.sol#L117-L137

The sendPacket function accepts any bytes for _composeMsg parameter, which is forwarded to the same function in TapiocaOmnichainSender contract. There, it is passed to _buildOFTMsgAndOptions without any modification and, in the end, it is encoded using LayerZero's OFTMsgCodec library - again, with no modification.

That said, the sender has full control over the compose message and can specify any number of nested messages (represented as _nextMsg).

Impact

HIGH - Anyone is able to execute operations in Tapioca on behalf of the OFT tokens.

Code Snippet

https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/contracts/usdo/Usdo.sol#L188

https://github.com/sherlock-audit/2024-02-tapioca/blob/main/TapiocaZ/contracts/tOFT/mTOFT.sol#L234

https://github.com/sherlock-audit/2024-02-tapioca/blob/main/TapiocaZ/contracts/tOFT/TOFT.sol#L182

https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/gitmodule/tapioca-periph/contracts/tapiocaOmnichainEngine/TapiocaOmnichainReceiver.sol#L180-L183

Tool used

Manual Review

Recommendation

Execute next messages with current value of srcChainSender_ as the first parameter to the _lzCompose recurrent call.

Duplicate of #113

sherlock-admin4 commented 4 months ago

1 comment(s) were left on this issue during the judging contest.

takarez commented:

there didnt seem to be any impact mentioned, impersonate to cause DOS, steal funds break functionality?

ComposableSecurityTeam commented 3 months ago

Escalate

This issue is not duplicate of #111. Actually, the issue #111 is a dup of another issue I reported (#136).

This issue has different:

Attack vector

In #111 the root cause is in _remoteTransferReceiver function:https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/gitmodule/tapioca-periph/contracts/tapiocaOmnichainEngine/TapiocaOmnichainReceiver.sol#L224). The sender of cross-chain message can make the recipient to initiate another cross-chain message (e.g. another remote transfer message).

In this issue (#135) the root cause lies in the _lzCompose function (https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/gitmodule/tapioca-periph/contracts/tapiocaOmnichainEngine/TapiocaOmnichainReceiver.sol#L182). That is, when the OFT contract executes a list of compose messages, the first is executed with the correct sender in srcChainSender_ parameter, and the rest of messages contain the address of OFT contract in the srcChainSender_ parameter (set in the line linked above).

The attacker can simply create a cross-chain call with more than one compose message where the first message is executed as intended and the rest have the OFT contract as the sender.

Impact

In #111 the attacker is able to execute a remote transfer on behalf of any user, thus stealing their tokens.

In this issue the attacker is able to execute any cross-chain message on behalf of OFT contract. There might be two important results:

  1. DoS: The chain of messages is started on the source chain but never executed of the destination chain because the latter messages always revert due to invalid sender (e.g. trying to exercise option as OFT contract instead of the original sender).
  2. Abusing approvals: The attacker is able to steal any tokens that the user approved OFT contract for. It can simply initiate a remote transfer with OFT as the sender and victim of the owner of tokens.

Fix

In #111 the fis to change parameter of _internalRemoteTransferSendPacket function and it’s ready waiting in PR.

In this issue, the fix is in _lzCompose function (https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/gitmodule/tapioca-periph/contracts/tapiocaOmnichainEngine/TapiocaOmnichainReceiver.sol#L182). I cannot see any PR that.

sherlock-admin2 commented 3 months ago

Escalate

This issue is not duplicate of #111. Actually, the issue #111 is a dup of another issue I reported (#136).

This issue has different:

  • attack vector,
  • impact,
  • Fix.

Attack vector

In #111 the root cause is in _remoteTransferReceiver function:https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/gitmodule/tapioca-periph/contracts/tapiocaOmnichainEngine/TapiocaOmnichainReceiver.sol#L224). The sender of cross-chain message can make the recipient to initiate another cross-chain message (e.g. another remote transfer message).

In this issue (#135) the root cause lies in the _lzCompose function (https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/gitmodule/tapioca-periph/contracts/tapiocaOmnichainEngine/TapiocaOmnichainReceiver.sol#L182). That is, when the OFT contract executes a list of compose messages, the first is executed with the correct sender in srcChainSender_ parameter, and the rest of messages contain the address of OFT contract in the srcChainSender_ parameter (set in the line linked above).

The attacker can simply create a cross-chain call with more than one compose message where the first message is executed as intended and the rest have the OFT contract as the sender.

Impact

In #111 the attacker is able to execute a remote transfer on behalf of any user, thus stealing their tokens.

In this issue the attacker is able to execute any cross-chain message on behalf of OFT contract. There might be two important results:

  1. DoS: The chain of messages is started on the source chain but never executed of the destination chain because the latter messages always revert due to invalid sender (e.g. trying to exercise option as OFT contract instead of the original sender).
  2. Abusing approvals: The attacker is able to steal any tokens that the user approved OFT contract for. It can simply initiate a remote transfer with OFT as the sender and victim of the owner of tokens.

Fix

In #111 the fis to change parameter of _internalRemoteTransferSendPacket function and it’s ready waiting in PR.

In this issue, the fix is in _lzCompose function (https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/gitmodule/tapioca-periph/contracts/tapiocaOmnichainEngine/TapiocaOmnichainReceiver.sol#L182). I cannot see any PR that.

The escalation could not be created because you are not exceeding the escalation threshold.

You can view the required number of additional valid issues/judging contest payouts in your Profile page, in the Sherlock webapp.

damianrusinek commented 3 months ago

Escalate

This issue is not duplicate of https://github.com/sherlock-audit/2024-02-tapioca-judging/issues/111. Actually, the issue https://github.com/sherlock-audit/2024-02-tapioca-judging/issues/111 is a dup of another issue I reported (https://github.com/sherlock-audit/2024-02-tapioca-judging/issues/136).

This issue has different:

attack vector, impact, Fix. Attack vector

In https://github.com/sherlock-audit/2024-02-tapioca-judging/issues/111 the root cause is in _remoteTransferReceiver function:https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/gitmodule/tapioca-periph/contracts/tapiocaOmnichainEngine/TapiocaOmnichainReceiver.sol#L224). The sender of cross-chain message can make the recipient to initiate another cross-chain message (e.g. another remote transfer message).

In this issue (https://github.com/sherlock-audit/2024-02-tapioca-judging/issues/135) the root cause lies in the lzCompose function (https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/gitmodule/tapioca-periph/contracts/tapiocaOmnichainEngine/TapiocaOmnichainReceiver.sol#L182). That is, when the OFT contract executes a list of compose messages, the first is executed with the correct sender in srcChainSender parameter, and the rest of messages contain the address of OFT contract in the srcChainSender_ parameter (set in the line linked above).

The attacker can simply create a cross-chain call with more than one compose message where the first message is executed as intended and the rest have the OFT contract as the sender.

Impact

In https://github.com/sherlock-audit/2024-02-tapioca-judging/issues/111 the attacker is able to execute a remote transfer on behalf of any user, thus stealing their tokens.

In this issue the attacker is able to execute any cross-chain message on behalf of OFT contract. There might be two important results:

DoS: The chain of messages is started on the source chain but never executed of the destination chain because the latter messages always revert due to invalid sender (e.g. trying to exercise option as OFT contract instead of the original sender). Abusing approvals: The attacker is able to steal any tokens that the user approved OFT contract for. It can simply initiate a remote transfer with OFT as the sender and victim of the owner of tokens. Fix

In https://github.com/sherlock-audit/2024-02-tapioca-judging/issues/111 the fis to change parameter of _internalRemoteTransferSendPacket function and it’s ready waiting in PR.

In this issue, the fix is in _lzCompose function (https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/gitmodule/tapioca-periph/contracts/tapiocaOmnichainEngine/TapiocaOmnichainReceiver.sol#L182). I cannot see any PR that.

sherlock-admin2 commented 3 months ago

Escalate

This issue is not duplicate of https://github.com/sherlock-audit/2024-02-tapioca-judging/issues/111. Actually, the issue https://github.com/sherlock-audit/2024-02-tapioca-judging/issues/111 is a dup of another issue I reported (https://github.com/sherlock-audit/2024-02-tapioca-judging/issues/136).

This issue has different:

attack vector, impact, Fix. Attack vector

In https://github.com/sherlock-audit/2024-02-tapioca-judging/issues/111 the root cause is in _remoteTransferReceiver function:https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/gitmodule/tapioca-periph/contracts/tapiocaOmnichainEngine/TapiocaOmnichainReceiver.sol#L224). The sender of cross-chain message can make the recipient to initiate another cross-chain message (e.g. another remote transfer message).

In this issue (https://github.com/sherlock-audit/2024-02-tapioca-judging/issues/135) the root cause lies in the lzCompose function (https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/gitmodule/tapioca-periph/contracts/tapiocaOmnichainEngine/TapiocaOmnichainReceiver.sol#L182). That is, when the OFT contract executes a list of compose messages, the first is executed with the correct sender in srcChainSender parameter, and the rest of messages contain the address of OFT contract in the srcChainSender_ parameter (set in the line linked above).

The attacker can simply create a cross-chain call with more than one compose message where the first message is executed as intended and the rest have the OFT contract as the sender.

Impact

In https://github.com/sherlock-audit/2024-02-tapioca-judging/issues/111 the attacker is able to execute a remote transfer on behalf of any user, thus stealing their tokens.

In this issue the attacker is able to execute any cross-chain message on behalf of OFT contract. There might be two important results:

DoS: The chain of messages is started on the source chain but never executed of the destination chain because the latter messages always revert due to invalid sender (e.g. trying to exercise option as OFT contract instead of the original sender). Abusing approvals: The attacker is able to steal any tokens that the user approved OFT contract for. It can simply initiate a remote transfer with OFT as the sender and victim of the owner of tokens. Fix

In https://github.com/sherlock-audit/2024-02-tapioca-judging/issues/111 the fis to change parameter of _internalRemoteTransferSendPacket function and it’s ready waiting in PR.

In this issue, the fix is in _lzCompose function (https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/gitmodule/tapioca-periph/contracts/tapiocaOmnichainEngine/TapiocaOmnichainReceiver.sol#L182). I cannot see any PR that.

You've created a valid escalation!

To remove the escalation from consideration: Delete your comment.

You may delete or edit your escalation comment anytime before the 48-hour escalation window closes. After that, the escalation becomes final.

nevillehuang commented 3 months ago

This seems like a duplicate of #113, will need to review further. They are all very similar to each other.

cvetanovv commented 3 months ago

I agree with the escalations and @nevillehuang comment. We can deduplicate from #111 and duplicate with #113.

cvetanovv commented 3 months ago

Planning to accept the escalation and remove the duplication with #111, but duplicate with #113.

Evert0x commented 3 months ago

Result: High Duplicate of #113

sherlock-admin4 commented 3 months ago

Escalations have been resolved successfully!

Escalation status: