Skip to content

fix(reputation): reject future-dated caller-supplied timestamps - #1232

Merged
Emeka000 merged 2 commits into
Emeka000:mainfrom
samuel2926i39-art:fix/reputation-timestamp-validation
Jul 26, 2026
Merged

fix(reputation): reject future-dated caller-supplied timestamps#1232
Emeka000 merged 2 commits into
Emeka000:mainfrom
samuel2926i39-art:fix/reputation-timestamp-validation

Conversation

@samuel2926i39-art

Copy link
Copy Markdown

Summary

submit_rating, record_assignment, and flag_fraud in the reputation contract now reject caller-supplied timestamps that lie in the future relative to ledger time, closing a way to permanently manipulate recency weighting and inactivity decay.

Context / before-after

  • Before: These functions took a raw timestamp: u64 argument and stored it directly (RatingEvent.timestamp, last_active_at) with no bounds check against env.ledger().timestamp(). weighted_rating_score and decay_penalty key their weighting purely off this attacker-controlled value - a far-future timestamp made age = now.saturating_sub(r.timestamp) evaluate to 0, guaranteeing max recency weight (2x) forever, and setting last_active_at far in the future permanently defeated the inactivity-decay penalty.
  • After: Added require_valid_timestamp(env, timestamp), which rejects (Error::InvalidInput) any timestamp greater than current ledger time. Wired into submit_rating, record_assignment, and flag_fraud; update_from_event inherits the check since it delegates to those two.

Testing

cargo test -p reputation-contract - 54 passed, 0 failed. Fixed 6 existing tests that called these functions with a literal timestamp without advancing the mock ledger to match (they now set env.ledger().with_mut(...) first, matching realistic usage). Added 4 new tests: future-timestamp rejection for submit_rating, record_assignment, and flag_fraud, plus one confirming a timestamp equal to current ledger time is still accepted.

Closes #1128

mac and others added 2 commits July 26, 2026 04:16
submit_rating, record_assignment, and flag_fraud stored a raw
caller-supplied timestamp with no bounds validation. weighted_rating_score
and decay_penalty key their weighting purely off this value, so a
far-future timestamp gave permanent maximum recency weight and defeated
inactivity decay entirely.

Adds require_valid_timestamp, which rejects any timestamp greater than
the current ledger time (Error::InvalidInput). Applied to all three
write paths; update_from_event inherits the check since it delegates
to record_assignment/flag_fraud.
@Emeka000
Emeka000 merged commit bb407f9 into Emeka000:main Jul 26, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

reputation: rating/assignment functions trust a caller-supplied timestamp with no bounds validation

2 participants