Public Google Apps Script - how can I make my API key hidden but still retrieve it? - security

I have a script that retrieves a webhook (meaning it has to be deployed as a publicly accessible App), and then uses an API to send a message.
The API requires using a key and secret, which I obviously don't want accessible to the public.
Q1: Is there a way to hide an API key/secret in another script and somehow have it accessible?
(Or any other similar solution - doesn't have to be fancy, just functional/safe).
Alternate Question:
Q2: What can a stranger actually see in my public Apps Script project? The full code? If I hide keys in a functions with an underscore ie. function name_(){}, can they read it?
IMPORTANT INFO: I have not 'shared' the project or spreadsheets with anyone, they're still private. But I've 'deployed' the Web App with permissions for 'anyone'. I assume that means anyone can access?

Everything in the script is visible to whoever has access (script owner, workspace admins, added users). Unless only the url of the webapp is shared and if the script itself is not shared then they are not able to access the script, so technically you can still keep them in your script. It is safe there and only the owner and workspace admins (if it is for Google workspace) can access it.
A way you can store/save the key is by storing it in script properties. Doing this you only need to run the script once to store the API key, moving forward you can remove the API key from the script and it will still run:
https://developers.google.com/apps-script/guides/properties#saving_data
Also refer to this post for more information, in my posted answer I have also provided alternatives and reference links:
Is it safe to put in secrets inside Google App Script code?

My project meet this issue, too. Because the amount of functions is not too much , So i hide my main GAS behind an dummy one .
So far I had 2 GAS
the main GAS with key , and all functions , and I deploy it as Web APP
Of cause u need doGet or doPost to do as entrance of API
The dummy one to share with users.
Then you can call something like below in dummy GAS
var url = 'https://script.google.com/macros/s/xxxxxxxxxxx/exec';
UrlFetchApp.fetch(url,{'method': 'get'});
I hope its useful in your case.

Related

Is it safe to use fetch with credentials from a content script?

Consider this scenario:
A content script wants to upload a file. I would prefer this operation to be done from my service/background script, but passing a File to that side via messages seems to be somewhat impossible without weird workarounds.
This is a good reference for the workarounds available: Passing FormData/File Object from content script to background script in chrome extension with Manifest V3
Workaround 1 seems bad, since it will require to break up the request which is not compatible with the backend API. Workaround 2 seems insecure, since the host web page will definitely be able to send rogue messages to an embedded iframe as it will share context.
I'm considering having the content script perform the upload directly like this:
The content script loads the authentication secret from extension storage (chrome.storage.sync or chrome.storage.local depending on login persistence mode).
It calls fetch directly to upload the form data.
Is that safe?
One hazard I had in mind was that a host page could hook window.fetch to intercept the credentials. That doesn't seem possible after my testing (the content script has a separate fetch defined in its own isolated environment). Is there anything else to watch out for?

how to access a different module in multi target application

I'm new to cloud foundry, so I'm not sure, if my thoughts and plans are right. Maybe someone can explain or discuss it with me.
What I want to do:
Implement a MTA (Multitarget Application) with a a html5-module as frontend and a nodeJS-module as backend. Furthermore there should be a mongodb instance, which will be accessed from the nodejs-module. Later it should also get multitenant.
What I already did:
I implemented a simple nodejs-app and connected it to the db. Persisting and calling data with rest works already fine. I implemented a simple sapui5 app, which consumes data from the db with ajax. For now, the node startscript is in the html5 module, so it works somehow. But now I want to separate the modules.
So I created a mta-project with the two modules in webide and imported the two apps.
What I expect to do for it:
For now, I have an approuter, which is in my nodejs-module, but I can not access the webapp folder in the html5-module from here: file not found error: /home/vcap/app//. Is there a possibility to access the webapp-folder in another module over the path "/home/vcap/app/"? Or can I lookup the app-directory anywhere?
I have read, that an approuter-module (nodejs) can be needed, but I don't know exactly what it does. I think it serves the index.html file when opening the url of the whole app?

Cloud Functions for Firebase: admin vs root lookups

Getting the hang of Firebase and JavaScript for coding cloud functions; but I guess I'm looking if anyone can explain the pros and cons of using the following for look-ups and/or writes in cloud functions?!
the use of admin.database().ref()
vs
root.child()
I myself have been using admin.database.ref(), but do I need to? Is it just as good to use the root.child() instead?
I see that you've also asked this question in the comments for my Firecast on YouTube. That's a good question. If you've been following along with the Cloud Functions for Firebase samples, you might have seen admin.database().ref().
admin.database().ref() uses the Firebase admin SDK to access data in the Database. As an admin reference, it has unrestricted access to any part of the Database.
In the video, root = event.data.ref.root, a reference to the root of the database where the .onWrite event occurred. ref has the same read and write access as the user who triggered the event. Unlike admin.database().ref(), it does not grant unrestricted access. root.child therefore access that specific path in the database, as long as the user has permission to access it.
Now event.data.adminRef.root is a Database reference with unrestricted access to any part of the Database. If this sounds like admin.database.ref(), it's because they're exactly alike. In my case, I chose event.data.ref.root to limit the amount of new topics introduced in one video. If you're more comfortable using the admin SDK, that is totally fine.

Am I supposed to publish my Spotify API key in an open source app?

I have created a simple app, script almost, that backs up playlist contents (just song titles/etc., not the music) off Spotify. It uses libspotify.
I want to publish the source; I wonder what the approach is for API keys in this case? Without the API key, if the user is required to provide it in some header file, the app becomes useless to most people.
I believe their approach in your case would be that you should publish the code but have your key stored safely in a directory outside the published code. That way, anyone using your code will have to get their own application key.
If you release your app in binary form they are OK with it being compiled into the application.
There's a thorough response at https://stackoverflow.com/a/15885844, complete with a sweet car analogy and all. :-)

cherrypy: how to access file system from cherrypy?

I am working on a cherrpy web service to work with my web app. In this service it needs to be able to access the file system. For example, I want to be able to list all files under a certain directory. I am using os.walk('/public/') but don't seem to get it to work, even though the same code works outside of cherrpy.
Is there a way to make it work so I can use cherrypy to manage files?
What user is the webapp running as, and does it have access to read the folder?
According to the documentation os.walk() will ignore errors from the underlying calls to os.listdirs()
http://docs.python.org/release/2.4.4/lib/os-file-dir.html
You could try setting the onerror argument like
def print_error(error):
print error
os.walk('/public/', print_error)
which might give you a hint as to what's going on.
Also, you could try going directly to os.listdirs() and see if you get any errors from it.

Resources