CVE-2026-25758 Overview
CVE-2026-25758 is a critical Insecure Direct Object Reference (IDOR) vulnerability discovered in Spree Commerce, an open source e-commerce solution built with Ruby on Rails. This vulnerability exists in Spree's guest checkout flow and allows any guest user to bind arbitrary guest addresses to their order by manipulating address ID parameters during the checkout process.
The flaw enables unauthorized access to other guests' personally identifiable information (PII) including names, physical addresses, and phone numbers. The vulnerability effectively bypasses existing ownership validation checks and affects all guest checkout transactions across vulnerable Spree Commerce installations.
Critical Impact
Attackers can exploit this IDOR vulnerability to harvest sensitive PII data from other guest users' addresses, potentially leading to identity theft, targeted phishing attacks, or regulatory compliance violations under data protection laws such as GDPR and CCPA.
Affected Products
- Spree Commerce versions prior to 4.10.3
- Spree Commerce versions 5.0.x prior to 5.0.8
- Spree Commerce versions 5.1.x prior to 5.1.10
- Spree Commerce versions 5.2.x prior to 5.2.7
- Spree Commerce versions 5.3.x prior to 5.3.2
Discovery Timeline
- February 6, 2026 - CVE-2026-25758 published to NVD
- February 9, 2026 - Last updated in NVD database
Technical Details for CVE-2026-25758
Vulnerability Analysis
This IDOR vulnerability stems from improper access control implementation in the address book functionality of Spree Commerce's guest checkout flow. The vulnerability is classified under CWE-284 (Improper Access Control), which encompasses failures to properly restrict access to resources from unauthorized actors.
The core issue lies in how Spree Commerce handles address ID assignments during the checkout process. When a guest user submits an order, they can manipulate the bill_address_id or ship_address_id parameters to reference addresses belonging to other guest users. The existing validation logic failed to properly verify ownership when the order's user_id was nil (as is the case with guest checkouts).
This vulnerability is exploitable over the network without requiring authentication, making it particularly dangerous for e-commerce platforms with high guest checkout volumes. Successful exploitation results in unauthorized disclosure of confidential PII data without affecting system integrity or availability.
Root Cause
The root cause of CVE-2026-25758 lies in the bill_address_id= and ship_address_id= setter methods within the Spree::Order::AddressBook module. The original validation logic checked if address.user_id == user_id, but this comparison failed to account for scenarios where both values are nil (guest users).
When user_id is nil for a guest order and address.user_id is also nil for a guest address, the comparison nil == nil evaluates to true, allowing any guest address to be bound to any guest order. This logic flaw meant the ownership validation was effectively bypassed for all guest checkout transactions.
Attack Vector
The attack can be executed by any guest user during the checkout process. An attacker initiates a guest checkout on a vulnerable Spree Commerce store and intercepts the address submission request. By modifying the bill_address_id or ship_address_id parameters to sequential or enumerated address IDs, the attacker can bind addresses belonging to other guest users to their order.
Upon successful manipulation, the attacker's order displays the victim's address information including full name, street address, city, state, postal code, country, and phone number. This can be automated to enumerate and harvest large volumes of PII data from the e-commerce platform.
# Security patch in core/app/models/spree/order/address_book.rb
# Source: https://github.com/spree/spree/commit/15619618e43b367617ec8d2d4aafc5e54fa7b734
end
def bill_address_id=(id)
+ return if bill_address_id == id
+
address = Spree::Address.find_by(id: id)
- if address && address.user_id == user_id
+ # rubocop:disable Style/ConditionalAssignment
+ if address && user_id.present? && address.user_id == user_id
self['bill_address_id'] = address.id
- bill_address.reload
else
self['bill_address_id'] = nil
end
+ # rubocop:enable Style/ConditionalAssignment
+ reset_bill_address
end
def bill_address_attributes=(attributes)
The patch adds a critical check using user_id.present? which ensures that address ID binding only occurs when a valid user is associated with the order. For guest checkouts (where user_id is nil), the address ID is set to nil, forcing guests to provide new address information rather than reference existing addresses.
Detection Methods for CVE-2026-25758
Indicators of Compromise
- Unusual patterns of address ID references in checkout requests where guest orders reference pre-existing address IDs
- Multiple orders from different sessions binding to the same address ID values
- Sequential or enumerated address ID values appearing in checkout API requests
- Error logs indicating address lookup failures followed by successful bindings to different addresses
Detection Strategies
- Implement web application firewall (WAF) rules to detect and block requests with manipulated address ID parameters during guest checkout
- Monitor application logs for checkout requests where guest users attempt to reference existing address records
- Set up anomaly detection for API endpoints related to /checkout/update that process address parameters
- Review database query logs for address lookups performed during guest checkout sessions
Monitoring Recommendations
- Enable detailed logging on address assignment operations within the Spree Order model
- Configure alerting for high volumes of address ID enumeration attempts from single IP addresses or sessions
- Monitor for unusual data access patterns where guest checkout sessions retrieve address data they did not create
- Implement rate limiting on checkout API endpoints to slow enumeration attacks
How to Mitigate CVE-2026-25758
Immediate Actions Required
- Upgrade Spree Commerce to a patched version immediately: 4.10.3, 5.0.8, 5.1.10, 5.2.7, or 5.3.2
- Review server logs for historical evidence of address ID manipulation attempts
- Conduct a data breach assessment if exploitation is suspected, as PII may have been compromised
- Notify affected users and relevant data protection authorities if required by applicable regulations
Patch Information
Spree Commerce has released security patches across all supported version branches. The fix adds proper ownership validation that explicitly requires a non-nil user_id before allowing address ID binding. Organizations should upgrade to the following fixed versions:
| Branch | Fixed Version |
|---|---|
| 4.10.x | 4.10.3 |
| 5.0.x | 5.0.8 |
| 5.1.x | 5.1.10 |
| 5.2.x | 5.2.7 |
| 5.3.x | 5.3.2 |
For detailed patch information, refer to the GitHub Security Advisory GHSA-87fh-rc96-6fr6.
Workarounds
- If immediate patching is not possible, disable guest checkout functionality temporarily until the upgrade can be applied
- Implement a custom middleware or controller filter to strip address ID parameters from guest checkout requests
- Deploy WAF rules to block checkout requests containing bill_address_id or ship_address_id parameters when no user session is authenticated
- Consider implementing additional server-side validation to verify address ownership before binding
# Configuration example - Nginx WAF rule to block address ID manipulation
# Add to your Nginx configuration for temporary mitigation
location ~ /checkout {
# Block requests with address_id parameters from guest sessions
if ($arg_order[bill_address_id] ~ ".+") {
set $block_check "A";
}
if ($cookie_guest_token ~ ".+") {
set $block_check "${block_check}B";
}
if ($block_check = "AB") {
return 403;
}
# Continue with normal proxy configuration
proxy_pass http://spree_backend;
}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

