CVE-2013-1656
Description
Spree Commerce 1.0.x through 1.3.2 allows remote authenticated administrators to instantiate arbitrary Ruby objects and execute arbitrary commands via the (1) payment_method parameter to core/app/controllers/spree/admin/payment_methods_controller.rb; and the (2) promotion_action parameter to promotion_actions_controller.rb, (3) promotion_rule parameter to promotion_rules_controller.rb, and (4) calculator_type parameter to promotions_controller.rb in promo/app/controllers/spree/admin/, related to unsafe use of the constantize function.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
spreeRubyGems | >= 1.0.0, < 2.0.0.rc1 | 2.0.0.rc1 |
Affected products
23cpe:2.3:a:spreecommerce:spree:*:*:*:*:*:*:*:*+ 22 more
- cpe:2.3:a:spreecommerce:spree:*:*:*:*:*:*:*:*range: <=1.3.2
- cpe:2.3:a:spreecommerce:spree:1.0.0:*:*:*:*:*:*:*
- cpe:2.3:a:spreecommerce:spree:1.0.1:*:*:*:*:*:*:*
- cpe:2.3:a:spreecommerce:spree:1.0.2:*:*:*:*:*:*:*
- cpe:2.3:a:spreecommerce:spree:1.0.3:*:*:*:*:*:*:*
- cpe:2.3:a:spreecommerce:spree:1.0.4:*:*:*:*:*:*:*
- cpe:2.3:a:spreecommerce:spree:1.0.5:*:*:*:*:*:*:*
- cpe:2.3:a:spreecommerce:spree:1.0.6:*:*:*:*:*:*:*
- cpe:2.3:a:spreecommerce:spree:1.0.7:*:*:*:*:*:*:*
- cpe:2.3:a:spreecommerce:spree:1.1.0:*:*:*:*:*:*:*
- cpe:2.3:a:spreecommerce:spree:1.1.1:*:*:*:*:*:*:*
- cpe:2.3:a:spreecommerce:spree:1.1.2:*:*:*:*:*:*:*
- cpe:2.3:a:spreecommerce:spree:1.1.3:*:*:*:*:*:*:*
- cpe:2.3:a:spreecommerce:spree:1.1.4:*:*:*:*:*:*:*
- cpe:2.3:a:spreecommerce:spree:1.1.5:*:*:*:*:*:*:*
- cpe:2.3:a:spreecommerce:spree:1.1.6:*:*:*:*:*:*:*
- cpe:2.3:a:spreecommerce:spree:1.2.0:*:*:*:*:*:*:*
- cpe:2.3:a:spreecommerce:spree:1.2.1:*:*:*:*:*:*:*
- cpe:2.3:a:spreecommerce:spree:1.2.2:*:*:*:*:*:*:*
- cpe:2.3:a:spreecommerce:spree:1.2.3:*:*:*:*:*:*:*
- cpe:2.3:a:spreecommerce:spree:1.2.4:*:*:*:*:*:*:*
- cpe:2.3:a:spreecommerce:spree:1.3.0:*:*:*:*:*:*:*
- cpe:2.3:a:spreecommerce:spree:1.3.1:*:*:*:*:*:*:*
Patches
170092eb55b8bFix unsafe constantize calls in admin controllers
9 files changed · +113 −19
backend/app/controllers/spree/admin/payment_methods_controller.rb+9 −0 modified@@ -3,6 +3,7 @@ module Admin class PaymentMethodsController < ResourceController skip_before_filter :load_resource, :only => [:create] before_filter :load_data + before_filter :validate_payment_method_provider, :only => :create respond_to :html @@ -50,6 +51,14 @@ def update def load_data @providers = Gateway.providers.sort{|p1, p2| p1.name <=> p2.name } end + + def validate_payment_method_provider + valid_payment_methods = Rails.application.config.spree.payment_methods.map(&:to_s) + if !valid_payment_methods.include?(params[:payment_method][:type]) + flash[:error] = t(:invalid_payment_provider) + redirect_to new_admin_payment_method_path + end + end end end end
backend/app/controllers/spree/admin/promotion_actions_controller.rb+20 −2 modified@@ -1,7 +1,9 @@ class Spree::Admin::PromotionActionsController < Spree::Admin::BaseController + before_filter :load_promotion, :only => [:create, :destroy] + before_filter :validate_promotion_action_type, :only => :create + def create @calculators = Spree::Promotion::Actions::CreateAdjustment.calculators - @promotion = Spree::Promotion.find(params[:promotion_id]) @promotion_action = params[:action_type].constantize.new(params[:promotion_action]) @promotion_action.promotion = @promotion if @promotion_action.save @@ -14,7 +16,6 @@ def create end def destroy - @promotion = Spree::Promotion.find(params[:promotion_id]) @promotion_action = @promotion.promotion_actions.find(params[:id]) if @promotion_action.destroy flash[:success] = I18n.t(:successfully_removed, :resource => I18n.t(:promotion_action)) @@ -24,4 +25,21 @@ def destroy format.js { render :layout => false } end end + + private + + def load_promotion + @promotion = Spree::Promotion.find(params[:promotion_id]) + end + + def validate_promotion_action_type + valid_promotion_action_types = Rails.application.config.spree.promotions.actions.map(&:to_s) + if !valid_promotion_action_types.include?(params[:action_type]) + flash[:error] = t(:invalid_promotion_action) + respond_to do |format| + format.html { redirect_to spree.edit_admin_promotion_path(@promotion)} + format.js { render :layout => false } + end + end + end end
backend/app/controllers/spree/admin/promotion_rules_controller.rb+20 −2 modified@@ -1,8 +1,10 @@ class Spree::Admin::PromotionRulesController < Spree::Admin::BaseController helper 'spree/promotion_rules' + before_filter :load_promotion, :only => [:create, :destroy] + before_filter :validate_promotion_rule_type, :only => :create + def create - @promotion = Spree::Promotion.find(params[:promotion_id]) # Remove type key from this hash so that we don't attempt # to set it when creating a new record, as this is raises # an error in ActiveRecord 3.2. @@ -19,7 +21,6 @@ def create end def destroy - @promotion = Spree::Promotion.find(params[:promotion_id]) @promotion_rule = @promotion.promotion_rules.find(params[:id]) if @promotion_rule.destroy flash[:success] = I18n.t(:successfully_removed, :resource => I18n.t(:promotion_rule)) @@ -29,4 +30,21 @@ def destroy format.js { render :layout => false } end end + + private + + def load_promotion + @promotion = Spree::Promotion.find(params[:promotion_id]) + end + + def validate_promotion_rule_type + valid_promotion_rule_types = Rails.application.config.spree.promotions.rules.map(&:to_s) + if !valid_promotion_rule_types.include?(params[:promotion_rule][:type]) + flash[:error] = t(:invalid_promotion_rule) + respond_to do |format| + format.html { redirect_to spree.edit_admin_promotion_path(@promotion)} + format.js { render :layout => false } + end + end + end end
backend/app/controllers/spree/admin/promotions_controller.rb+0 −13 modified@@ -5,19 +5,6 @@ class PromotionsController < ResourceController helper 'spree/promotion_rules' protected - def build_resource - if params[:promotion] - calculator_type = params[:promotion].delete(:calculator_type) - @promotion = Promotion.new(params[:promotion]) - if calculator_type - @promotion.calculator = calculator_type.constantize.new - end - else - @promotion = Promotion.new - end - @promotion - end - def location_after_save spree.edit_admin_promotion_url(@promotion) end
backend/spec/controllers/spree/admin/payment_methods_controller_spec.rb+18 −1 modified@@ -17,12 +17,29 @@ module Spree # regression test for #2094 it "does not clear password on update" do payment_method.preferred_password.should == "haxme" - spree_put :update, :id => payment_method.id, :payment_method => { :type => payment_method.class.to_s, :preferred_password => "" } + spree_put :update, :id => payment_method.id, :payment_method => { :type => payment_method.class.to_s, :preferred_password => "" } response.should redirect_to(spree.edit_admin_payment_method_path(payment_method)) payment_method.reload payment_method.preferred_password.should == "haxme" end + it "can create a payment method of a valid type" do + expect { + spree_post :create, :payment_method => { :name => "Test Method", :type => "Spree::Gateway::Bogus" } + }.to change(Spree::PaymentMethod, :count).by(1) + + response.should be_redirect + response.should redirect_to spree.edit_admin_payment_method_path(assigns(:payment_method)) + end + + it "can not create a payment method of an invalid type" do + expect { + spree_post :create, :payment_method => { :name => "Invalid Payment Method", :type => "Spree::InvalidType" } + }.to change(Spree::PaymentMethod, :count).by(0) + + response.should be_redirect + response.should redirect_to spree.new_admin_payment_method_path + end end end
backend/spec/controllers/spree/admin/promotion_actions_controller_spec.rb+21 −0 added@@ -0,0 +1,21 @@ +require 'spec_helper' + +describe Spree::Admin::PromotionActionsController do + stub_authorization! + + let!(:promotion) { create(:promotion) } + + it "can create a promotion action of a valid type" do + spree_post :create, :promotion_id => promotion.id, :action_type => "Spree::Promotion::Actions::CreateAdjustment" + response.should be_redirect + response.should redirect_to spree.edit_admin_promotion_path(promotion) + promotion.actions.count.should == 1 + end + + it "can not create a promotion action of an invalid type" do + spree_post :create, :promotion_id => promotion.id, :action_type => "Spree::InvalidType" + response.should be_redirect + response.should redirect_to spree.edit_admin_promotion_path(promotion) + promotion.rules.count.should == 0 + end +end
backend/spec/controllers/spree/admin/promotion_rules_controller_spec.rb+21 −0 added@@ -0,0 +1,21 @@ +require 'spec_helper' + +describe Spree::Admin::PromotionRulesController do + stub_authorization! + + let!(:promotion) { create(:promotion) } + + it "can create a promotion rule of a valid type" do + spree_post :create, :promotion_id => promotion.id, :promotion_rule => { :type => "Spree::Promotion::Rules::Product" } + response.should be_redirect + response.should redirect_to spree.edit_admin_promotion_path(promotion) + promotion.rules.count.should == 1 + end + + it "can not create a promotion rule of an invalid type" do + spree_post :create, :promotion_id => promotion.id, :promotion_rule => { :type => "Spree::InvalidType" } + response.should be_redirect + response.should redirect_to spree.edit_admin_promotion_path(promotion) + promotion.rules.count.should == 0 + end +end
backend/spec/requests/admin/promotion_adjustments_spec.rb+1 −1 modified@@ -110,7 +110,7 @@ it "should allow an admin to create an product promo with percent per item discount" do create(:product, :name => "RoR Mug") - fill_in "Name", :with => "Promotion" + fill_in "Name", :with => "Promotion" select2 "Add to cart", :from => "Event Name" click_button "Create" page.should have_content("Editing Promotion")
core/config/locales/en.yml+3 −0 modified@@ -529,6 +529,9 @@ en: intercept_email_address: "Intercept Email Address" intercept_email_instructions: "Override email recipient and replace with this address." invalid_search: "Invalid search criteria." + invalid_payment_provider: "Invalid payment provider." + invalid_promotion_action: "Invalid promotion action." + invalid_promotion_rule: "Invalid promotion rule." inventory: Inventory inventory_adjustment: "Inventory Adjustment" inventory_setting_description: "Inventory Configuration, Backordering, Zero-Stock Display."
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
11- www.conviso.com.br/advisories/CVE-2013-1656.txtnvdExploit
- spreecommerce.com/blog/multiple-security-vulnerabilities-fixednvdVendor Advisory
- github.com/advisories/GHSA-jxx8-v83v-rhw3ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2013-1656ghsaADVISORY
- blog.convisoappsec.com/en/spree-commerce-multiple-unsafe-reflection-vulnerabilities-cve-2013-1656ghsaWEB
- github.com/rubysec/ruby-advisory-db/blob/master/gems/spree/CVE-2013-1656.ymlghsaWEB
- github.com/spree/spree/commit/70092eb55b8be8fe5d21a7658b62da658612fba7ghsaWEB
- web.archive.org/web/20130907044454/https://www.conviso.com.br/advisories/CVE-2013-1656.txtghsaWEB
- web.archive.org/web/20140329142330/http://spreecommerce.com/blog/multiple-security-vulnerabilities-fixedghsaWEB
- web.archive.org/web/20140618100330/http://blog.conviso.com.br/2013/03/spree-commerce-multiple-unsafe.htmlghsaWEB
- blog.conviso.com.br/2013/03/spree-commerce-multiple-unsafe.htmlnvd
News mentions
0No linked articles in our index yet.