Flow

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

[H-3]Denial-of-Service (DoS) Attack via SVG Bloat in `tokenURI` Function of `FlowNFTDescriptor` Contract.

Summary:

The FlowNFTDescriptor contract, particularly its tokenURI function, contains a vulnerability that enables a Denial-of-Service (DoS) attack through SVG bloat. This exploit can be used by an attacker to disrupt access to NFT metadata, impacting users and applications relying on this contract.

Vulnerability Details:

1) SVG Content Length: The tokenURI function constructs a JSON string that includes an SVG image. If an attacker can control or excessively inflate the SVG content, they can create a scenario where the JSON string exceeds the maximum allowable gas limits for processing.

2) Memory Limits: During the execution of the tokenURI function, if the size of the SVG string becomes too large, it can lead to an Out of Gas (OOG) error, effectively preventing legitimate users from retrieving token metadata.

3) Denial-of-Service: This exploit can be used by an attacker to block access to the tokenURI function, rendering the NFT metadata inaccessible and thus disrupting the normal operation of the associated NFT marketplace or application.

Proof of Concept: The following Foundry test case demonstrates the vulnerability by overloading the SVG content to trigger an OOG error.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;
import "forge-std/src/Test.sol"; //change if the path doesn't match.
import "src/FlowNFTDescriptor.sol"; //change it if the path doesn't match.
import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
contract FlowNFTDescriptorTest is Test {
FlowNFTDescriptor descriptor;
function setUp() public {
descriptor = new FlowNFTDescriptor();
}
function testDoSAttackWithSvgBloat() public {
// Define a bloated SVG string to simulate DoS via excessive data
string memory largeSVG = "<svg>";
for (uint256 i = 0; i < 10_000; i++) {
largeSVG = string.concat(largeSVG, "<circle cx='50' cy='50' r='40' fill='blue' />");
}
largeSVG = string.concat(largeSVG, "</svg>");
// Overload `tokenURI` function in contract to accept the large SVG
(bool success,) = address(descriptor).call(abi.encodeWithSignature("tokenURIWithSVG(string)", largeSVG));
// Assert that calling with a bloated SVG fails due to out of gas
assertFalse(success, "The function did not fail with SVG bloat as expected");
}
}

Run the following command to get the result:

forge test --match-path tests/yourtestpath.t.sol -vvv

this will be the result:

Ran 1 test for tests/DoS.t.sol:FlowNFTDescriptorTest
\[FAIL: EvmError: MemoryLimitOOG] testDoSAttackWithSvgBloat() (gas: 9223372036854754743)
Traces:
\[34653696465] FlowNFTDescriptorTest::testDoSAttackWithSvgBloat()
└─ ← \[MemoryLimitOOG] EvmError: MemoryLimitOOG
Suite result: FAILED. 0 passed; 1 failed; 0 skipped; finished in 2.38s (2.38s CPU time)
Ran 1 test suite in 2.38s (2.38s CPU time): 0 tests passed, 1 failed, 0 skipped (1 total tests)
Failing tests:
Encountered 1 failing test in tests/DoS.t.sol:FlowNFTDescriptorTest
\[FAIL: EvmError: MemoryLimitOOG] testDoSAttackWithSvgBloat() (gas: 9223372036854754743)
Encountered a total of 1 failing tests, 0 tests succeeded

The failing test in this scenario proves that the FlowNFTDescriptor contract is vulnerable to a Denial of Service (DoS) attack through SVG bloat. Here’s how it demonstrates this vulnerability:

  1. Memory Limit Exceeded: The test attempts to generate an extremely large SVG string as input to the tokenURI function. This overloads the memory allocation during the execution of the function.

  2. Gas Limit: When the test fails with the MemoryLimitOOG (Out of Gas) error, it indicates that the function call requires more memory than the Ethereum Virtual Machine (EVM) allows for a single transaction. This is a direct consequence of trying to handle an excessively large payload (the bloated SVG).

  3. Denial of Service: Since the contract cannot successfully execute the tokenURI function due to the memory limitations, it effectively denies service for legitimate users. Anyone trying to retrieve the token URI for a valid NFT might encounter this issue if an attacker has already flooded the system with large SVGs, making it impractical to call this function without incurring high costs or failure.

Impact:

An attacker can exploit this vulnerability by submitting excessively large SVG payloads, thereby monopolizing computational resources. This could result in the failure of legitimate calls to the tokenURI function, effectively rendering the contract inoperable for all users attempting to retrieve NFT metadata.

Tools Used: Slither and Aderyn.

Recommendations:

1) Input Size Limitation:
Implement checks to limit the size of the SVG input that can be processed by the tokenURI function. For instance, you can set a maximum byte size for the SVG input and revert transactions that exceed this limit. This would prevent overly large SVG data from being processed and causing OOG errors.

2) Rate Limiting:
Introduce rate limiting mechanisms to control how frequently users can call the tokenURI function. This can help prevent a single user from overwhelming the contract with excessive requests, thus reducing the risk of DoS attacks.

3) Fallback Mechanism:
Implement a fallback mechanism that can handle failures in the tokenURI function gracefully. If the function fails due to memory limits or excessive gas consumption, consider returning a default or cached response that indicates the metadata instead of failing completely.

Updates

Lead Judging Commences

inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Too generic
inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Too generic

Support

FAQs

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