The vote API route (POST /api/v1/forum/vote) trusts the JSON body’s direction value without runtime validation. TypeScript types are not enforced at runtime, so an attacker can send arbitrary strings (e.g., "x") as direction. Downstream (VoteServer) treats any non-"up" and non-null value as a downvote and persists the invalid value in votes_data. This can be exploited to bypass intended business logic.
Exploitation
An authenticated attacker can repeatedly alternate requests to manipulate vote counts:
POST /api/v1/forum/vote with { "postId": "<victim>", "direction": "x" } (decrements votes by 1)
POST /api/v1/forum/vote with { "postId": "<victim>", "direction": null } (removes the recorded vote but does not restore the vote count due to the invalid stored value)
Repeating this cycle allows a single user to indefinitely decrease a post’s vote count while bypassing normal per-user vote tracking.
Impact
- Integrity loss for forum rankings and vote-based reputation systems.
- Business logic can be bypassed, allowing unauthorized manipulation of post scores.
Recommendations
- Implement strict runtime validation of the
direction field to only accept "up", "down", or null; reject all other values with HTTP 400.
- Validate
postId format/length (e.g., UUID) before passing it to VoteServer.
- Harden downstream logic in
VoteServer to treat any unknown stored vote as null and avoid persisting unexpected values.
Impacted Code
const body: VoteRequestBody = await request.json()
const { postId, direction } = body
// Call the existing server action
const result = await VoteServer(postId, direction)
References
The vote API route (
POST /api/v1/forum/vote) trusts the JSON body’sdirectionvalue without runtime validation. TypeScript types are not enforced at runtime, so an attacker can send arbitrary strings (e.g.,"x") asdirection. Downstream (VoteServer) treats any non-"up"and non-nullvalue as a downvote and persists the invalid value invotes_data. This can be exploited to bypass intended business logic.Exploitation
An authenticated attacker can repeatedly alternate requests to manipulate vote counts:
POST /api/v1/forum/votewith{ "postId": "<victim>", "direction": "x" }(decrements votes by 1)POST /api/v1/forum/votewith{ "postId": "<victim>", "direction": null }(removes the recorded vote but does not restore the vote count due to the invalid stored value)Repeating this cycle allows a single user to indefinitely decrease a post’s vote count while bypassing normal per-user vote tracking.
Impact
Recommendations
directionfield to only accept"up","down", ornull; reject all other values with HTTP 400.postIdformat/length (e.g., UUID) before passing it toVoteServer.VoteServerto treat any unknown stored vote asnulland avoid persisting unexpected values.Impacted Code
References