瀏覽代碼

Add back validates signature

John Tajima 13 年之前
父節點
當前提交
bc4a797ef0
共有 2 個文件被更改,包括 29 次插入0 次删除
  1. 14 0
      lib/shopify_api/session.rb
  2. 15 0
      test/session_test.rb

+ 14 - 0
lib/shopify_api/session.rb

@@ -37,11 +37,25 @@ module ShopifyAPI
         url.gsub!(/https?:\/\//, '')                            # remove http:// or https://
         url.concat(".myshopify.com") unless url.include?('.')   # extend url to myshopify.com if no host is given
       end
+
+      def validate_signature(params)
+        return false unless signature = params[:signature]
+
+        sorted_params = params.except(:signature, :action, :controller).collect{|k,v|"#{k}=#{v}"}.sort.join
+        Digest::MD5.hexdigest(secret + sorted_params) == signature
+      end
+
     end
     
     def initialize(url, token = nil, params = nil)
       self.url, self.token = url, token
       self.class.prepare_url(self.url)
+
+      if params
+        unless self.class.validate_signature(params) && params[:timestamp].to_i > 24.hours.ago.utc.to_i
+          raise "Invalid Signature: Possible malicious login" 
+        end
+      end
     end
     
     def shop

+ 15 - 0
test/session_test.rb

@@ -24,6 +24,12 @@ class SessionTest < Test::Unit::TestCase
       end
     end
 
+    should "raise error if params passed but signature omitted" do
+      assert_raises(RuntimeError) do
+        session = ShopifyAPI::Session.new("testshop.myshopify.com", "any-token", {'foo' => 'bar'})
+      end
+    end
+
     should "setup api_key and secret for all sessions" do
       ShopifyAPI::Session.setup(:api_key => "My test key", :secret => "My test secret")
       assert_equal "My test key", ShopifyAPI::Session.api_key
@@ -51,5 +57,14 @@ class SessionTest < Test::Unit::TestCase
       session = ShopifyAPI::Session.new("testshop.myshopify.com", "any-token")
       assert_equal "https://testshop.myshopify.com/admin", session.site
     end
+
+    should "raise error if signature does not match expected" do
+      ShopifyAPI::Session.secret = 'secret'
+      params = {:foo => 'hello', :foo => 'world', :timestamp => Time.now}
+      sorted_params = params.except(:signature, :action, :controller).collect{|k,v|"#{k}=#{v}"}.sort.join
+      signature = Digest::MD5.hexdigest(ShopifyAPI::Session.secret + sorted_params)
+
+      session = ShopifyAPI::Session.new("testshop.myshopify.com", "any-token", params.merge(:signature => signature))
+    end
   end
 end