braintree 4.40.0 → 4.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/lib/braintree/client_token_gateway.rb +10 -1
  3. data/lib/braintree/credit_card_gateway.rb +9 -3
  4. data/lib/braintree/credit_card_verification_gateway.rb +3 -0
  5. data/lib/braintree/customer_gateway.rb +11 -3
  6. data/lib/braintree/error_codes.rb +12 -0
  7. data/lib/braintree/http.rb +4 -2
  8. data/lib/braintree/merchant_account_gateway.rb +2 -0
  9. data/lib/braintree/payment_method_gateway.rb +6 -1
  10. data/lib/braintree/payment_method_nonce_gateway.rb +4 -0
  11. data/lib/braintree/paypal_account_gateway.rb +6 -1
  12. data/lib/braintree/plan_gateway.rb +4 -0
  13. data/lib/braintree/sepa_direct_debit_account_gateway.rb +4 -0
  14. data/lib/braintree/subscription_gateway.rb +6 -0
  15. data/lib/braintree/testing_gateway.rb +4 -0
  16. data/lib/braintree/transaction.rb +14 -0
  17. data/lib/braintree/transaction_gateway.rb +39 -7
  18. data/lib/braintree/transaction_line_item_gateway.rb +3 -1
  19. data/lib/braintree/transaction_search.rb +1 -0
  20. data/lib/braintree/us_bank_account_gateway.rb +2 -0
  21. data/lib/braintree/us_bank_account_verification_gateway.rb +4 -0
  22. data/lib/braintree/version.rb +1 -1
  23. data/spec/integration/braintree/apple_pay_spec.rb +3 -1
  24. data/spec/integration/braintree/client_api/client_token_spec.rb +14 -0
  25. data/spec/integration/braintree/credit_card_spec.rb +31 -0
  26. data/spec/integration/braintree/credit_card_verification_spec.rb +54 -0
  27. data/spec/integration/braintree/customer_spec.rb +58 -0
  28. data/spec/integration/braintree/transaction_idempotency_spec.rb +30 -0
  29. data/spec/integration/braintree/transaction_search_spec.rb +95 -0
  30. data/spec/integration/braintree/transaction_spec.rb +211 -1
  31. data/spec/unit/braintree/client_token_spec.rb +72 -0
  32. data/spec/unit/braintree/credit_card_spec.rb +28 -2
  33. data/spec/unit/braintree/credit_card_verification_gateway_spec.rb +1 -0
  34. data/spec/unit/braintree/credit_card_verification_spec.rb +8 -0
  35. data/spec/unit/braintree/customer_spec.rb +28 -2
  36. data/spec/unit/braintree/http_spec.rb +44 -0
  37. data/spec/unit/braintree/merchant_account_spec.rb +11 -0
  38. data/spec/unit/braintree/package_tracking_spec.rb +2 -2
  39. data/spec/unit/braintree/payment_method_nonce_spec.rb +14 -0
  40. data/spec/unit/braintree/payment_method_spec.rb +20 -0
  41. data/spec/unit/braintree/paypal_account_spec.rb +20 -0
  42. data/spec/unit/braintree/plan_gateway_spec.rb +30 -0
  43. data/spec/unit/braintree/sepa_debit_account_spec.rb +14 -0
  44. data/spec/unit/braintree/subscription_spec.rb +20 -0
  45. data/spec/unit/braintree/test_transaction_spec.rb +18 -0
  46. data/spec/unit/braintree/transaction_gateway_spec.rb +24 -0
  47. data/spec/unit/braintree/transaction_line_item_spec.rb +11 -0
  48. data/spec/unit/braintree/transaction_search_spec.rb +25 -0
  49. data/spec/unit/braintree/transaction_spec.rb +68 -6
  50. data/spec/unit/braintree/us_bank_account_spec.rb +8 -0
  51. data/spec/unit/braintree/us_bank_account_verification_spec.rb +14 -0
  52. data/spec/unit/braintree/util_spec.rb +37 -0
  53. metadata +7 -3
@@ -23,7 +23,7 @@ describe Braintree::CreditCard do
23
23
  :venmo_sdk_payment_method_code, # NEXT_MAJOR_VERSION Remove this attribute
24
24
  :device_data,
25
25
  :payment_method_nonce,
26
- {:external_vault=>[:network_transaction_id]},
26
+ {:external_vault=>[:network_transaction_id, :mastercard_transaction_link_id]},
27
27
  {:options => match_array([:make_default, :skip_advanced_fraud_checking, :verification_merchant_account_id, :verify_card, :verification_amount, :venmo_sdk_session, # NEXT_MAJOR_VERSION Remove this attribute
28
28
  :account_information_inquiry, :fail_on_duplicate_payment_method, :fail_on_duplicate_payment_method_for_customer, :verification_account_type, :verification_currency_iso_code])},
29
29
  {:billing_address => [
@@ -72,7 +72,7 @@ describe Braintree::CreditCard do
72
72
  :venmo_sdk_payment_method_code, # NEXT_MAJOR_VERSION Remove this attribute
73
73
  :device_data,
74
74
  :payment_method_nonce,
75
- {:external_vault=>[:network_transaction_id]},
75
+ {:external_vault=>[:network_transaction_id, :mastercard_transaction_link_id]},
76
76
  {:options => match_array([:make_default, :skip_advanced_fraud_checking, :verification_merchant_account_id, :verify_card, :verification_amount, :venmo_sdk_session, # NEXT_MAJOR_VERSION Remove this attribute
77
77
  :account_information_inquiry, :fail_on_duplicate_payment_method, :fail_on_duplicate_payment_method_for_customer, :verification_account_type, :verification_currency_iso_code])},
78
78
  {:billing_address => [
@@ -293,4 +293,30 @@ describe Braintree::CreditCard do
293
293
  card = Braintree::CreditCard._new(:gateway, {:purchase => "No"})
294
294
  expect(card.purchase).to eq("No")
295
295
  end
296
+
297
+ describe "path traversal" do
298
+ it "self.delete raises an exception if the token is a traversal segment" do
299
+ expect do
300
+ Braintree::CreditCard.delete("../payment_methods/paypal_account/victim_token")
301
+ end.to raise_error(ArgumentError, "token contains invalid characters")
302
+ end
303
+
304
+ it "self.find raises an exception if the token is a traversal segment" do
305
+ expect do
306
+ Braintree::CreditCard.find("../payment_methods/paypal_account/victim_token")
307
+ end.to raise_error(ArgumentError, "token contains invalid characters")
308
+ end
309
+
310
+ it "self.from_nonce raises an exception if the nonce is a traversal segment" do
311
+ expect do
312
+ Braintree::CreditCard.from_nonce("../payment_methods/paypal_account/victim_token")
313
+ end.to raise_error(ArgumentError, "nonce contains invalid characters")
314
+ end
315
+
316
+ it "self.update raises an exception if the token is a traversal segment" do
317
+ expect do
318
+ Braintree::CreditCard.update("../payment_methods/paypal_account/victim_token", :cvv => "123")
319
+ end.to raise_error(ArgumentError, "token contains invalid characters")
320
+ end
321
+ end
296
322
  end
@@ -31,6 +31,7 @@ describe Braintree::CreditCardVerificationGateway do
31
31
  expect(result.inspect).to include("number")
32
32
  expect(result.inspect).to include("external_vault")
33
33
  expect(result.inspect).to include("previous_network_transaction_id")
34
+ expect(result.inspect).to include("previous_mastercard_transaction_link_id")
34
35
  expect(result.inspect).to include("status")
35
36
  expect(result.inspect).to include("intended_transaction_source")
36
37
  expect(result.inspect).to include("options")
@@ -183,4 +183,12 @@ describe Braintree::CreditCardVerification do
183
183
  expect(verification.credit_card[:payment_account_reference]).to eq("V0010013019339005665779448477")
184
184
  end
185
185
  end
186
+
187
+ describe "path traversal" do
188
+ it "self.find raises an exception if the id is a traversal segment" do
189
+ expect do
190
+ Braintree::CreditCardVerification.find("../verifications/victim_id")
191
+ end.to raise_error(ArgumentError, "id contains invalid characters")
192
+ end
193
+ end
186
194
  end
@@ -136,7 +136,7 @@ describe Braintree::Customer do
136
136
  :venmo_sdk_payment_method_code, # NEXT_MAJOR_VERSION Remove this attribute
137
137
  :device_data,
138
138
  :payment_method_nonce,
139
- {:external_vault=>[:network_transaction_id]},
139
+ {:external_vault=>[:network_transaction_id, :mastercard_transaction_link_id]},
140
140
  {:options => match_array([:make_default, :skip_advanced_fraud_checking, :verification_merchant_account_id, :verify_card, :verification_amount, :venmo_sdk_session, # NEXT_MAJOR_VERSION Remove this attribute
141
141
  :account_information_inquiry, :fail_on_duplicate_payment_method, :verification_account_type, :verification_currency_iso_code])},
142
142
  {:billing_address => [
@@ -267,7 +267,7 @@ describe Braintree::Customer do
267
267
  :venmo_sdk_payment_method_code, # NEXT_MAJOR_VERSION Remove this attribute
268
268
  :device_data,
269
269
  :payment_method_nonce,
270
- {:external_vault=>[:network_transaction_id]},
270
+ {:external_vault=>[:network_transaction_id, :mastercard_transaction_link_id]},
271
271
  {:options => match_array([
272
272
  :account_information_inquiry,
273
273
  :make_default,
@@ -415,4 +415,30 @@ describe Braintree::Customer do
415
415
  end.to raise_error(NoMethodError, /protected method .new/)
416
416
  end
417
417
  end
418
+
419
+ describe "path traversal" do
420
+ it "self.delete raises an exception if the customer_id is a traversal segment" do
421
+ expect do
422
+ Braintree::Customer.delete("../transactions/some_id/void")
423
+ end.to raise_error(ArgumentError, "customer_id contains invalid characters")
424
+ end
425
+
426
+ it "self.find raises an exception if the customer_id is a traversal segment" do
427
+ expect do
428
+ Braintree::Customer.find("../transactions/some_id/void")
429
+ end.to raise_error(ArgumentError, "customer_id contains invalid characters")
430
+ end
431
+
432
+ it "self.update raises an exception if the customer_id is a traversal segment" do
433
+ expect do
434
+ Braintree::Customer.update("../transactions/some_id/void", :first_name => "HackerOne")
435
+ end.to raise_error(ArgumentError, "customer_id contains invalid characters")
436
+ end
437
+
438
+ it "self.transactions raises an exception if the customer_id is a traversal segment" do
439
+ expect do
440
+ Braintree::Customer.transactions("../transactions/some_id/void")
441
+ end.to raise_error(ArgumentError, "customer_id contains invalid characters")
442
+ end
443
+ end
418
444
  end
@@ -183,6 +183,50 @@ END
183
183
  end
184
184
  end
185
185
 
186
+ describe "#delete" do
187
+ it "appends the query string to the path when query_params are present" do
188
+ http = Braintree::Http.new(Braintree::Configuration.new)
189
+ response = double("response", :code => "200")
190
+
191
+ expect(http).to receive(:_http_do).with(Net::HTTP::Delete, "/customers?id=123").and_return(response)
192
+
193
+ http.delete("/customers", :id => 123)
194
+ end
195
+
196
+ it "does not append a query string when query_params are empty" do
197
+ http = Braintree::Http.new(Braintree::Configuration.new)
198
+ response = double("response", :code => "200")
199
+
200
+ expect(http).to receive(:_http_do).with(Net::HTTP::Delete, "/customers").and_return(response)
201
+
202
+ http.delete("/customers")
203
+ end
204
+ end
205
+
206
+ describe "#get" do
207
+ it "appends the query string to the path when query_params are present" do
208
+ http = Braintree::Http.new(Braintree::Configuration.new)
209
+ response = double("response", :code => "200")
210
+ allow(http).to receive(:_body).with(response).and_return("")
211
+ allow(Braintree::Xml).to receive(:hash_from_xml).with("").and_return({})
212
+
213
+ expect(http).to receive(:_http_do).with(Net::HTTP::Get, "/customers?id=123").and_return(response)
214
+
215
+ http.get("/customers", :id => 123)
216
+ end
217
+
218
+ it "does not append a query string when query_params are empty" do
219
+ http = Braintree::Http.new(Braintree::Configuration.new)
220
+ response = double("response", :code => "200")
221
+ allow(http).to receive(:_body).with(response).and_return("")
222
+ allow(Braintree::Xml).to receive(:hash_from_xml).with("").and_return({})
223
+
224
+ expect(http).to receive(:_http_do).with(Net::HTTP::Get, "/customers").and_return(response)
225
+
226
+ http.get("/customers")
227
+ end
228
+ end
229
+
186
230
  describe "_build_query_string" do
187
231
  it "returns an empty string for empty query params" do
188
232
  expect(Braintree::Http.new(:config)._build_query_string({})).to eq("")
@@ -0,0 +1,11 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Braintree::MerchantAccount do
4
+ describe "path traversal" do
5
+ it "self.find raises an exception if the merchant_account_id is a traversal segment" do
6
+ expect do
7
+ Braintree::MerchantAccount.find("../transactions/some_id/void")
8
+ end.to raise_error(ArgumentError, "merchant_account_id contains invalid characters")
9
+ end
10
+ end
11
+ end
@@ -24,8 +24,8 @@ describe "Package Tracking Unit Tests" do
24
24
 
25
25
  it "raises an ArgumentError if transaction_id is an invalid format" do
26
26
  expect do
27
- Braintree::Transaction.package_tracking("invalid-transaction-id", {})
28
- end.to raise_error(ArgumentError, "transaction_id is invalid")
27
+ Braintree::Transaction.package_tracking("invalid/transaction/id", {})
28
+ end.to raise_error(ArgumentError, "transaction_id contains invalid characters")
29
29
  end
30
30
 
31
31
  it "raises an exception if attributes contain an invalid key" do
@@ -47,4 +47,18 @@ describe Braintree::PaymentMethodNonce do
47
47
  expect(payment_method_nonce.default?).to be true
48
48
  end
49
49
  end
50
+
51
+ describe "path traversal" do
52
+ it "self.create raises an exception if the payment_method_token is a traversal segment" do
53
+ expect do
54
+ Braintree::PaymentMethodNonce.create("../payment_method_nonces/victim_nonce")
55
+ end.to raise_error(ArgumentError, "payment_method_token contains invalid characters")
56
+ end
57
+
58
+ it "self.find raises an exception if the payment_method_nonce is a traversal segment" do
59
+ expect do
60
+ Braintree::PaymentMethodNonce.find("../payment_method_nonces/victim_nonce")
61
+ end.to raise_error(ArgumentError, "payment_method_nonce contains invalid characters")
62
+ end
63
+ end
50
64
  end
@@ -144,4 +144,24 @@ describe Braintree::PaymentMethod do
144
144
  end.to_not raise_error
145
145
  end
146
146
  end
147
+
148
+ describe "path traversal" do
149
+ it "self.find raises an exception if the token is a traversal segment" do
150
+ expect do
151
+ Braintree::PaymentMethod.find("../customers/some_id/transaction_ids")
152
+ end.to raise_error(ArgumentError, "token contains invalid characters")
153
+ end
154
+
155
+ it "self.update raises an exception if the token is a traversal segment" do
156
+ expect do
157
+ Braintree::PaymentMethod.update("../customers/some_id/transaction_ids", {})
158
+ end.to raise_error(ArgumentError, "token contains invalid characters")
159
+ end
160
+
161
+ it "self.delete raises an exception if the token is a traversal segment" do
162
+ expect do
163
+ Braintree::PaymentMethod.delete("../customers/some_id/transaction_ids")
164
+ end.to raise_error(ArgumentError, "token contains invalid characters")
165
+ end
166
+ end
147
167
  end
@@ -50,4 +50,24 @@ describe Braintree::PayPalAccount do
50
50
  expect(paypal_account.edit_paypal_vault_id).to eq(mock_edit_paypal_vault_id)
51
51
  end
52
52
  end
53
+
54
+ describe "path traversal" do
55
+ it "self.find raises an exception if the token is a traversal segment" do
56
+ expect do
57
+ Braintree::PayPalAccount.find("../payment_methods/credit_card/victim_token")
58
+ end.to raise_error(ArgumentError, "token contains invalid characters")
59
+ end
60
+
61
+ it "self.update raises an exception if the token is a traversal segment" do
62
+ expect do
63
+ Braintree::PayPalAccount.update("../payment_methods/credit_card/victim_token", {})
64
+ end.to raise_error(ArgumentError, "token contains invalid characters")
65
+ end
66
+
67
+ it "self.delete raises an exception if the token is a traversal segment" do
68
+ expect do
69
+ Braintree::PayPalAccount.delete("../payment_methods/credit_card/victim_token")
70
+ end.to raise_error(ArgumentError, "token contains invalid characters")
71
+ end
72
+ end
53
73
  end
@@ -0,0 +1,30 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Braintree::PlanGateway do
4
+ let(:gateway) do
5
+ config = Braintree::Configuration.new(
6
+ :merchant_id => "merchant_id",
7
+ :public_key => "public_key",
8
+ :private_key => "private_key",
9
+ )
10
+ Braintree::Gateway.new(config)
11
+ end
12
+
13
+ describe "path traversal" do
14
+ it "find raises an exception if the id is a traversal segment" do
15
+ plan_gateway = Braintree::PlanGateway.new(gateway)
16
+
17
+ expect do
18
+ plan_gateway.find("../plans/victim_id")
19
+ end.to raise_error(ArgumentError, "id contains invalid characters")
20
+ end
21
+
22
+ it "update raises an exception if the plan_id is a traversal segment" do
23
+ plan_gateway = Braintree::PlanGateway.new(gateway)
24
+
25
+ expect do
26
+ plan_gateway.update("../plans/victim_id", {})
27
+ end.to raise_error(ArgumentError, "plan_id contains invalid characters")
28
+ end
29
+ end
30
+ end
@@ -83,4 +83,18 @@ describe Braintree::SepaDirectDebitAccount do
83
83
  it { is_expected.to be false }
84
84
  end
85
85
  end
86
+
87
+ describe "path traversal" do
88
+ it "self.find raises an exception if the token is a traversal segment" do
89
+ expect do
90
+ Braintree::SepaDirectDebitAccount.find("../payment_methods/credit_card/victim_token")
91
+ end.to raise_error(ArgumentError, "token contains invalid characters")
92
+ end
93
+
94
+ it "self.delete raises an exception if the token is a traversal segment" do
95
+ expect do
96
+ Braintree::SepaDirectDebitAccount.delete("../payment_methods/credit_card/victim_token")
97
+ end.to raise_error(ArgumentError, "token contains invalid characters")
98
+ end
99
+ end
86
100
  end
@@ -77,4 +77,24 @@ describe Braintree::Subscription do
77
77
  expect(subscription).not_to eq("not a subscription")
78
78
  end
79
79
  end
80
+
81
+ describe "path traversal" do
82
+ it "self.cancel raises an exception if the subscription_id is a traversal segment" do
83
+ expect do
84
+ Braintree::Subscription.cancel("../transactions/some_id/void")
85
+ end.to raise_error(ArgumentError, "subscription_id contains invalid characters")
86
+ end
87
+
88
+ it "self.find raises an exception if the id is a traversal segment" do
89
+ expect do
90
+ Braintree::Subscription.find("../transactions/some_id/void")
91
+ end.to raise_error(ArgumentError, "id contains invalid characters")
92
+ end
93
+
94
+ it "self.update raises an exception if the subscription_id is a traversal segment" do
95
+ expect do
96
+ Braintree::Subscription.update("../transactions/some_id/void", {})
97
+ end.to raise_error(ArgumentError, "subscription_id contains invalid characters")
98
+ end
99
+ end
80
100
  end
@@ -0,0 +1,18 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Braintree::TestTransaction do
4
+ describe "path traversal" do
5
+ [
6
+ :settle,
7
+ :settlement_confirm,
8
+ :settlement_decline,
9
+ :settlement_pending,
10
+ ].each do |method_name|
11
+ it "self.#{method_name} raises an exception if the transaction_id is a traversal segment" do
12
+ expect do
13
+ Braintree::TestTransaction.public_send(method_name, "../transactions/victim_id/void")
14
+ end.to raise_error(ArgumentError, "transaction_id contains invalid characters")
15
+ end
16
+ end
17
+ end
18
+ end
@@ -53,6 +53,7 @@ describe Braintree::TransactionGateway do
53
53
  {:external_vault => [
54
54
  :status,
55
55
  :previous_network_transaction_id,
56
+ :previous_mastercard_transaction_link_id,
56
57
  ]},
57
58
  {:google_pay_card => [:number, :cryptogram, :google_transaction_id, :expiration_month, :expiration_year, :source_card_type, :source_card_last_four, :eci_indicator]},
58
59
  {:industry => [
@@ -200,5 +201,28 @@ describe Braintree::TransactionGateway do
200
201
  it "creates transaction gateway submit for partial settlement signature" do
201
202
  expect(Braintree::TransactionGateway._submit_for_partial_settlement_signature).to include(:final_capture)
202
203
  end
204
+
205
+ it "creates a transaction gateway refund signature" do
206
+ expect(Braintree::TransactionGateway._refund_signature).to match([
207
+ :amount,
208
+ :api_request_key,
209
+ :merchant_account_id,
210
+ :order_id,
211
+ :surcharge_amount,
212
+ ])
213
+ end
214
+
215
+ it "creates a transaction gateway reverse signature" do
216
+ expect(Braintree::TransactionGateway._reverse_signature).to match([
217
+ :api_request_key,
218
+ ])
219
+ end
220
+
221
+ it "rejects invalid transaction IDs when reversing" do
222
+ transaction = Braintree::TransactionGateway.new(gateway)
223
+
224
+ expect { transaction.reverse("../transactions/victim") }
225
+ .to raise_error(ArgumentError, "transaction_id contains invalid characters")
226
+ end
203
227
  end
204
228
  end
@@ -0,0 +1,11 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Braintree::TransactionLineItem do
4
+ describe "path traversal" do
5
+ it "self.find_all raises an exception if the transaction_id is a traversal segment" do
6
+ expect do
7
+ Braintree::TransactionLineItem.find_all("../transactions/victim_id/void")
8
+ end.to raise_error(ArgumentError, "transaction_id contains invalid characters")
9
+ end
10
+ end
11
+ end
@@ -21,4 +21,29 @@ describe Braintree::TransactionSearch do
21
21
  search.billing_company "one"
22
22
  end.to raise_error(RuntimeError, "An operator is required")
23
23
  end
24
+
25
+ it "builds a hash for ach_type with a single value (same_day)" do
26
+ search = Braintree::TransactionSearch.new
27
+ search.ach_type.is Braintree::Transaction::AchType::SameDay
28
+ expect(search.to_hash).to eq({:ach_type => [Braintree::Transaction::AchType::SameDay]})
29
+ end
30
+
31
+ it "builds a hash for ach_type with a single value (standard)" do
32
+ search = Braintree::TransactionSearch.new
33
+ search.ach_type.is Braintree::Transaction::AchType::Standard
34
+ expect(search.to_hash).to eq({:ach_type => [Braintree::Transaction::AchType::Standard]})
35
+ end
36
+
37
+ it "builds a hash for ach_type with both values" do
38
+ search = Braintree::TransactionSearch.new
39
+ search.ach_type.in Braintree::Transaction::AchType::SameDay, Braintree::Transaction::AchType::Standard
40
+ expect(search.to_hash).to eq({:ach_type => [Braintree::Transaction::AchType::SameDay, Braintree::Transaction::AchType::Standard]})
41
+ end
42
+
43
+ it "raises if ach_type is given a value outside the allow-list" do
44
+ search = Braintree::TransactionSearch.new
45
+ expect do
46
+ search.ach_type.is "invalid_ach_type"
47
+ end.to raise_error(ArgumentError, /Invalid argument\(s\) for ach_type: invalid_ach_type/)
48
+ end
24
49
  end
@@ -40,8 +40,8 @@ describe Braintree::Transaction do
40
40
  describe "self.submit_for_settlement" do
41
41
  it "raises an ArgumentError if transaction_id is an invalid format" do
42
42
  expect do
43
- Braintree::Transaction.submit_for_settlement("invalid-transaction-id")
44
- end.to raise_error(ArgumentError, "transaction_id is invalid")
43
+ Braintree::Transaction.submit_for_settlement("invalid/transaction/id")
44
+ end.to raise_error(ArgumentError, "transaction_id contains invalid characters")
45
45
  end
46
46
 
47
47
  it "raises an ArgumentError if options hash includes an invalid key" do
@@ -54,16 +54,16 @@ describe Braintree::Transaction do
54
54
  describe "self.adjust_authorization" do
55
55
  it "raises an ArgumentError if transaction_id is an invalid format" do
56
56
  expect do
57
- Braintree::Transaction.adjust_authorization("invalid-transaction-id", "10.00")
58
- end.to raise_error(ArgumentError, "transaction_id is invalid")
57
+ Braintree::Transaction.adjust_authorization("invalid/transaction/id", "10.00")
58
+ end.to raise_error(ArgumentError, "transaction_id contains invalid characters")
59
59
  end
60
60
  end
61
61
 
62
62
  describe "self.update_details" do
63
63
  it "raises an ArgumentError if transaction_id is an invalid format" do
64
64
  expect do
65
- Braintree::Transaction.update_details("invalid-transaction-id")
66
- end.to raise_error(ArgumentError, "transaction_id is invalid")
65
+ Braintree::Transaction.update_details("invalid/transaction/id")
66
+ end.to raise_error(ArgumentError, "transaction_id contains invalid characters")
67
67
  end
68
68
  end
69
69
 
@@ -604,4 +604,66 @@ describe Braintree::Transaction do
604
604
  expect(transaction.surcharge_amount).to be_nil
605
605
  end
606
606
  end
607
+
608
+ describe "path traversal" do
609
+ it "self.clone_transaction raises an exception if the transaction_id is a traversal segment" do
610
+ expect do
611
+ Braintree::Transaction.clone_transaction("../customers/some_id", :amount => "10.00")
612
+ end.to raise_error(ArgumentError, "transaction_id contains invalid characters")
613
+ end
614
+
615
+ it "self.find raises an exception if the id is a traversal segment" do
616
+ expect do
617
+ Braintree::Transaction.find("../customers/some_id")
618
+ end.to raise_error(ArgumentError, "id contains invalid characters")
619
+ end
620
+
621
+ it "self.refund raises an exception if the transaction_id is a traversal segment" do
622
+ expect do
623
+ Braintree::Transaction.refund("../customers/some_id")
624
+ end.to raise_error(ArgumentError, "transaction_id contains invalid characters")
625
+ end
626
+
627
+ it "self.void raises an exception if the transaction_id is a traversal segment" do
628
+ expect do
629
+ Braintree::Transaction.void("../transactions/victim_id")
630
+ end.to raise_error(ArgumentError, "transaction_id contains invalid characters")
631
+ end
632
+
633
+ it "self.cancel_release raises an exception if the transaction_id is a traversal segment" do
634
+ expect do
635
+ Braintree::Transaction.cancel_release("../transactions/victim_id/void")
636
+ end.to raise_error(ArgumentError, "transaction_id contains invalid characters")
637
+ end
638
+
639
+ it "self.package_tracking raises an exception if the transaction_id is a traversal segment" do
640
+ expect do
641
+ Braintree::Transaction.package_tracking("../transactions/victim_id/void", {})
642
+ end.to raise_error(ArgumentError, "transaction_id contains invalid characters")
643
+ end
644
+
645
+ it "self.submit_for_settlement raises an exception if the transaction_id is a traversal segment" do
646
+ expect do
647
+ Braintree::Transaction.submit_for_settlement("../transactions/victim_id/void")
648
+ end.to raise_error(ArgumentError, "transaction_id contains invalid characters")
649
+ end
650
+
651
+ it "self.adjust_authorization raises an exception if the transaction_id is a traversal segment" do
652
+ expect do
653
+ Braintree::Transaction.adjust_authorization("../transactions/victim_id/void", "10.00")
654
+ end.to raise_error(ArgumentError, "transaction_id contains invalid characters")
655
+ end
656
+
657
+ it "self.update_details raises an exception if the transaction_id is a traversal segment" do
658
+ expect do
659
+ Braintree::Transaction.update_details("../transactions/victim_id/void")
660
+ end.to raise_error(ArgumentError, "transaction_id contains invalid characters")
661
+ end
662
+
663
+ it "self.submit_for_partial_settlement raises an exception if the authorized_transaction_id is a traversal segment" do
664
+ expect do
665
+ Braintree::Transaction.submit_for_partial_settlement("../transactions/victim_id/void")
666
+ end.to raise_error(ArgumentError, "authorized_transaction_id contains invalid characters")
667
+ end
668
+ end
607
669
  end
@@ -10,4 +10,12 @@ describe Braintree::UsBankAccount do
10
10
  expect(Braintree::UsBankAccount._new(:gateway, :default => false).default?).to eq(false)
11
11
  end
12
12
  end
13
+
14
+ describe "path traversal" do
15
+ it "self.find raises an exception if the token is a traversal segment" do
16
+ expect do
17
+ Braintree::UsBankAccount.find("../payment_methods/credit_card/victim_token")
18
+ end.to raise_error(ArgumentError, "token contains invalid characters")
19
+ end
20
+ end
13
21
  end
@@ -95,4 +95,18 @@ describe Braintree::UsBankAccountVerification do
95
95
  expect(verification).not_to eq(same_id_different_object)
96
96
  end
97
97
  end
98
+
99
+ describe "path traversal" do
100
+ it "self.find raises an exception if the id is a traversal segment" do
101
+ expect do
102
+ Braintree::UsBankAccountVerification.find("../verifications/victim_id")
103
+ end.to raise_error(ArgumentError, "id contains invalid characters")
104
+ end
105
+
106
+ it "self.confirm_micro_transfer_amounts raises an exception if the id is a traversal segment" do
107
+ expect do
108
+ Braintree::UsBankAccountVerification.confirm_micro_transfer_amounts("../verifications/victim_id", ["0.01", "0.02"])
109
+ end.to raise_error(ArgumentError, "id contains invalid characters")
110
+ end
111
+ end
98
112
  end
@@ -417,4 +417,41 @@ describe Braintree::Util do
417
417
  expect(Braintree::Util.url_decode("foo%3Fbar")).to eq("foo?bar")
418
418
  end
419
419
  end
420
+
421
+ describe "self.invalid_path_segment?" do
422
+ [
423
+ "customer123",
424
+ "CUSTOMER_123",
425
+ "a-b_c-D9",
426
+ "1234567890",
427
+ "a",
428
+ 123,
429
+ ].each do |valid_segment|
430
+ it "returns false for a valid segment #{valid_segment.inspect}" do
431
+ expect(Braintree::Util.invalid_path_segment?(valid_segment)).to eq(false)
432
+ end
433
+ end
434
+
435
+ [
436
+ "",
437
+ " ",
438
+ ".",
439
+ "..",
440
+ "foo/bar",
441
+ "foo\\bar",
442
+ "foo%bar",
443
+ "..%2f..%2fvictim",
444
+ "%2e%2e",
445
+ "../../victim_customer/addresses/victim_address",
446
+ "abc.def",
447
+ "abc def",
448
+ nil,
449
+ {},
450
+ [],
451
+ ].each do |invalid_segment|
452
+ it "returns true for an invalid segment #{invalid_segment.inspect}" do
453
+ expect(Braintree::Util.invalid_path_segment?(invalid_segment)).to eq(true)
454
+ end
455
+ end
456
+ end
420
457
  end