Download presentation
Presentation is loading. Please wait.
Published byArleen Johns Modified over 9 years ago
1
Case Study: Interspire and PayPal Express
2
Case: Interspire and PayPal Express Interspire is an eCommerce merchant software Can be integrated with PayPal Express to collect the payments Need to maintain state of a transaction between 3 parties: the Attacker, the Merchant, and PayPal Logic flaw allows the attacker to purchase an order at a reduced price Refer to Section III. B 1) in How to Shop For Free Online for the complete description of this case 2
3
The Flaw Attacker can use a session with a successful payment status on a different order than it was intended for Allows attacker to complete an expensive order using the payment intended for a cheaper order 3
4
Discovering the Flaw Presented by Wang et al. in How to Shop for Free Online: Security Analysis of Cashier-as-a- Service Based Web Stores Used a manual code review method – Identify all API parameters the attacker can access – Test how parameters affect the internal state 4
5
Identify the API Parameters API parameters (method arguments) can be signed or unsigned Unsigned arguments: – Sent in cleartext Signed arguments: – Sender uses a digital signature to sign the argument – Provides data integrity 5
6
Manipulating the API Parameters Attackers can manipulate data sent from the client side Test manipulating the arguments one at a time, then trace through the rest of the checkout process – See how each individual arguments affects the internal state of the transaction, and the end result 6
7
Modifying Unsigned Arguments Change the value manually – store.com/checkout?price=5 Leave the argument value empty – store.com/checkout?price= Remove the argument completely – store.com/checkout 7
8
Modifying Signed Arguments Replace a signed argument from one session with the same signed argument from a second session – Session 1: store.com/updateOrder?orderID=(SIGNED1)&sessionID=1 – Session 2: store.com/updateOrder?orderID=(SIGNED2)&sessionID=2 – Replace orderID in session 1 with orderID from session 2: store.com/updateOrder?orderID=(SIGNED2)&sessionID=1 8
9
Modifying Signed Arguments Leave the signed argument value empty – store.com/updateOrder?orderID=&sessionID=1 Remove the signed argument completely – store.com/updateOrder?sessionID=1 Reuse a signed argument from a completed transaction in a new transaction – Replay attack 9
10
Modifying the Workflow Try skipping steps of the transaction – Skip one step, then run the rest of the transaction – Skip multiple steps, then run the rest of the transaction Try running the steps out of order Do these manipulations with expected argument values Then, do these workflow manipulations with manipulated unsigned and signed arguments 10
11
Interspire and PayPal Express API Parameters Price (Total cost of items in the cart) (ORDERID) (Signed Order object) SessionID (Temporary session number) PayerID (Like a userID) PayPalExpress (Cashier being used) Result (sent from PayPal to Interspire) StoreID (sent to PayPal from Interspire) Token (sent from PayPal to Interspire) 11
12
Notation Used in the Animation If a parameter is unsigned, it is represented with lower case words. For example: – price – sessionID If a parameter is signed, it is represented with all uppercase words inside parenthesis. For example: – (ORDERID) Parameter values are not shown – price – instead of price=5 12
13
The Attacker Parameters sent by the Attacker, or ones the Attacker could modify, are in red text API Methods accessible by the attacker are in black text 13
14
The Merchant Parameters sent by the Merchant are in blue text Code run by the Merchant is in blue text Public API Methods (attacker accessible): – Store_checkout(Price,PayPalExpress) – Store_ finishOrder(TokenID, PayerID, SessionID); – Store_updateOrderStatus(OrderID, SessionID); 14
15
PayPal Express Parameters sent by PayPal Express is in green text Code run by PayPal Express is in green text Public API Methods (attacker accessible): – PayPal_pay(token, payerID); 15
16
Interspire and PayPal Checkout Transaction Overview Step 1: Attacker adds items to their cart Step 2: Attacker clicks on ‘Checkout’ Step 2a: The Store contacts PayPal and gets a token Step 3: The Attacker is redirected PayPal for payment Step 4: The Attacker is redirected to the Store to finish the order Step 4a: The Store contacts PayPal to check if payment was made Step 5: The Attacker is redirected to another Store page to complete the order 16
17
Checkout Transaction Overview 1. Attacker adds cheap items to cart 2. store.com/checkout?price&PayPalExpress 2a. PayPal.com/setExpressCheckout?StoreID token Redirect to : PayPal.com/pay?token&payerID 3. PayPal.com/pay?token&payerID Redirect to: store.com/finishOrder?token&payerID&sessionID 4. store.com/finishOrder?token&payerID&sessionID 4a. PayPal.com/doExpressPayment?StoreID&payerID result Redirect to: store.com/updateOrderStatus?(ORDERID)&sessionID 5. store.com/updateOrderStatus?(ORDERID)&sessionID Transaction Completed 17
18
Translation between Case Study and How to Shop for Free 18 Case StudyFigure 7 in How to Shop for Free article 2. store.com/checkout?price&PayPalExpressRT1.a: TStore.com/placeOrder 2a. PayPal.com/setExpressCheckout?StoreIDRT1.a.a: CaaS.com/SetExpCheckout?identity T &… tokenRT1.a.b: token C Redirect to : PayPal.com/pay?token&payerIDRT1.b: redir to CaaS.com/pay?token C 3. PayPal.com/pay?token&payerIDRT2.a: CaaS.com/pay?token A Redirect to: store.com/finishOrder?token&payerID&sessionID RT2.b: redir to TStore.com/finishOrder?token C &payerID C 4. store.com/finishOrder?token&payerID&sessionIDRT3.a: TStore.com/finishOrder?token A &payerID A 4a. PayPal.com/doExpressPayment?StoreID&payerIDRT3.a.a: CaaS.com/DoExpPay?identity T &token C &gross T resultRT3.a.b: result C Redirect to: store.com/updateOrderStatus?(ORDERID)&sessionID RT3.b: redir to TStore.com/updateOrderStatus?orderID T* 5. store.com/updateOrderStatus?(ORDERID)&sessionIDRT4.a: Store.com/updateOrderStatus?orderID T* Transaction CompletedRT4.b: Purchase done
19
Interspire and PayPal Express Flaw The following slides show how the logic flaw when Interspire used PayPal Express to collect payment can be exploited The HTTP interactions will be shown, followed by the manual code review A table tracks the internal state of the variables through each transaction step 19
20
The Animation Each step of the transaction includes: 1.Description of the step 2.Sequence diagram to show which two parties are communicating, and includes: – The API method called – The last party who could modified unsigned parameters 3.The backend code for that API method – Pseudocode is based on C 20
21
1. Create Cheap Order (First Session) On the merchant website, the Attacker adds cheap items to their cart 21
22
1. Create Cheap Order (First Session) Attacker adds cheap items to cart 22
23
myCustomer =myPrice =mySessionID =myTokenID =(ORDERID) = Session 1 (Cheap Order)Session 2 (Expensive Order)Payment and other Variables carts[ ] = payments[ ] = price = payerID = recipientID = paymentAmount = paymentType = orderID = tokens[ ] = recipientID = payerID = recipientID = payerID = orders[ ] = orderID = price = status = paymentType = orderID = price = status = paymentType = currentOrderID = 0 currentPaymentID = 0 currentSessionID = 0 currentTokenID = 0 customer = Attacker ExpResults[ ] = Program Variables Attacker Variables 1. Create Cheap Order myPrice = 5; mySessionID = 0; myCustomer = Attacker; Attacker 50 23
24
2. Checkout Cheap Order On the merchant website, the Attacker clicks the checkout button On the merchants’ server side, a cart object is created – Is linked to the sessionID 24
25
2. Checkout Cheap Order Attacker adds cheap items to cart store.com/checkout?price&PayPalExpress 25
26
Session 1 (Cheap Order)Session 2 (Expensive Order)Payment and other Variables carts[ ] = payments[ ] = price = payerID = recipientID = paymentAmount = paymentType = orderID = tokens[ ] = recipientID = payerID = recipientID = payerID = orders[ ] = orderID = price = status = paymentType = orderID = price = status = paymentType = currentOrderID = 0 currentPaymentID = 0 currentSessionID = 0 currentTokenID = 0 customer = Attacker ExpResults[ ] = 2. Checkout Cheap Order createCart(myPrice) carts[currentSessionID].price = myPrice; ExpResults[currentSessionID] = Pay_NotHappened; currentSessionID++; 0 0 1 5 Pay_NotHappened Store_checkout(myPrice,PayPalExpress) Program Variables Attacker Variables 26 myCustomer = AttackermyPrice = 5mySessionID = 0myTokenID =(ORDERID) =
27
2.a During Checkout: Store Gets PayPal Token On the merchants’ server side, a call is made to PayPal Express API method to request a token for the transaction A token is returned to the merchants’ server The Attacker does not have access to this communication; it is directly between the merchant and PayPal Express 27
28
Attacker adds cheap items to cart store.com/checkout?price&PayPalExpress PayPal.com/setExpressCheckout?StoreID token 2.a During Checkout: Store Gets PayPal Token 28
29
Session 1Session 2Payment and other Variables carts[ 0 ] =carts[ ] =payments[ ] = price = 5price = payerID = recipientID = paymentAmount = paymentType = orderID = tokens[ ] = recipientID = payerID = recipientID = payerID = orders[ ] = orderID = price = status = paymentType = orderID = price = status = paymentType = currentOrderID = 0 currentPaymentID = 0 currentSessionID = 1 currentTokenID = 0 customer = Attacker ExpResults[ 0 ] = Pay_NotHappenedExpResults[ ] = 2.a During Checkout: Store Gets PayPal Token PayPal_setExpressCheckout(StoreID); tokens[currentTokenID].payer = Not Set; tokens[currentTokenID].recipientID = StoreID; currentTokenID++; StoreID 0 Not Set 1 //payer not valid yet Program Variables Attacker Variables 29 myCustomer = AttackermyPrice = 5mySessionID = 0myTokenID =(ORDERID) =
30
3. Store Redirects to PayPal. Attacker Makes Payment The merchant redirects the Attacker to PayPal Express to make a payment – Attacker does pay for the order The token received from PayPal Express in step 2.a is included as a parameter in this new page request 30
31
Attacker adds cheap items to cart store.com/checkout?price&PayPalExpress PayPal.com/setExpressCheckout?StoreID token Redirect to : PayPal.com/pay?token&payerID PayPal.com/pay?token&payerID 3. Store Redirects to PayPal. Attacker Makes Payment 31
32
myCustomer = AttackermyPrice = 5mySessionID = 0myTokenID =(ORDERID) = Session 1 (Cheap Order)Session 2 (Expensive Order)Payment and other Variables carts[ 0 ] =carts[ ] =payments[ ] = price = 5price = payerID = recipientID = paymentAmount = paymentType = orderID = tokens[ 0 ] =tokens[ ] = recipientID = StoreID payerID = Not_Set recipientID = payerID = orders[ ] = orderID = price = status = paymentType = orderID = price = status = paymentType = currentOrderID = 0 currentPaymentID = 0 currentSessionID = 1 currentTokenID = 1 customer = Attacker ExpResults[ 0 ] = Pay_NotHappenedExpResults[ ] = 3. Attacker Makes Payment on PayPal PayPal_Pay(myTokenID, myCustomer); tokens[myTokenID].payerID = myCustomer; if (myTokenID = currentTokenID) return; //if invalid tokenID Program Variables Attacker Variables Attacker 32 0
33
4. PayPal Redirects to Store. Store Creates Order After payment is made, PayPal Express redirects the Attacker back to the merchant to continue the checkout process The merchant creates an order object on the server – The payment status of the order is set to pending – Price is retrieved from cart stored on the server, not from an API parameter – Is not linked to the sessionID 33
34
Attacker adds cheap items to cart store.com/checkout?price&PayPalExpress PayPal.com/setExpressCheckout?StoreID token Redirect: PayPal.com/pay?token&payerID PayPal.com/pay?token&payerID store.com/finishOrder?token&payerID&sessionID 4. PayPal Redirects to Store. Store Creates Order Redirect to: store.com/finishOrder?token&payerID&sessionID 34
35
myCustomer = AttackermyPrice = 5mySessionID = 0myTokenID = 0(ORDERID) = Session 1 (Cheap Order)Session 2 (Expensive Order)Payment and other Variables carts[ 0 ] =carts[ ] =payments[ ] = price = 5price = payerID = recipientID = paymentAmount = paymentType = orderID = tokens[ 0 ] =tokens[ ] = recipientID = StoreID payerID = Attacker recipientID = payerID = orders[ ] = orderID = price = status = paymentType = orderID = price = status = paymentType = currentOrderID = 0 currentPaymentID = 0 currentSessionID = 1 currentTokenID = 1 customer = Attacker ExpResults[ 0 ] = Pay_NotHappenedExpResults[ ] = 4. Store Creates Order Store_finishOrder(myTokenID, myCustomer, mySessionID); orderID = createOrder( carts[mySessionID].price, PENDING, PayPalExpress); if (mySessionID = currentSessionID) return;//if invalid sessionID Program Variables Attacker Variables orderID = orders[currentOrderID].orderID = currentOrderID; orders[currentOrderID].price = carts[mySessionID].price; orders[currentOrderID].status = PENDING; orders[currentOrderID].paymentType = PayPalExpress currentOrderID++; return currentOrderID-1; 0 0 5 PENDING PayPalExpress 1 0 35
36
4.a Store Checks if Payment was Made The merchant asks PayPal Express if payment was made PayPal Express records the payment on their server PayPal Express returns the result of payment – Payment Suceeded – Is linked to the sessionID The merchant digitally signs an orderID with information about the order, whether or not payment suceeded 36
37
Attacker adds cheap items to cart store.com/checkout?price&PayPalExpress PayPal.com/setExpressCheckout?StoreID token Redirect to : PayPal.com/pay?token&payerID PayPal.com/pay?token&payerID PayPal.com/doExpressPayment?StoreID&payerID result 4.a Store Checks if Payment was Made store.com/finishOrder?token&payerID&sessionID Redirect to: store.com/finishOrder?token&payerID&sessionID 37
38
myCustomer = AttackermyPrice = 5mySessionID = 0myTokenID = 0(ORDERID) = Session 1 (Cheap Order)Session 2 (Expensive Order)Payment and other Variables carts[ 0 ] =carts[ ] =payments[ ] = price = 5price = payerID = recipientID = paymentAmount = paymentType = orderID = tokens[ 0 ] =tokens[ ] = recipientID = StoreID payerID = Attacker recipientID = payerID = orders[ 0 ] =orders[ ] = orderID = 0 price = 5 status = PENDING paymentType = PayPalExpress orderID = price = status = paymentType = currentOrderID = 1 currentPaymentID = 0 currentSessionID = 0 currentTokenID = 1 customer = Attacker orderID = 0 ExpResults[ 0 ] = Pay_NotHappenedExpResults[ ] = 4.a Store Checks if Payment was Made Program Variables Attacker Variables ExpResults[mySessionID] = PayPal_doExpressPayment(myCustomer, StoreID, myTokenID, orderID, carts[mySessionID].price); if (myTokenID = currentTokenID) return Pay_Failed;//if tokenID invalid if (tokens[myTokenID].payerID == Not_Set) return Pay_Failed; //if payer not confirmed if (tokens[myTokenID].payerID != myCustomer) return Pay_Failed; //if payer not the customer if (tokens[myTokenID].recipientID != StoreID) return Pay_Failed; //if recipient not the store 38 recordPayment(myCustomer, StoreID, PayPalExpress, carts[mySessionID].price, orderID);
39
myCustomer = AttackermyPrice = 5mySessionID = 0myTokenID = 0(ORDERID) = Session 1 (Cheap Order)Session 2 (Expensive Order)Payment and other Variables carts[ 0 ] =carts[ ] =payments[ ] = price = 5price = payerID = recipientID = paymentAmount = paymentType = orderID = tokens[ 0 ] =tokens[ ] = recipientID = StoreID payerID = Attacker recipientID = payerID = orders[ 0 ] =orders[ ] = orderID = 0 price = 5 status = PENDING paymentType = PayPalExpress orderID = price = status = paymentType = currentOrderID = 1 currentPaymentID = 0 currentSessionID = 1 currentTokenID = 1 customer = Attacker orderID = 0 ExpResults[ 0 ] = Pay_NotHappenedExpResults[ ] = 4.a Store Checks if Payment was Made Program Variables Attacker Variables recordPayment(myCustomer, StoreID, PayPalExpress, carts[mySessionID].price, orderID); payments[currentPaymentID].payerID = myCustomer; payments[currentPaymentID].recipientID = StoreID; payments[currentPaymentID].paymentType = PayPalExpress; payments[currentPaymentID].paymentAmount = carts[mySessionID].price; payments[currentPaymentID].orderID = orderID; currentPaymentID++; return Pay_Succeeded; 0 Attacker StoreID 5 PayPalExpress 0 1 Pay_Succeeded 39 sign(orderID);
40
5. Store Redirects to Update Order Status After checking payment status with PayPal Express, the merchant redirects the Attacker to a final merchant page to complete the transaction – Signed (ORDERID) is included as a parameter Attacker stops this page from loading 40
41
store.com/updateOrderStatus ?( ORDERID )=0&sessionID=0 Attacker adds cheap items to cart store.com/checkout?price&PayPalExpress PayPal.com/setExpressCheckout?StoreID token Redirect to : PayPal.com/pay?token&payerID PayPal.com/pay?token&payerID PayPal.com/doExpressPayment?StoreID&payerID result store.com/finishOrder?token&payerID&sessionID Redirect to: store.com/finishOrder?token&payerID&sessionID Attacker stops the redirect from loading (can intercept with a proxy to do this) Attacker now has session from cheap order stored with successful payment results Redirect to: store.com/updateOrderStatus?(ORDERID)=0&sessionID=0 5. Store Redirects to Update Order Status 41
42
myCustomer = AttackermyPrice = 5mySessionID = 0myTokenID = 0(ORDERID) = Session 1 (Cheap Order)Session 2 (Expensive Order)Payment and other Variables carts[ 0 ] =carts[ ] =payments[ 0 ] = price = 5price = payerID = Attacker recipientID = StoreID paymentAmount = 5 paymentType = PayPalExpress orderID = 0 tokens[ 0 ] =tokens[ ] = recipientID = StoreID payerID = Attacker recipientID = payerID = orders[ 0 ] =orders[ ] = orderID = 0 price = 5 status = PENDING paymentType = PayPalExpress orderID = price = status = paymentType = currentOrderID = 1 currentPaymentID = 1 currentSessionID = 1 currentTokenID = 1 customer = Attacker orderID = 0 ExpResults[ 0 ] = Pay_SucceededExpResults[ ] = Program Variables Attacker Variables 42 5. Store Redirects to Update Order Status Store_UpdateOrderStatus((ORDERID), mySessionID); Attacker stops the redirect from loading (can intercept with a proxy to do this) Attacker now has session from cheap order stored with successful payment results 0
43
6. Create Expensive Order (Second Session) In a new tab or second browser, the Attacker starts a second order Expensive items are added to the cart 43
44
Attacker adds cheap items to cart store.com/checkout?price&PayPalExpress PayPal.com/setExpressCheckout?StoreID token Redirect to : PayPal.com/pay?token&payerID PayPal.com/pay?token&payerID PayPal.com/doExpressPayment?StoreID&payerID result store.com/finishOrder?token&payerID&sessionID Redirect to: store.com/finishOrder?token&payerID&sessionID Attacker stops the redirect from loading (can intercept with a proxy to do this) Attacker now has session from cheap order stored with successful payment results Redirect to: store.com/updateOrderStatus?(ORDERID)=0&sessionID=0 store.com/updateOrderStatus?(ORDERID)=0&sessionID=0 Attacker adds Expensive items to cart 6. Create Expensive Order (Second Session) Attacker creates a second session in a new tab or second browser 44
45
myCustomer = AttackermyPrice = 5mySessionID = 0myTokenID = 0(ORDERID) = 0 Session 1 (Cheap Order)Session 2 (Expensive Order)Payment and other Variables carts[ 0 ] =carts[ ] =payments[ 0 ] = price = 5price = payerID = Attacker recipientID = StoreID paymentAmount = 5 paymentType = PayPalExpress orderID = 0 tokens[ 0 ] =tokens[ ] = recipientID = StoreID payerID = Attacker recipientID = payerID = orders[ 0 ] =orders[ ] = orderID = 0 price = 5 status = PENDING paymentType = PayPalExpress orderID = price = status = paymentType = currentOrderID = 1 currentPaymentID = 1 currentSessionID = 1 currentTokenID = 1 customer = Attacker ExpResults[ 0 ] = Pay_SucceededExpResults[ ] = Program Variables Attacker Variables 6. Create Expensive Order myPrice = 200; mySessionID = 1; 45 2001
46
7. Checkout Expensive Order On the merchant website, the Attacker clicks the checkout button On the merchants’ server side, a cart object is created – Is linked to the sessionID 46
47
store.com/checkout?price&PayPalExpress store.com/updateOrderStatus?(ORDERID)=0&sessionID=0 Attacker adds Expensive items to cart 7. Checkout Expensive Order 47
48
Session 1 (Cheap Order)Session 2 (Expensive Order)Payment and other Variables carts[ 0 ] =carts[ ] =payments[ 0 ] = price = 5price = payerID = Attacker recipientID = StoreID paymentAmount = 5 paymentType = PayPalExpress orderID = 0 tokens[ 0 ] =tokens[ ] = recipientID = StoreID payerID = Attacker recipientID = payerID = orders[ 0 ] =orders[ ] = orderID = 0 price = 5 status = PENDING paymentType = PayPalExpress orderID = price = status = paymentType = currentOrderID = 1 currentPaymentID = 1 currentSessionID = 1 currentTokenID = 1 customer = Attacker ExpResults[ 0 ] = Pay_SucceededExpResults[ ] = Program Variables Attacker Variables 7. Checkout Expensive Order createCart(myPrice) carts[currentSessionID].price = myPrice; ExpResults[currentSessionID] = Pay_NotHappened; currentSessionID++; Store_checkout(myPrice,PayPalExpress) 1 200 Pay_NotHappened1 2 48 myCustomer = AttackermyPrice = 200mySessionID = 1myTokenID = 0(ORDERID) = 0
49
7.a During Checkout: Store Gets PayPal Token On the merchants’ server side, a call is made to PayPal Express API method to request a token for the transaction A token is returned to the merchants’ server The Attacker does not have access to this communication; it is directly between the merchant and PayPal Express 49
50
store.com/checkout?price&PayPalExpress PayPal.com/setExpressCheckout?StoreID token store.com/updateOrderStatus?(ORDERID)=0&sessionID=0 Attacker adds Expensive items to cart 7.a During Checkout: Store Gets PayPal Token 50
51
Session 1 (Cheap Order)Session 2 (Expensive Order)Payment and other Variables carts[ 0 ] =carts[ 1 ] =payments[ 0 ] = price = 5price = 200 payerID = Attacker recipientID = StoreID paymentAmount = 5 paymentType = PayPalExpress orderID = 0 tokens[ 0 ] =tokens[ ] = recipientID = StoreID payerID = Attacker recipientID = payerID = orders[ 0 ] =orders[ ] = orderID = 0 price = 5 status = PENDING paymentType = PayPalExpress orderID = price = status = paymentType = currentOrderID = 1 currentPaymentID = 1 currentSessionID = 1 currentTokenID = 1 customer = Attacker ExpResults[ 0 ] = Pay_SucceededExpResults[ 1 ] = Pay_NotHappened myCustomer = AttackermyPrice = 200mySessionID = 1myTokenID = 0(ORDERID) = 0 Program Variables Attacker Variables PayPal_setExpressCheckout(StoreID); tokens[currentTokenID].payer = Not Set; tokens[currentTokenID].recipientID = StoreID; currentTokenID++; StoreID 1 Not Set 2 //payer not valid yet 7.a During Checkout: Store Gets PayPal Token 51
52
8. Store Redirects to PayPal. Attacker Skips Payment The merchant redirects the Attacker to PayPal Express to make a payment – Attacker does not pay for the order The token received from PayPal Express in step 2.a is included as a parameter in this new page request 52
53
store.com/checkout?price&PayPalExpress PayPal.com/setExpressCheckout?StoreID token Redirect to : PayPal.com/pay?token&payerID PayPal.com/pay?token&payerID store.com/updateOrderStatus?(ORDERID)=0&sessionID=0 Attacker adds Expensive items to cart 8. Store Redirects to PayPal. Attacker Skips Payment Attacker skips payment 53
54
Session 1 (Cheap Order)Session 2 (Expensive Order)Payment and other Variables carts[ 0 ] =carts[ 1 ] =payments[ 0 ] = price = 5price = 200 payerID = Attacker recipientID = StoreID paymentAmount = 5 paymentType = PayPalExpress orderID = 0 tokens[ 0 ] =tokens[ ] = recipientID = StoreID payerID = Attacker recipientID = payerID = orders[ 0 ] =orders[ ] = orderID = 0 price = 5 status = PENDING paymentType = PayPalExpress orderID = price = status = paymentType = currentOrderID = 1 currentPaymentID = 1 currentSessionID = 1 currentTokenID = 1 customer = Attacker ExpResults[ 0 ] = Pay_SucceededExpResults[ 1 ] = Pay_NotHappened myCustomer = AttackermyPrice = 200mySessionID = 1myTokenID = 0(ORDERID) = 0 Program Variables Attacker Variables StoreID 1 Not Set 2 54 1 8. Store Redirects to PayPal. Attacker Skips Payment PayPal_Pay(myTokenID, myCustomer); Attacker skips payment
55
9. PayPal Redirects to Store. Store Still Creates Order Payment is not made, but PayPal Express still redirects the Attacker back to the merchant to continue the checkout process The merchant creates an order object on the server – The payment status of the order is set to pending – Price is retrieved from cart stored on the server, not from an API parameter – Is not linked to the sessionID 55
56
store.com/checkout?price&PayPalExpress PayPal.com/setExpressCheckout?StoreID token Redirect to : PayPal.com/pay?token&payerID PayPal.com/pay?token&payerID store.com/finishOrder?token&payerID&sessionID Redirect to: store.com/finishOrder?token&payerID&sessionID store.com/updateOrderStatus?(ORDERID)=0&sessionID=0 Attacker adds Expensive items to cart 9. PayPal Redirects to Store. Store Still Creates Order 56
57
Session 1 (Cheap Order)Session 2 (Expensive Order)Payment and other Variables carts[ 0 ] =carts[ 1 ] =payments[ 0 ] = price = 5price = 200 payerID = Attacker recipientID = StoreID paymentAmount = 5 paymentType = PayPalExpress orderID = 0 tokens[ 0 ] =tokens[ 1 ] = recipientID = StoreID payerID = Attacker recipientID = StoreID payerID = Not_Set orders[ 0 ] =orders[ ] = orderID = 0 price = 5 status = PENDING paymentType = PayPalExpress orderID = price = status = paymentType = currentOrderID = 1 currentPaymentID = 1 currentSessionID = 1 currentTokenID = 2 customer = Attacker ExpResults[ 0 ] = Pay_SucceededExpResults[ 1 ] = Pay_NotHappened myCustomer = AttackermyPrice = 200mySessionID = 1myTokenID = 1(ORDERID) = 0 Program Variables Attacker Variables 9. Store Creates Order Store_finishOrder(myTokenID, myCustomer, mySessionID); orderID = createOrder( carts[mySessionID].price, PENDING, PayPalExpress); if (mySessionID = currentSessionID) return;//if invalid sessionID orders[currentOrderID].orderID = currentOrderID; orders[currentOrderID].price = carts[mySessionID].price; orders[currentOrderID].status = PENDING; orders[currentOrderID].paymentType = PayPalExpress currentOrderID++; return currentOrderID-1; orderID = 1 1 200 PENDING PayPalExpress 1 2 57
58
9.a Store Checks if Payment was Made The merchant asks PayPal Express if payment was made PayPal Express records the payment on their server PayPal Express returns the result of payment – Payment Failed – Is linked to the sessionID The merchant digitally signs an orderID with information about the order, whether or not payment suceeded 58
59
store.com/checkout?price&PayPalExpress PayPal.com/setExpressCheckout?StoreID token Redirect to : PayPal.com/pay?token&payerID PayPal.com/pay?token&payerID PayPal.com/doExpressPayment?StoreID&payerID result (payment failed) store.com/finishOrder?token&payerID&sessionID Redirect to: store.com/finishOrder?token&payerID&sessionID store.com/updateOrderStatus?(ORDERID)=0&sessionID=0 Attacker adds Expensive items to cart 9.a Store Checks if Payment was Made 59
60
Session 1 (Cheap Order)Session 2 (Expensive Order)Payment and other Variables carts[ 0 ] =carts[ 1 ] =payments[ 0 ] = price = 5price = 200 payerID = Attacker recipientID = StoreID paymentAmount = 5 paymentType = PayPalExpress orderID = 0 tokens[ 0 ] =tokens[ 1 ] = recipientID = StoreID payerID = Attacker recipientID = StoreID payerID = Not_Set orders[ 0 ] =orders[ 1 ] = orderID = 0 price = 5 status = PENDING paymentType = PayPalExpress orderID = 1 price = 200 status = PENDING paymentType = PayPal_Express currentOrderID = 2 currentPaymentID = 1 currentSessionID = 1 currentTokenID = 2 customer = Attacker orderID = 1 ExpResults[ 0 ] = Pay_SucceededExpResults[ 1 ] = Pay_NotHappened myCustomer = AttackermyPrice = 200mySessionID = 1myTokenID = 1(ORDERID) = 0 Program Variables Attacker Variables 9.a Store Checks if Payment was Made ExpResults[mySessionID] = PayPal_DoExpressPayment(myCustomer, StoreID, myTokenID, orderID, carts[mySessionID].price); if (myTokenID = currentTokenID) return Pay_Failed;//if tokenID invalid if (tokens[myTokenID].payerID == Not_Set) return Pay_Failed;//payer not confirmed Pay_Failed 60 sign(orderID );
61
10. Store Redirects to Update Order Status After checking payment status with PayPal Express, the merchant redirects the Attacker to a final merchant page to complete the transaction – Signed (ORDERID) is included as a parameter Order not completed because payment failed\ – Attacker still has access to the signed (ORDERID) parameter 61
62
store.com/checkout?price&PayPalExpress PayPal.com/setExpressCheckout?StoreID token Redirect to : PayPal.com/pay?token&payerID PayPal.com/pay?token&payerID PayPal.com/doExpressPayment?StoreID&payerID result (payment failed) store.com/finishOrder?token&payerID&sessionID Redirect to: store.com/finishOrder?token&payerID&sessionID Redirect to: store.com/updateOrderStatus?(ORDERID)=1&sessionID=1 store.com/updateOrderStatus?(ORDERID)=0&sessionID=0 Attacker adds Expensive items to cart 10. Store Redirects to Update Order Status store.com/updateOrderStatus?(ORDERID)=1&sessionID=1 Attacker still gets signed (ORDERID) with information about the expensive order Order not filled because payment verification failed 62
63
Session 1 (Cheap Order)Session 2 (Expensive Order)Payment and other Variables carts[ 0 ] =carts[ 1 ] =payments[ 0 ] = price = 5price = 200 payerID = Attacker recipientID = StoreID paymentAmount = 5 paymentType = PayPalExpress orderID = 0 tokens[ 0 ] =tokens[ 1 ] = recipientID = StoreID payerID = Attacker recipientID = StoreID payerID = Not_Set orders[ 0 ] =orders[ 1 ] = orderID = 0 price = 5 status = PENDING paymentType = PayPalExpress orderID = 1 price = 200 status = PENDING paymentType = PayPal_Express currentOrderID = 2 currentPaymentID = 1 currentSessionID = 1 currentTokenID = 2 customer = Attacker orderID = 1 ExpResults[ 0 ] = Pay_SucceededExpResults[ 1 ] = Pay_Failed myCustomer = AttackermyPrice = 200mySessionID = 1myTokenID = 1(ORDERID) = 0 Program Variables Attacker Variables Store_UpdateOrderStatus((ORDERID), mySessionID); if (mySessionID = currentSessionID) return;//if sessionID is invalid if ((ORDERID) = currentOrderID) return;//if orderID is invalid if (orders[(ORDERID)].paymentType != PayPalExpress) return; //if payment not from PayPalExp if (ExpResults[mySessionID] == Pay_NotHappened) return; //if payment not started if (ExpResults[mySessionID] == Pay_Failed) return;//Payment failed 63 1 10. Store Redirects to Update Order Status
64
11. Attacker Updates First Session with Second ORDERID Attacker returns to the first session from step 5, which was paused at the last step of the checkout process The signed (SESSIONID) from step 5 is replaced with the signed (SESSIONID) from step 10 The first session is resumed – Payment status is based on sessionID from cheap order, order information is based on signed (SESSIONID) from expensive order – Expensive order completed sucessfully 64
65
store.com/checkout?price&PayPalExpress PayPal.com/setExpressCheckout?StoreID token Redirect to : PayPal.com/pay?token&payerID PayPal.com/pay?token&payerID PayPal.com/doExpressPayment?StoreID&payerID result (payment failed) store.com/finishOrder?token&payerID&sessionID Redirect to: store.com/finishOrder?token&payerID&sessionID Redirect to: store.com/updateOrderStatus?(ORDERID)=1&sessionID=1 store.com/updateOrderStatus?(ORDERID)=0&sessionID=0 Attacker adds Expensive items to cart store.com/updateOrderStatus?(ORDERID)=1&sessionID=1 11. Attacker Updates First Session with Second ORDERID Attacker returns to first session with stored successful payment result, where they stopped the final webpage from loading Attacker replaces the first signed ORDERID with the second signed ORDERID by copying and pasting the value in the URL Attacker loads the webpage store.com/updateOrderStatus? (ORDERID)=0&sessionID=0 (ORDERID)=1 Expensive Purchase Completed 65
66
Session 1 (Cheap Order)Session 2 (Expensive Order)Payment and other Variables carts[ 0 ] =carts[ 1 ] =payments[ 0 ] = price = 5price = 200 payerID = Attacker recipientID = StoreID paymentAmount = 5 paymentType = PayPalExpress orderID = 0 tokens[ 0 ] =tokens[ 1 ] = recipientID = StoreID payerID = Attacker recipientID = StoreID payerID = Not_Set orders[ 0 ] =orders[ 1 ] = orderID = 0 price = 5 status = PENDING paymentType = PayPalExpress orderID = 1 price = 200 status = PENDING paymentType = PayPal_Express currentOrderID = 2 currentPaymentID = 1 currentSessionID = 1 currentTokenID = 2 customer = Attacker orderID = 1 ExpResults[ 0 ] = Pay_SucceededExpResults[ 1 ] = Pay_Failed myCustomer = AttackermyPrice = 200mySessionID = 1myTokenID = 1(ORDERID) = 1 Program Variables Attacker Variables mySessionID = 0; 0 11. Attacker Updates 1 st Session with 2 nd ORDERID 66
67
Session 1 (Cheap Order)Session 2 (Expensive Order)Payment and other Variables carts[ 0 ] =carts[ 1 ] =payments[ 0 ] = price = 5price = 200 payerID = Attacker recipientID = StoreID paymentAmount = 5 paymentType = PayPalExpress orderID = 0 tokens[ 0 ] =tokens[ 1 ] = recipientID = StoreID payerID = Attacker recipientID = StoreID payerID = Not_Set orders[ 0 ] =orders[ 1 ] = orderID = 0 price = 5 status = PENDING paymentType = PayPalExpress orderID = 1 price = 200 status = PENDING paymentType = PayPal_Express currentOrderID = 2 currentPaymentID = 1 currentSessionID = 1 currentTokenID = 2 customer = Attacker orderID = 1 ExpResults[ 0 ] = Pay_SucceededExpResults[ 1 ] = Pay_Failed myCustomer = AttackermyPrice = 200mySessionID = 0myTokenID = 1(ORDERID) = 1 Program Variables Attacker Variables Store_UpdateOrderStatus((ORDERID), mySessionID); if (mySessionID = currentSessionID) return;//if sessionID is invalid if ((ORDERID) = currentOrderID) return;//if orderID is invalid if (orders[(ORDERID)].paymentType != PayPalExpress) return; //if payment not from PayPalExp if (ExpResults[mySessionID] == Pay_NotHappened) return; //if payment not started if (ExpResults[mySessionID] == Pay_Failed) return; orders[(ORDERID)].status = PAID; //if payment failed ExpResults[mySessionID] = Pay_NotHappened; //Clear the payment result PAID Pay_NotHappened 11. Attacker Updates 1 st Session with 2 nd ORDERID 67
68
Why Does This Work?
69
What Interspire Did Right Steps 2 & 7 – Sets payment status for session as not paid Steps 4 & 9 – Verified sessionID value – Price retrieved from a cart object stored on the server side, not from the unsigned price parameter in the URL This is why only the (ORDERID) parameter needs to be signed Steps 4.a & 9.a – Verified with PayPal that payment was made, using price stored in cart on server side, not from the unsigned price parameter in the URL – Result parameter from PayPal is never seen by the user 69
70
What Interspire Did Right Step 11 – Verified sessionID value – Verified (ORDERID) – Verified payment was attempted – Verified payment did not fail – Session payment status was cleared after order updated to PAID Prevents replay attacks 70
71
What PayPal Did Right Steps 2.a and 7.a – In token returned to Store, payerID set to “not set” Step 3 – Verified tokenID Steps 4.a & 9.a – Verified tokenID – Verified payerID was set – Verified the payer is same as the customer on the Store website Prevent an attacker stealing a customers active session 71
72
What Interspire Did Wrong Steps 9.a & 10 – If payment verification from PayPal shows the payment failed in step 9.a, the Store still creates a signed ORDERID Step 11 – (ORDERID) not associated with a sessionID – Doesn’t verify payment amount made to PayPal is the same amount as the price stored in the order 72
73
Fixing the Logic Flaw Connect the orderID and sessionID: In step 4 and 9, can add another field in the Order object to store the sessionID In step 10, compare the users’ sessionID to orders[(ORDERID)].sessionID – If they don’t match, return 73
74
Fixing the Logic Flaw Verify the payment amount with the price of the order: The PayPal Express API method DoExpressPayment in steps 4.a and 9.a also returns the payment amount* A second field could be added to the Expected Results object, to store the payment amount along with the payment status in steps 4.a and 9.a In step 10 compare orders[(ORDERID)].price to ExpResults[mySessionID].paymentAmount – If they don’t match, return 74 *https://developer.paypal.com/docs/classic/api/merchant/DoExpressCheckoutPay ment_API_Operation_NVP/
75
Fixing the Logic Flaw Don’t provide a correct signed (ORDERID) variable if payment failed: In steps 4.a and 9.a, if the payment status returned from PayPal_DoExpressPayment is Pay_Failed – Don’t send the (ORDERID) parameter when calling UpdateOrderStatus in step 10 Modify the UpdateOrderStatus method to accept a null value – Set the ORDERID to an invalid number, and still sign it UpdateOrderStatus method already checks for invalid values 75
76
Resources R. Wang, S. Chen, X. Wang, S. Qadeer, "How to Shop for Free Online: Security Analysis of Cashier-as-a-Service Based Web Stores," in 2011 IEEE Symposium on Security and Privacy (SP), 22-25 May 2011, Berkeley, CA, pp. 465-480. [Online]. Available: IEEE Xplore, doi: 10.1109/SP.2011.26 76
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.