How to create/use environment variables for API Secret Keys in Shopify/Liquid? - api

I am trying to use the ipapi API (https://ipapi.com/documentation) to get the geolocation data of users and I have an API key which I will need to use to make the API call to get the JSON results.
In nodejs, we can use .env to store secret keys and access them with process.env.KEY_NAME. The same goes for servers such as Heroku and AWS, where we can store an API keys as config vars.
But for shopify, I can't seem to find out where to store secret API keys.
I have read some examples:
How to define global variables in Liquid? (this doesn't seem like the right thing to do as I want to store it as a secret and access it from another file).
https://devcenter.heroku.com/articles/config-vars (only for themekit/slate development).
Is it safe to just create another .liquid file and place all my secret keys there and just call it from another file?
Would appreciate if someone could point me the right direction.
Thank you!

You cannot hide secret API keys in Shopify. Instead, if you want to use a service that is secret, you can install your own custom App in the store, and use the App Proxy callback to call your App. Your App can then use secrets to make secret key API calls, and then that data is returned to the store front for use.
On the other hand, for something trivial like calling a geolocation service, you probably have the option to just call them with a public token assigned to your account, no secret. So you'd just use that, and not worry.

Related

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.

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

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

How are api keys stored securely in mobile apps?

I am trying to build a woocommerce frontend mobile app (ionic) using the woocommerce-api.
I have to make the api key be able to read AND write so that people can place orders.
The api key is used to get any data from the store (backend) like product images, names, etc...
If someone got a hold on the api secret key he can do whatever he wants to my woocommerce store, erase products, add products, or anything.
The following is the part I dont understand:
If I store my keys on a server, and write a method to retrieve them whenever a user uses my app, what is stopping anyone from reverse engineering my app and using the calling the same method to retrieve my api key and then proceeding to do whatever they want?
Example 1 (api stored in client-side)
1- hacker reads my source code.
2- hacker reads my api secret key.
3- hacker writes a fake app to mess with my store.
Example 2 (api stored in server)
1- hacker reads my source code.
2- hacker finds out my function "GetApiFromServer()"
3- hacker uses write a fake app with the same GetApiFromServer() function.
4- hacker messes with my store.
What is the difference? is there something I am missing?

Where to keep private keys and credentials for a web app?

I have a webapp that uses keys and credentials to call API endpoints from external services like payment gateways, database providers, and such.
I have these options in mind to keep these values:
Set environmental variables before app start and load them when the app runs. If required values are not available, e.g. not set, exit the app.
On app start, ask user (myself or an administrator) to enter the credentials. If required fields are empty, exit, otherwise continue loading the app.
Keep them in a config file as plain values. This is the least preferable way as to me.
Which of these should I use if I want to keep keys as safe and secure as possible?
I would go with user environment variables, as it is recommended by both google and amazon.
If you go for storing in plain text files, remember to not keep them in your app's source tree (if you use some version control, you may end up exposing them to public).
Also, remember to regenerate your keys periodically.
I think you should, as you said, use configuration files. And maybe encrypt it ?
If you have lots of keys to manage, environment variables get clumsy. A hybrid approach works for me: encrypt the secrets and put them all in config (typically as base64). Use the same encryption key for all of them, and pass it in as an environment variable.
So you only need to make one environment variable to secure as many other secrets as you need.

How to use the Photobucket REST API?

Has anyone successfully used the Photobucket REST API? According to the pathetic docs, it requires OAuth authorization, which would require a consumer key and secret, but registering an app gives you but a single developer key, which I have no idea what to do with.
If you go into photobucket and go to your application and view the details, you will see there is a developer key and what they call a 'private' key. I would assume this is the secret you are looking for. If you manage to make a successful call to the photobucket API, I would appreciate if you could provide the URL you used (anonymize anything private like the signature, of course)