Shopify app access token - how to make it more secure? - shopify

When store owner installs my app I save access tokens into database for later use. Having access tokens from store is huge security responsibility because anybody with these tokens can modify stores from any domain/address, there is no ip or domain lock.
What method could I use to make this more secure? I was thinking to save tokens offline and then upload it only when needed (in case I need to make some global updates for all stores), then delete it again. In case when merchant access app configuration within admin, I would just save it into session. Is there any better method?

Good question.
I save them in a database as well but I encode them with a separate key from the Shopify App password. That way even if someone have access to the database because of some backdoor entrance he won't be able to use them. That said if someone have access to the code he will be able to figure out how to decrypt it since he will have access to the key.
That said I make sure that each and every request is authenticated before I show any response from the server. Since I'm using NodeJS as the back-end I make sure that there are no global variables that can be accessed or modified from different stores. Everything is neatly scoped in separated functions so that the session is scoped for the current store and no other ones will be able to dirty the other store session.
In addition I make sure that there is a webhook that fires when the client uninstall his app in order to clear my database from any information regrading his store.
I know some people are using sessions for this ( online method ) but they pose other problems that I didn't like so I stuck with a database ( offline ) since that is the quicker way to access the App instead of multiply redirects in order to save the session.
As for proposals I can give you a few tips that I learn on my way while building a few basic Apps. ( I'm not an expert on the subject by any means )
don't rely on any cookies when it comes to sensible information
authenticate every request that comes from the front-end
don't trust the user and validate any input that comes from the front-end
don't over-complicate your setup, while it's good to have high security it's bad if it makes your app slow for the user and you lose customers
look to other ready to use popular solutions that can guide you to the correct path
don't get greedy with the App scopes, only request the scopes that you need for you app
remember to clean up after yourself when it's possible but don't over do it ( too many Apps modify the code of customers and break it only to prevent any way to clean it afterwards ) Example use the ScriptTag API instead of a liquid snippet using the Asset API. If you have to use the Asset API add only the parts that you know that won't break a site. Creating a variable is ok if you are using var if the site supports IE11 creating a variable using const or let is not OK or using vanilla JS is OK but using jQuery without knowing for sure that the site has it installed globally is not OK.
More insights on the matter can be seen here:
https://help.shopify.com/en/api/getting-started/authentication/oauth/api-access-modes
https://community.shopify.com/c/Shopify-APIs-SDKs/Best-way-to-store-shops-that-have-installed-my-app-and-their/m-p/402972

Related

How to store and use multiple users' keys for third party client

I want to build web app that uses Spotify API. I got case where user has to authenticate with his spotify account, then I recive access and refresh token that is being used in code to authenticate calls to Spotify to perform some actions on user's account.
I have trouble deciding how it should be really done. First thing that came to my mind - store them in Redis for some time, update on refresh and whenever we need to perform some action on any user we get his credentials and do it. Is this proper way? I tough about simply storing them in app memory but I might want to make in serverless.
Did anyone come accross that kind of problem? Do anyone know how to do it 'properly'.

Storing API Keys submitted by client in frontend

I know API keys need to be stored securely and should not be accessible client side. That being said, I also know that a lot of Wordpress plugins/ custom sites/ and such allow users to copy paste the API key into a text input on the admin panel.
My question is how do you do this securely? Do they hash it and save it to their database?
Say for example I made a react app or wordpress plugin that allowed users to do something with the Google Maps API. I know I can go get their API key and just hard code it in... but if I wanted to let the user update the key on their own - What would be the reccomended steps?
Thanks!
If I understand you correctly, you want your application to process secrets of third party APIs. A bit scary, but if you get the user consent - why not? First thing first - make sure the user understands what he is doing. Point out exactly what you will do with the API keys, what you will not do with the API keys and how will they be protected.
Personally I would never want to store such secrets in my own database, as this would be a single point of failure. When you are hacked, everyone is hacked. Why not put such secrets in - say - local storage so it never touches one of your servers?
Ok, in case it is your server that needs to do something, you could get the API key passed in a request, do something, but never log or persistently store the secret anywhere.
In case it is enough for the Java Script to do the job, local storage is even better solution.
One could think about encrypting the keys in the local storage, but I don't believe this would improve security a lot. I mean this would be security through obscurity and could by bypassed by someone with physical access to the machine/browser/user agent. But if someone would have such access, then probably some of the API keys would be one of the smaller problems.

GunDB user authentication and data storage among users

I have been following your project for quite some time now and am intrigued by the functionality of gunDB where it doesn't require a database in between and keeps security in check.
However, I've got some questions about GunDB which I've been thinking about for quite some time now before I can give Gun a go with a project I'm currently working on. In this project it is necessary that data is safe but should also be shareable once a group has been setup. The project is a mobile app project and ata is mostly stored on the device in a SQLite database.
I have been looking into Gun as it allows for better usage of the app in sense of collaboration. The questions I have, however, are:
User authentication
How is user authentication handled through private keys? So how can a user "register" with, for example, a username and password to login to the service.
For authentication I am currently using Firebase where it is possible to use username/password authentication and I would like to know how Gun approaches this case and how it's implemented.
Data storage
In the documentation and on the website it's stated that data is stored locally with every client and can be stored on a "node" or server using either a local hard drive or the Amazon S3 storage option.
What I am curious about is what data is actually stored at the client? Is this only the data he/she has access to or is this a copy of the whole dataset where the client can only access whatever he/she is granted to have access to?
Maintaining your data
When I've got a production system running with a lot of data, how will I be able to manage my data flows and/or help out my clients with issues they have in the system?
In other words, how can I make sure I can keep up with the system if I want to throw in an update and/or service my clients with data issues.
My main concern is the ability to synchronize their local storage correctly.
Those are all my questions for now.
Thank you very much in advance for providing some clarity on these subjects.
Best regards,
(Answered by Mark Nadal on Github: https://github.com/amark/gun/issues/398#issuecomment-320418285)
#sleever great to hear from you! Thanks for finally jumping into the discussion! :D
User Authentication,
this is currently in alpha. If you haven't already seen these links, check them out:
https://github.com/amark/gun/wiki/auth
http://gun.js.org/explainers/data/security.html
https://github.com/amark/gun/blob/master/sea.js#L23-L43
https://github.com/BrockAtkinson/login-riot-gun
If you have already, would love to either (A) get you to alpha test and help push things forward or (B) hear any specific questions you have about it. This thread is also a more at length discussion about alternative security API ideas: #321 .
Data storage.
Browser peers by default store the data that they subscribe to, not the full data set. You could ask it to store everything, but the browser wouldn't like that. Meanwhile NodeJS peers, especially if hooked up to S3 or others, would store all data and act as a backup.
Does this make data insecure? No, encryption should keep it secure, even if anybody/everybody stores it, the encryption makes it safe. (See [insert link to (1)] for more information).
Maintenance.
You would service your customers by deploying an update to your app code. It would not be ideal for your customers if you could meddle with their data directly. If they wanted you to do that, my recommendation would be that they change their password, give the new password to you, and you login and make any necessary changes. Why? Because if you have admin access to their data, their privacy is fundamentally violated.

React Native API Authentication: No username/password?

Apologies for the general nature of this question. Hoping this doesn't get shot down as "too broad", but oh well, here goes:
I'm writing a React Native app that is purely informational (medical information), with a Rails API for the back-end.
The first main question I have is whether its necessary (or a good idea) to use authentication at all. We don't want the user to have to enter any information to use it (username, password, etc). They should just be able to download the app and jump right in to use it and read the information it provides.
However, I'm thinking that I would at least want the API to only respond to someone hitting it from within the React Native app (or not? Is it considered a normal practice to have an API completely exposed in the case of an app like this which is purely information and doesn't have users, like a website?)
Second - at some point we may want to be able to store some simple preferences for that user (I.E., are they a patient or a doctor, so we can tailor the materials based on that / send them to a different home screen when the open the app). Wondering what strategy someone might use to store simple preferences if the user doesn't ever create an account?
I would at least want the API to only respond to someone hitting it
from within the React Native app.
This probably can't be done, as in a mobile app everyone has access to your client secret and can try to reverse engineer your code.
You could make it more difficult by sending a dynamically generated token to your API on the request, for example, a hash based on a time frame, and check if the hash was sent the correct way. Then, you'd have to obfuscate the code in order to make it difficult for someone to reverse engineer it.
Second - at some point we may want to be able to store some simple
preferences for that user (I.E., are they a patient or a doctor, so we
can tailor the materials based on that / send them to a different home
screen when the open the app). Wondering what strategy someone might
use to store simple preferences if the user doesn't ever create an
account?
If you use a Parse Server instance as your backend, you could benefit from the anonymous user functionality. As you're using a Rails API, you could generate a uuid for each installation of the app and save the preferences on your database based on that uuid. If you don't need those preferences stored on your backend, just store any information you need on the device through any abstraction of AsyncStorage.
I really do not need authentication when it comes down to it - there are no users.
I could verify that the data is coming from my app based on a user agent or a hard coded password. SSL should help keep those secret.
But yeah, there would be nothing preventing someone from disassembling the app and getting that information. Great idea by #felipe-martim about generating a dynamic token.
I really just want to prevent basic abuse, and I could deal with that if it ever happened, or protect myself with something like Rack-attack.
And storing user preferences locally should work just fine for local preferences.
Bottom line is that I'll deal with this if I ever need to / the client budget allows for it!

secure the code in google chrome extension

I want to write a google chrome extension, that should make a request to my website to send and get some data, so, actually I should do an ajax request like it is written here https://developer.chrome.com/extensions/xhr.html
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://api.example.com/data.json", true);
I wanted ask if there is a way to somehow secure the code or prevent others from using my api, because actually the other users can see the source code of the extension when they install it and so use my api without me being aware of it.
EDIT:
If I need to make some sort of authentication, than how can I authenticate the user before making the ajax call ? for authentication I will need to send a request to my server , but for that I should send , e.g. username and password, that should be saved somewhere in the extension's files, which, in fact, can be seen by the users, when they install the extension.
Thanks
Don't trust the browser, take steps to authenticate the user instead. So, in this case, you could require that YOU enter in a password that is used to communicate with your server.
Your Google extension would simple require you to enter in a password before it attempts to use AJAX to communicate with your server.
Be aware that you should build in means of protecting yourself from brute-force attacks. So, do things like lock everything down if there are more than some small number of wrong passwords, etc.
You could also consider using the password to simply decrypt the destination of the XHR, but if you go this route, you should store this very carefully, because this will be brute-forceable offline.
EDIT
Trying to lock down an API so that only a single application can use it is just not practical nor technically possible, so you're only hope of doing this is to authenticate the user using the API, regardless of the accessing software he is using. You could have the user sign an agreement that legally limits them to only your extension, but I suspect this will go largely unenforceable and will consume your time tracking abusers down.
If you don't want unauthorized people even knowing where the API is, you could perform authentication using an out-of-band mechanism: over the telephone, email, SMS, or simply, another API that will grant the user a password or token that requests to your API must be accompanied with.
During this out-of-band process, you could also grant the user, a unique URI (the API access point) that is only valid per authenticated session (https://api.totally-cool-extension.com/api/ijyeDvB5dYvSiWG97OLuTAoNWwbhuZ0/, for example). Any requests to your server on OTHER URIs simply won't work. However, this isn't theoretically much different than using the same API access point, and having a good password. It just changes the number of places in your architecture that will be performing authentication and/or authorization checks.
<aside>My vote would be to reduce the number of authorization/authentication points to as few as possible so that you can spend more time on getting that one place correct rather than having multiple places and possibly multiple logic flaws or other things that could lead to vulnerabilities.</aside>
You could also explore using Public Key Infrastructure and/or one-time passwords schemes or device-based token generators, etc., but in the end, you'll be allowing authenticated and authorized users to use your API. And, thanks to the Internet, this will not remain an undisclosed URI for long.
And, more importantly, it will not prevent someone from using the data on their own. Even with all these measures in place, it would be trivial for an authorized user to collect this data as it is being streamed to your extension. Or, if you employ point-to-point encryption, they could screen-scrap or use some form of JS introspection on your very code or even extract the data from their computer's memory.
I know you were looking for a silver bullet here, but it doesn't exist.
I think you are doing it wrong. You should never trust what's going on on internet users PC's. Never!
Move the line of trust one step inward, make your API public and then design the security where you have perfect control - server side.
I could not get correct aspect of your use case
Few Points:
Your extension code is always traceable( Any one who has installed extension can view the code)
If you are looking for security through complicated or obfuscated coding patterns you end up slow down of understanding process not the whole.
If your target is to ensure users who install your extension should be able to access and inert all other users( Who have gained illegal access or downloaded and edited code) have a session shared key per installation.
Please explain further use case so i can help you better.