Race Condition Allows Multiple Upvotes on Plugins

linkResolution: ❌

Not a security bug

Not considered for fix

Easily detectable

Mitigated by admin moderation tools


linkReport

Summary
A race condition vulnerability allows a user to bypass the intended one-vote-per-user restriction on plugins. By sending multiple concurrent vote requests to the vote endpoint, the same account can successfully cast multiple votes for a single plugin, artificially increasing its vote count.
 
Vulnerability Type
Race Condition
 
Business Logic Bypass
 
Vote Manipulation
 
Affected URL
https://www.amplenote.com/plugins/SjZGNPZBvRq42xpfD6u8CbHT
Affected Endpoint
POST /plugins/SjZGNPZBvRq42xpfD6u8CbHT/cast_vote
Description
The plugin marketplace allows users to vote for plugins, with the intended behavior being that each account may cast only one vote per plugin.
 
During testing, I discovered that the voting functionality is vulnerable to a race condition. When multiple cast_vote requests are sent concurrently, several requests pass the server-side validation before the user's voting state is updated.
 
As a result, multiple votes from the same account are recorded for a single plugin.
 
In my testing:
 
The plugin initially had 13 votes.
 
I sent approximately 10 concurrent requests.
 
The plugin's vote count increased by 4 votes from my single account.
 
Although not every concurrent request succeeds, several are processed successfully. Repeating the attack with a larger number of concurrent requests (e.g., 100+) results in additional votes being registered, demonstrating that the one-vote-per-user restriction can be bypassed repeatedly.
 
Steps to Reproduce
Log in to an Amplenote account.
 
Visit the plugin page:
 
https://www.amplenote.com/plugins/SjZGNPZBvRq42xpfD6u8CbHT
Click Vote and intercept the request.
 
Capture the following request:
 
POST /plugins/SjZGNPZBvRq42xpfD6u8CbHT/cast_vote
Example request body:
 
_method=post&authenticity_token=<valid_token>
Send multiple identical requests simultaneously using Burp Suite Repeater (Parallel Send) or Turbo Intruder.
 
Observe that several requests are accepted successfully.
 
Refresh the plugin page.
 
Observe that the vote count has increased by more than one, despite all requests originating from the same authenticated account.
 
Proof of Concept
Initial state
 
Plugin votes: 13
Attack
 
Approximately 10 concurrent POST requests to:
 
POST /plugins/SjZGNPZBvRq42xpfD6u8CbHT/cast_vote
Observed Result
 
Plugin votes: 17
The same account successfully added 4 additional votes.
 
Increasing the number of concurrent requests further results in additional votes being counted, although not every request succeeds due to the timing of the race condition.
 
Impact
An attacker can manipulate the plugin voting system by artificially inflating vote counts, which may result in:
 
Unfair promotion of plugins.
 
Manipulation of plugin rankings and popularity metrics.
 
Reduced trust in community-driven voting.
 
Automated vote inflation using concurrent requests.
 
Potential influence over plugin visibility if rankings are based on vote totals.
 
Root Cause
The application validates whether a user has already voted before recording the vote, but these operations are not performed atomically. Multiple concurrent requests complete the validation before the voting state is updated, allowing duplicate votes from the same account.
 
Remediation
Process vote validation and vote creation within a single database transaction.
 
Enforce a database uniqueness constraint (e.g., user_id + plugin_id) so that only one vote can exist per user for each plugin.
 
Apply row-level locking or equivalent synchronization during vote processing.
 
Revalidate the user's voting status immediately before committing the transaction.
 
CWE
CWE-362 Concurrent Execution using Shared Resource with Improper Synchronization (Race Condition)
 
Severity
Medium
 
This issue compromises the integrity of the plugin voting system by allowing a single account to cast multiple votes through concurrent requests. If plugin rankings or recommendations rely on vote counts, attackers can unfairly influence visibility and popularity, undermining the credibility of the platform's voting mechanism.