An unauthenticated user can approve any pending affiliate request by sending a GET request to /affiliate_requests/:id/approve with a valid external_id. The set_affiliate_request before_action fetches the AffiliateRequest object based on the user-supplied ID without checking if the user is authorized to approve it. The approve action is excluded from the authenticate_user! before_action and the can_perform_action? check only verifies the state of the request, not the user's permissions.
File: app/controllers/affiliate_requests_controller.rb
Route: GET /affiliate_requests/:id/approve
Vulnerable Code:
before_action :set_affiliate_request, only: %i[approve ignore] (line 12)
set_affiliate_request method (lines 111-113) uses AffiliateRequest.find_by_external_id!(params[:id])
approve action (lines 63-74) calls perform_action_if_permitted which checks state but not user authorization.
approve is in PUBLIC_ACTIONS (line 6), bypassing authentication.
Impact: Allows unauthenticated attackers to approve any pending affiliate request if they know or can guess the external_id.
Reproduction Steps:
- Obtain the
external_id of a pending affiliate request.
- Send a GET request to
/affiliate_requests/:id/approve with the obtained ID.
- The request is approved without authentication or authorization check.
Recommendation: Implement proper authorization in the approve action to ensure only the legitimate seller associated with the affiliate request can approve it. This should likely involve checking current_user and scoping the AffiliateRequest lookup under the seller, e.g., current_user.affiliate_requests.find_by_external_id!(params[:id]) or using a proper authorization library like Pundit or Cancancan.
An unauthenticated user can approve any pending affiliate request by sending a GET request to
/affiliate_requests/:id/approvewith a validexternal_id. Theset_affiliate_requestbefore_action fetches theAffiliateRequestobject based on the user-supplied ID without checking if the user is authorized to approve it. Theapproveaction is excluded from theauthenticate_user!before_action and thecan_perform_action?check only verifies the state of the request, not the user's permissions.File:
app/controllers/affiliate_requests_controller.rbRoute:
GET /affiliate_requests/:id/approveVulnerable Code:
before_action :set_affiliate_request, only: %i[approve ignore](line 12)set_affiliate_requestmethod (lines 111-113) usesAffiliateRequest.find_by_external_id!(params[:id])approveaction (lines 63-74) callsperform_action_if_permittedwhich checks state but not user authorization.approveis inPUBLIC_ACTIONS(line 6), bypassing authentication.Impact: Allows unauthenticated attackers to approve any pending affiliate request if they know or can guess the
external_id.Reproduction Steps:
external_idof a pending affiliate request./affiliate_requests/:id/approvewith the obtained ID.Recommendation: Implement proper authorization in the
approveaction to ensure only the legitimate seller associated with the affiliate request can approve it. This should likely involve checkingcurrent_userand scoping theAffiliateRequestlookup under the seller, e.g.,current_user.affiliate_requests.find_by_external_id!(params[:id])or using a proper authorization library like Pundit or Cancancan.