skip to Main Content

Basically my question is similar to this one:

How to secure php scripts?

with one slight difference, the other side is Shopify.

Background info:
Shopify user bought some credits (Audible style), and wants to know how many he has available. He logs in into his account, and it says there that he has X credits.

That number comes from AJAX call to my server (I have full control), where there is a simple php script which checks the value in db (which is updated using webhooks from Shopify, each of which needs to be verified so they are secure, I think).

The script uses customers ID for a look up, and that value needs to be passed to the script somehow, and that allows someone external to just keep running it until he has all IDs and corresponding credits values.

So, my questions is, how do I stop that? How do I ensure that only authenticated users can check it, and only for their IDs.

There is plenty of info on Shopify docs about securing the connections the other way, i.e. to make sure only correct scripts have access to the Shopify db, but nothing about my problem.

As far as I know I only I only have access to JS on Shopify, which creates the problem, because everything I send to my server is visible to all.

Thanks

EDIT: I just read up on CSRF. I can easily implement checks for origin and headers, but these can be faked, right?

EDIT 2: I got around this problem by using metafields. So, instead of storing all that info on my server’s db, I just use Customer Metafields to store the available credits. Webhooks are secure so that’s brilliant. It still doesn’t solve a problem with the next stage though. Customers will still need to be able to use their credits and get digital products, which are generated by my server. So I still need to verify the requests.

EDIT 3: Comment by @deceze and answer by @Jilu got me thinking. Yes, you are correct, I need to do that, but I don’t have access to back-end on Shopify, so I cannot create session. However, what I could do (if I figure out how in js) is hash it. PHP login scripts operate on password_hash. That way you do not store a password in the db. Password get’s verified again hash (or whatever you call) in the db, and it’s either true or false. If true, you are logged in. So I could try to generate a token using a specific string (make it very long) and user id. Send it with the request, and using password_verify or what not, check it against the users. The one that pops positive is logged in user who requested the information. That is assuming I can hide the string in the Shopify…

2

Answers


  1. Chosen as BEST ANSWER

    You create a token out of shared secret (both Shopify and server have it), and client ID.

    On Shopify:

    {% assign my_secret_string = "ShopifyIsAwesome!" | hmac_sha256: "secret_key" %}
    My encoded string is: {{ my_secret_string }}
    

    On server:

    We gonna be checking received hash value against values in our db, so we need to hash local client IDs using the same algo and key (that probably should be done on receiving the Customer Creation webhook).

    Hash IDs using: http://php.net/manual/en/function.hash-hmac.php

    $hashed_id = hash_hmac('sha256', '$client_id', 'secret_key');
    

    Compare hash using: http://php.net/manual/en/function.hash-equals.php

    $check = hash_equals($hashed_id, $received_id);
    

    Then all that's requires is to loop through the db until you find a match. There may be quicker ways of doing it.


  2. Step1: Do a session login system.
    Step2: Before the Ajax, generate a random token in your form or request page, put it into a input display none, send it with POST.
    Verify each time if the token is set and is the same that you got.

    You have now verified if the user is really logged in with session.
    And you checked that he is from the right page.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search