Is "execute app as me" deployment setting secure? - security

I'm currently creating a simple script that is essentially just a form that people can fill out an upload a couple of files.
When I click Deploy as a Web App, one of the form items asks "Execute the app as". One of the options is: Me (example#gmail.com)
Is this safe?
Does that mean anyone who has a link to the script essentially becomes logged in to my account?
Are there security risks to this?

One of the most important issues is, who has access to the Apps Script file. The file sharing settings are set totally differently than the web app deployment settings. You can have the Apps Script file SHARED settings, set to not being shared with anyone, and still have anyone be able to access the web app. So, access to the web app, and access to the file are two different things. That's a key point to understand.
The Execute the app as me, is not inherently unsecure. It doesn't log someone into your account. IF you somehow configured your app to give broad access to your account, which you can do, that's obviously a potential security hole. You should set scopes manually in the appsscript.json manifest file that are more restricted. For example, restricted scopes to your Gmail and Drive if the Web App sends an email, or accesses your Google Drive. You can restrict the email scope to only be able to send an email, and restrict the Drive scope to only be able to access files and folders that the script created, or that the user picked with the Google file picker. You can restrict access to only the current spreadsheet, instead of all your spreadsheets.
Are there potential security holes? Yes. But there aren't any security holes that you wouldn't have with any web app. So, it's really dependent upon the practices you use.
Don't use/store settings/parameters in client side HTML, that directly cause a server function to perform an action that you don't want anyone to be able to execute.
How secure your app is depends on some simple practices.
Don't store settings or information in HTML that could cause a security hole. Passwords is the obvious example. Don't put names of files in HTML code. Don't pass settings or parameters in Client side calls to the server that are obviously a direct link to a server function that has broad access to your account.
You can put an underbar at the end of server side function names so that a user can't know the names of your server function.
https://developers.google.com/apps-script/guides/html/communication#private_functions
Have a main server function that then calls a private function, that in turn branches to other functions. So the user will never know the name of the function that is ultimately doing all the real work.

If someone else has access to modify your Script, then yes, he can re-publish the app that will have access to whatever you previously authorized, but won't have new authorizations. Eg, if you used only SpreadsheetApp as your first code and authorized it, someone who has access to modify this script you already published can open all your Spreadsheets and erase them, but wont be able to touch the Docs.
Someone with the published app URL will have none of this, it will only run the scripts you/shared scripters published.
I use "Me"/"Anyone Even Anonymous" quite frequently, published dozens of apps and never had any issue.

Related

How would you structure a webapp so that users don't need to sign in, but they still have a unique identifier that only they can use?

I want to create an educational web app that, for specific reasons, I want someone to visit the website and immediately start using its functionality. It's not very high-stakes since it's educational, so security is not high-priority, but I'd like the app to be accessed by one user which they can later optionally sign in if needed.
E.g. if you use the app on your browser, you can continue using it there and your progress persists, without needing to log in, unless you need to transfer to a new device.

Advice on whether possible to display iframe already authenticated (credentials)

I have a problem that I need to solve for my client. The situation is that they have a lot of users on one platform (platform_1). In order to use the platform a user must be signed in, therefore these users (credentials) are given out to clients for them to use the platform. The problem is that one user (one set of credentials) may be given out to a few clients, therefore we cannot know which of the clients did what (in this case - bought something) on the platform.
Figured I would just create a new system where the client can be created and a set of credentials would be attached to that account, then I would just display an iframe of that platform (platform_1) with the attached credentials on the newly build platform and then I would be able to track what the user is doing in the platform.
But turns out iframe cannot handle credentials and also it would not be safe to use this method..
Also thought about scraping the whole platfrom (platform_1), which would work, but then I believe it would be extremely hard to do live auctions, for example scrape the live auction and display it on my system and let the user click on some buttons and the script would do the same on the platform_1, but the delays and overall usage could make it very hard.
I would like to kindly ask you to share your thoughts on ways this problem could be solved or whether it aint possible.

What is the best way to authenticate users with auth0 (oauth2) in a chrome extension that runs content scripts across multiple origins?

I've seen a few posts on this but I want to highlight some specific questions I have yet to see properly answered.
My current chrome extension contains the following:
background service worker
html pages to handle login / logout (although doing this in a popup would be great)
content scripts that run a SPA on certain domains
What I would like is for a user to be able to authenticate with auth0, and then any content script running on any domain can then use an access token to hit my API.
The current challenges I've been seeing that I'm not sure how to tackle:
Ideally each running content script has its own token. This involves using the auth0 session to silently get an access token. However, since auth0 checks the origin when hitting /authorize it would mean registering every domain as an "allowed origin" which is not possible for me due to volume. Currently if I try just setting the redirectURI to my chrome extension URL, it ends up timing out. I have seen some users report this approach working, so I'm not sure if I'm doing something wrong or not, but this approach feels unsafe in retrospect.
If I instead funnel my requests through the background script, so all running content scripts effectively use a single access token, how do I refresh that access token? The documentation recommends making a call to /oauth/token which involves the client secret. My guess is this is not something I should be putting into my javascript as all of that is visible to anyone who inspects the bundle. Is that a valid concern? If so, what other approach do I have?
If I do use a manually stored refresh_token, what is the best way to keep that available? The chrome storage API says not to use it for sensitive information. Is it preferred then to keep it in local storage?
If the best option is to have the background script make all the requests on behalf of the content scripts, what is the safest way for the content scripts to make a request through the background script? I would rely on chrome.runtime.sendMessage but it seems like the API supports arbitrarily sending messages to any extension, which means other code that isn't part of the extension could also funnel requests through the background script.
More generally, I would love to hear some guidance on a safe architecture to authenticate users for a multi-domain extension.
I am also not adverse to using another service, but from what I've seen so far, auth0 offers relatively good UX/DX.

How to hide content in a txt file from direct url

I'm working on a windows app which is reading a "authorized" domains list from a txt file with a web request from "domain.com/sub/txtfile"
I don't want people to see the content of the file when entering it directly in the browser. Is it possible to achieve this with some .htaccess hacks or something else?
As your app is a client-side native Windows application, it's not possible to store any secret in the app itself that could be used for authentication. As the user has everything the Windows app may have, it impossible to authenticate the client as discussed many times here.
It also doesn't make much sense. Imagine it was somehow possible and file contents were only visible to your app. What would be the purpose? What if an attacker changed the hosts file on Windows to download the file from a rogue server? What if he used an intermediate proxy to inspect, change or replace contents? The latter is also possible with https, because the user has full control of the client, and can trust whatever certificate he wants.
You could authenticate the user though. An attacker can still see and modify downloaded file contents, but at least not anybody could download the file, only your authenticated users. But this means having a user database where the file is downloaded from, and implementing proper authentication. And it still doesn't solve the other problems.
In short, you can't protect a client-side application from a user that controls the whole client.

Is it possible to prevent the web/DB admin from peeking my online content?

Let's say, there is a website for an online diary. Users upload their secrets to the web server and stored in the database. Normally, a user without the password can't see the diary items. However the web admin or DB admin could still can connect to the DB and see everything.
Is there a solution to prevent this? I mean a solution for the whole web application, not only for a single user.
Client-side javascript can encrypt the content, using a key known only to the client and never sent to the server, prior to saving.
However, the server can at any time start serving up malicious JS that would send the keys back down to the server. The only way to make this impossible is to make your application an installable client-side app (via an extension or whatever - but nothing that auto-updates). Additionally, all of this paranoia is pointless unless the user can verify what the app is doing, so it would need to be open-source.
At this point you're basically writing GnuPG, so you might as well just use that.

Resources