Beginner FriendlyFoundryNFT
100 EXP
View results
Submission Details
Severity: high
Invalid

Misusing the `external` keyword in `Soulmate::readMessageInSharedSpace` function risks privacy breaches for couples, letting malicious users read their messages.

Description: The provided function Soulmate::readMessageInSharedSpace is intended to allow registered couples to read messages shared between them using the Soulmate Token. However, a crucial flaw exists in the visibility keyword external which means that anyone, not just the registered couples, can call this function. This design oversight leads to a significant privacy concern.

function readMessageInSharedSpace() @> external view returns (string memory) {
return string.concat(sharedSpace[ownerToId[msg.sender]], ", ", niceWords[block.timestamp % niceWords.length]);
}

Impact: The malicious user gains unauthorized access to sensitive information, potentially using it for blackmail, harassment, or other malicious activities. This breach damages user trust and reputation, leading to a loss of confidence in the platform.

Proof of Concept:

  1. Have registered couples send messages to each other through the Soulmate::writeMessageInSharedSpace function. These messages should be stored in the Soulmate::sharedSpace mapping within the Protocol.

  2. The malicious user discovers the visibility issue and exploits it by using their unauthorized account to call the Soulmate::readMessageInSharedSpace function.

  3. The malicious user retrieves and logs the messages returned by the function, exploiting the vulnerability to access private communications between registered couples.

Proof Of Code

Place the following into the SoulmateTest.t.sol.

function test_MaliciousUserCanReadMessagesInSharedSpacefromRegisteredCouples() public {
// Both Soulmate 1 and 2 are the registered Couples
vm.prank(soulmate1);
soulmateContract.mintSoulmateToken();
vm.prank(soulmate2);
soulmateContract.mintSoulmateToken();
///////////////////////////////////////////////////////////////////
vm.prank(soulmate1);
soulmateContract.writeMessageInSharedSpace("Buy some eggs");
// A malicious address comes in the picture to read what Soulmate 1 has sent to Soulmate 2
vm.prank(maliciousUser);
string memory message = soulmateContract.readMessageInSharedSpace();
string[4] memory possibleText =
["Buy some eggs, sweetheart", "Buy some eggs, darling", "Buy some eggs, my dear", "Buy some eggs, honey"];
bool found;
for (uint256 i; i < possibleText.length; i++) {
if (compare(possibleText[i], message)) {
found = true;
break;
}
}
console2.log(message);
assertTrue(found);
////////////////////////////////////////////////////////////////////////////////
}

Recommended Mitigation: Change the visibility keyword from external to internal or private to restrict access to the function within the contract scope.

Or,

Introduce access control mechanisms such as the use of a modifier as shown below, to ensure that only authorized users, such as registered couples with valid Soulmate Tokens, can access the Soulmate::readMessageInSharedSpacefunction.

- function writeMessageInSharedSpace(string calldata message) external {
- uint256 id = ownerToId[msg.sender];
- sharedSpace[id] = message;
- emit MessageWrittenInSharedSpace(id, message);
- }
- function readMessageInSharedSpace() external view returns (string memory) {
- return string.concat(sharedSpace[ownerToId[msg.sender]], ", ", niceWords[block.timestamp % niceWords.length]);
- }
+ modifier onlyRegisteredCouple() {
+ require(soulmateOf[msg.sender] != address(0), "Soulmate__UnauthorizedAccess");
+ _;
+ }
+ function writeMessageInSharedSpace(string calldata message) external onlyRegisteredCouple {
+ uint256 id = ownerToId[msg.sender];
+ sharedSpace[id] = message;
+ emit MessageWrittenInSharedSpace(id, message);
+ }
+ function readMessageInSharedSpace() external view returns (string memory) onlyRegisteredCouple {
+ return string.concat(sharedSpace[ownerToId[msg.sender]], ", ", niceWords[block.timestamp % niceWords.length]);
+ }
Updates

Lead Judging Commences

0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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