Flow

Sablier
FoundryDeFi
20,000 USDC
View results
Submission Details
Severity: high
Invalid

Lack of Access Control in void Function

Summary

https://github.com/Cyfrin/2024-10-sablier/blob/main/src/SablierFlow.sol

The void function in the contract is publicly accessible, allowing any external user to void any stream by simply calling the function with a valid streamId. Without access control restrictions, unauthorized users can disrupt the intended functionality of the contract by voiding streams they don’t own or control. This poses a significant security risk as it can lead to Denial of Service (DoS) attacks, arbitrary cancellations, and loss of confidence in the contract's integrity.

Vulnerability Code

function void(uint256 streamId)externaloverridenoDelegateCallnotNull(streamId)notVoided(streamId)updateMetadata(streamId){// Checks, Effects, and Interactions: void the stream._void(streamId);}

Impact

Denial of Service: Any user can void any stream, preventing rightful owners from continuing to use the stream.

  • Disruption of Business Logic: Unauthorized voiding could disrupt workflows or automated processes that rely on the integrity of active streams.

  • Potential Financial Losses: If streams involve financial transactions or tokens, unauthorized voiding could result in loss of funds, which would be critical in contracts involving payment stream

The following PoC demonstrates how an unauthorized user can void a stream they do not own:

  1. Setup: Assume there is a deployed instance of the contract, and streamId 1001 belongs to Alice.

  2. Malicious User Action:

    ```

// Deploy this PoC script as an external contract or execute it via a testing framework like Hardhat
await contractInstance.void(1001, { from: attackerAddress });

3.Result:

  • The void function will execute successfully from attackerAddress, voiding streamId 1001 despite the attacker having no permissions over this stream.

Severity Justification

The severity is rated as High due to the following reasons:

  • Ease of Exploitation: Any user can call the function without needing special permissions or elevated privileges.

  • Impact on Integrity: Unrestricted voiding affects the integrity and reliability of the contract, especially if the streams are part of core business logic or financial transactions.

  • Financial Impact: In cases where streams involve value transfers, unauthorized voiding could directly lead to financial losses.

Tools Used

Recommendations

To resolve this issue, implement an access control modifier to restrict access to the void function. Here are two possible approaches:

  1. Ownership Check: Add a check to ensure only the stream owner can void it:

modifier onlyStreamOwner(uint256 streamId) {
require(msg.sender == streamOwner[streamId], "Caller is not the stream owner");
_;
}
function void(uint256 streamId)
external
override
noDelegateCall
notNull(streamId)
notVoided(streamId)
updateMetadata(streamId)
onlyStreamOwner(streamId)
{
_void(streamId);
}

2.Role-based Access Control: For a more flexible setup, use role-based access, ensuring only authorized roles (e.g., STREAM_MANAGER_ROLE) can void streams:

function void(uint256 streamId)
external
override
noDelegateCall
notNull(streamId)
notVoided(streamId)
updateMetadata(streamId)
onlyRole(STREAM_MANAGER_ROLE)
{
_void(streamId);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge
10 months ago
inallhonesty Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
inallhonesty Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.