Signing/Hashing Inside Scripts

Dev_Gupta
Shopify Partner
2 0 2

I'm trying to write a script that allows bundle pricing, something like:

Product A costs $100
Product B costs $200
Product A costs $75 if B is in the cart
Product B costs $150 if A is in the cart

Writing the above script is fairly straightforward, but gets difficult to manage as soon as you start adding a few more combinations and permutations.

We have an outside server that can handle managing and calculating all of the various prices, and were picturing an architecture like this:

  1. User on our store website takes an action to modify their cart
  2. Before modifying cart, we submit it to our own server
  3. The server looks through all items, calculates what their new price should be, and attaches those new prices as custom line item properties.
  4. We then digitally sign our cart. This can be accomplished in a variety of ways, ideally we'd use a popular standard like JWT. This step ensures that the cart our server has sent to be processed by the script editor app hasn't been tampered with or modified en route. Security is a very big concern, because we want to make sure we don't allow the user to arbitrarily change prices.
  5. Our store's front-end code takes the response from our server, and submits it to Shopify via its AJAX cart API.
  6. Shopify runs the cart through our published script.
  7. Our script compares the signature provided by our server against what it generates on its own. If they don't match, it rejects the request, and if they do, it applies all the new prices.

Where this all falls down is in being able to generate a signature from inside Shopify's script editor. From my understanding, you cannot use any 3rd party gems or require any modules from within the script, including Ruby's standard library. That would mean having to roll our own hashing and signing solution, which seems quite daunting.

Does anybody have suggestions on alternate ways of being able to have an external service pass instructions to the script editor in a secure manner? Is there a chance the scripts team could make some kind of one way hashing function available from within the script? Are there solutions outside of the script editor that would allow us to modify
the price of an item depending on what else is in the cart? Thanks!
 

Zetya_Gavin
Shopify Partner
1247 6 96

generate a signature from inside Shopify's script editor

You might be able to take advantage of this upstream of the script: https://help.shopify.com/themes/liquid/filters/string-filters#hmac_sha256

www.bookthatapp.com
0 Likes
HunkyBill
Shopify Expert
4359 36 462

That would be cool. If your services generates the hash from the cart and provides the resulting hash as a key the checkout has access to, and the script tag editor validates it, it means we can all use that pattern and get rid of all those awful bundler Apps that fail in so many ways!

A hack for sure, but it would go a long way to allowing merchants to offer bundles and not screw up their inventory! Amaze Balls. Must keep us informed if this little hack works!

 

Custom Shopify Apps built just for you! hunkybill@gmail.com http://www.resistorsoftware.com
0 Likes
Dev_Gupta
Shopify Partner
2 0 2

Thanks for your responses. Gavin, those hashing functions seem useful (we also have them available on our own app servers to create the cart object), but once inside the black box of the script editor, we have no way to securely compare signatures and see if the payload is valid, at least not one I can see. If any of those liquid filters were available as functions within the editor, we'd have something viable.

The only other thing I can think of is if the Shopify API offered some way to alter a cart on the server side, a property that cannot be modified from the front-end, but is available to the script editor to compare. Then we could set something like "calculated_cart_total" to make sure all is as it should be.

0 Likes
evaldas_92
Excursionist
19 0 4

There still does not appear to be a way to calculate an hmac in Shopify Scripts?

The use case is very simple:

- Add cart line properties in Liquid
- Calculate an HMAC/SHA256 using liquid filter for properties added and add it as well
- In Shopify Scripts, recalculate the hmac/sha256 and compare with with the hmac in cart line properties to make sure properties have not been tinkered with

Only the last bit seems to be missing. 

Liquid example:

evaldas_92_0-1608298952931.png

 

0 Likes
PaulNewton
Shopify Partner
2579 134 440

@evaldas_92 wrote:

There still does not appear to be a way to calculate an hmac in Shopify Scripts?

The use case is very simple:

- Add cart line properties in Liquid
- Calculate an HMAC/SHA256 using liquid filter for properties added and add it as well


The liquid string concatenation in the example image still has a high chance of sign collision, apply the customer.id if available, or the cart.token(JSON)  adding it as cart attribute through javascript

This is also good use case for why scripts should be able to access cart attributes as cart level information should not be dependent on individual items.

Currently shopify scripts does not allow access to that OR a documented way to create reliable signatures or get something like current time for more unique hashes.

 

 


@evaldas_92 wrote:

- In Shopify Scripts, recalculate the hmac/sha256 and compare with with the hmac in cart line properties to make sure properties have not been tinkered with

Only the last bit seems to be missing. 

 


There's not a clear list of what ruby features are explicitly available|unavailable in checkoutscripts but sha-256 is mostly a conversion to binary -> padding > prime number constants...etc

So hypothetically if critical you may want to work out if you can just rebuild the sha algorithm in a checkoutscript.

Might get stopped at the chunking step that needs to know when you have 512bits, and the binary XOR ?

https://en.wikipedia.org/wiki/SHA-2#Pseudocode

https://qvault.io/2020/07/08/how-sha-2-works-step-by-step-sha-256/

And there's a good chance any script that figures that out will probably hit perf caps from the compression steps /bigshrug.

Problem Solved? ✔️Accept and ? Like the solution so you can help others.
Buy me a coffee ☕ paypal.me/paulnewton or donate to eff.org
Confused? Busy? Buy a custom solution paull.newton+shopifyforum@gmail.com
0 Likes