Summary
LevelOne::giveReview function lacks InSession check, causing teacher can give Review every week to student before the session start.causing malicious teacher decrease the score of students.And the reviewCount variable is always zero ,so that the check of reviewCount is not useful,resulting in score can be review to zero maliciously.
Vulnerability Details
function giveReview(address _student, bool review) public onlyTeacher {
if (!isStudent[_student]) {
revert HH__StudentDoesNotExist();
}
require(reviewCount[_student] < 5, "Student review count exceeded!!!");
require(block.timestamp >= lastReviewTime[_student] + reviewTime, "Reviews can only be given once per week");
if (!review) {
studentScore[_student] -= 10;
}
lastReviewTime[_student] = block.timestamp;
emit ReviewGiven(_student, review, studentScore[_student]);
}
step:
alice givereview to harriet false score every week.
function test_confirm_can_give_review() public schoolInSession {
vm.warp(block.timestamp + 1 weeks);
vm.prank(alice);
levelOneProxy.giveReview(harriet, false);
console2.log("harriet reviewCount", levelOneProxy.reviewCount(harriet));
vm.warp(block.timestamp + 1 weeks);
vm.prank(alice);
levelOneProxy.giveReview(harriet, false);
console2.log("harriet reviewCount", levelOneProxy.reviewCount(harriet));
vm.warp(block.timestamp + 1 weeks);
vm.prank(alice);
levelOneProxy.giveReview(harriet, false);
console2.log("harriet reviewCount", levelOneProxy.reviewCount(harriet));
vm.warp(block.timestamp + 1 weeks);
vm.prank(alice);
levelOneProxy.giveReview(harriet, false);
console2.log("harriet reviewCount", levelOneProxy.reviewCount(harriet));
vm.warp(block.timestamp + 1 weeks);
vm.prank(alice);
levelOneProxy.giveReview(harriet, false);
console2.log("harriet reviewCount", levelOneProxy.reviewCount(harriet));
vm.warp(block.timestamp + 1 weeks);
vm.prank(alice);
levelOneProxy.giveReview(harriet, false);
console2.log("harriet reviewCount", levelOneProxy.reviewCount(harriet));
assert(levelOneProxy.studentScore(harriet) == 40);
}
Impact
the check of reviewCount is not useful,resulting in score can be review to zero maliciously.
Tools Used
foundry
Recommendationsfunction
function giveReview(address _student, bool review) public onlyTeacher {
if (!isStudent[_student]) {
revert HH__StudentDoesNotExist();
}
+ if (inSession == false) {
+ revert();
+ }
require(reviewCount[_student] < 5, "Student review count exceeded!!!");
require(block.timestamp >= lastReviewTime[_student] + reviewTime, "Reviews can only be given once per week");
+ reviewCount[_student]++;
// where `false` is a bad review and true is a good review
if (!review) {
studentScore[_student] -= 10;
}
// Update last review time
lastReviewTime[_student] = block.timestamp;
emit ReviewGiven(_student, review, studentScore[_student]);
}