If I already have ../auth/documents.currentonly scope, do I also need ../auth/documents? - scopes

I'm transitioning a Google Docs add-on that was approved when the add-on concept first started (many years ago) from a Docs-only add-on to one that works for both Slides and Docs. In the process, I have had to redefine a lot of things (create a new project) and request authorization for OAuth scopes.
I had assumed that if my add-on had ../auth/documents.currentonly (which is truly all it needs), then I was good to go. I did have to request authorization for external_service and container.ui, which I obtained quickly from Google. So, I published the add-on, and all looked OK. I was able to install it on my test accounts, etc. I've seen the number of public users go from 0 to 63 in about a week.
However, I just got an obscure email from Google saying I had to take action because I didn't have the authorizations:
Apps requesting risky OAuth scopes that have not completed the OAuth developer verification process are limited to 100 new user grants.
The email doesn't specify what scope is risky, however. The OAuth consent screen shows all my APIs that needed authorization are approved (I also have an email showing they were granted authorization):
The consent screen doesn't allow me to request verification (the button is grayed) in its current state. I assume that, since no verification is requested or given for them, the currentonly scopes are not "risky".
I have replied to Google's email (which seems to be automated), and will hopefully get some more info.
In the meantime, I wondered if perhaps I misunderstood the scopes. It was a complex process and I don't remember if ../auth/documents.currentonly was automatically added to the screen, or if I had to add it at some point. I know it comes from a comment in the code of the add-on:
/**
* #OnlyCurrentDoc
*/
This is explained on https://developers.google.com/apps-script/guides/services/authorization
I'm wondering if the problem is that since my add-on is published, I also need to explicitly add a broader scope: ../auth/documents, which is indeed a scope that requires authorization ("risky"?). My add-on doesn't use other documents than the current one, so that wouldn't make sense to need it. It's how I understood the Google documentation about this.
As an experiment, here's what the screen looks like if I add that scope:
If I add that (and the corresponding one for presentations), I can request another verification (although I am unsure if it's really needed). Do the currentonly scopes also require the broader ones?
Update 2019-12-13
Today, even though I still have no reply to my response to the automated email, I see that my add-on has more than 100 users. That should not have happened according to the email I received, unless something changed. I'm assuming someone resolved the inconsistency on the Google side of things.

Related

How should signup form error responses be displayed

I have a subscription based application that is build using MERN. I've recently submitted the application to be security tested and one of the responses that I received was that the application should not specifically tell the user why their signup application has been rejected for all cases. For example, if they enter a username or email that has already been registered, I shouldn't return an error message that says "Sorry, this username is already registered", as this would allow the user to build a list of users and emails that have registered with our site.
I understand why we need to prevent this, but I don't understand how I can tell the user why there signup submission failed without telling them that it's because that email has already been registered. It seems pointless to reject their signup form without giving them a specific reason, does anyone know what the best thing to do here is?
I have a subscription based application that is build using MERN
The fact you're using MongoDB, Express, React and NodeJS is irrelevant to how your end-users and visitors use your product.
I've recently submitted the application to be security tested...
Watch out - most "security consultants" I've come across that offer to do "analysis" just run some commodity scripts and vulnerability scanners against a website and then lightly touch-up the generated reports to make them look hand-written.
one of the responses that I received was that the application should not specifically tell the user why their signup application has been rejected for all cases
Hnnnng - not in "all" cases, yes - but unfortunately usability and security tend to be opposite ends of a seesaw that you need to carefully balance.
If you're a non-expert or otherwise inexperienced, I'd ask your security-consultant for an exhaustive list of those cases where they consider harmful information-disclosure is possible and then you should run that list by your UX team (and your legal team) to have them weigh-in.
I'll add (if not stress) that the web-application security scene is full of security-theatre and cargo-cult-programming practices, and bad and outdated advice sticks around in peoples' heads for too long (e.g. remember how everyone used to insist on changing your password every ~90 days? not anymore: it turns out that due to human-factors reasons that changing passwords frequently is often less secure).
For example, if they enter a username or email that has already been registered, I shouldn't return an error message that says "Sorry, this username is already registered", as this would allow the user to build a list of users and emails that have registered with our site.
Before considering any specific scenarios, first consider the nature of your web-application and your threat-model and ask yourself if the damage to the end user-experience is justified by the security gains, or even if there's any actual security gained at all.
For example, and using that issue specifically (i.e. not informing users on the registration page if a username and/or e-mail address is already in-use), I'd argue that for a public Internet website with a general-audience that usernames (i.e. login-names, screen-names, etc) are not particularly sensitive, and they're usually mutable, so there is no real end-user harm by disclosing if a username is already taken or not.
...but the existence or details of an e-mail address in your user-accounts database generally should not be disclosed to unauthenticated visitors. However, I don't think this is really possible to hide from visitors: if someone completes your registration form with completely valid data (excepting an already-in-use e-mail address) and the website rejects the registration attempt with a vague or completely useless error message then a novice user is going to be frustrated and give-up (and think your website is just broken), while a malicious user (with even a basic knowledge of how web-applications work) is going to instantly know it's because the e-mail address is in-use because it will work when they submit a different e-mail address - ergo: you haven't actually gained any security benefit while simultaneously losing business because your registration process is made painfully difficult.
However, consider alternative approaches:
One possible alternative approach for this problem specifically is to make it appear that the registration was successful, but to not let the malicious user in until they verify the e-mail address via emailed link (which they won't be able to do if it isn't their address), and if it is just a novice-user who is already registered and didn't realise it then just send them an email reminding them of that fact. This approach might be preferable on a social-media site where it's important to not disclose anything relating to any other users' PII - but this approach probably wouldn't be appropriate for a line-of-business system.
Another alternative approach: don't have your own registration system: just use OIDC and let users authenticate and register via Google, Facebook, Apple, etc. This also saves your users from having to remember another password.
As for the risk of information-harvesting: I appreciate that bots that brute-force large amounts of form-submissions sounds like a good match for never revealing information, a better solution is to just add a CAPTCHA and to rate-limit clients (both by limiting total requests-per-hour as well as adding artificial delays to user registration processing (e.g. humans generally don't care if a registration form POST takes 500ms or 1500ms, but that 1000ms difference will drastically affect bots.
In all my time building web-applications, I've never encountered any serious attempts at information-harvesting via automated registration form or login form submissions: it's always just marketing spam, and adding a CAPTCHA (even without rate-limiting) was all that was needed to put an end to that.
(The "non-serious" attempts at information-harvesting that I have seen were things like non-technical human-users manually "brute-forcing" themselves by typing through their keyboard: they all give-up after a few dozen attempts).
I understand why we need to prevent this, but I don't understand how I can tell the user why there signup submission failed without telling them that it's because that email has already been registered. It seems pointless to reject their signup form without giving them a specific reason, does anyone know what the best thing to do here is?
I'm getting the feeling maybe you got scammed by your security "consultants" making-up overstated risks in their report to you - rather than your web-application actually being at risk of being exploited.

Methods to protect client-side Chrome extension code

I'm working on creating a Chrome extension that uses client-side JS to automate a task on a website. Since this tool would be used by businesses, I'm planning to sell it in a subscription-based model. Previously, Chrome had a payments API that could protect someone from having access to the client-side code without first paying, but they've since deprecated that API. Additionally, it used to be possible to get remote code and execute it within a Chrome extension, but Chrome has now also forbade that. And on top of that, it is not acceptable to obfuscate code.
Given all of these very strict restrictions, I'm wondering what options we as developers have to enforce any amount of security for our code. Obviously this is client-side code, meaning there is no true way to fully protect it, but what I'm initially thinking is:
Minify/bundle the code. Minification is allowed and I've been able to publish bundled/minified extensions before. This helps to hide intent of functions by shortening their names.
Use scripting.injectScript to inject individual functions from the background script to tabs rather than have it readily available on the page. This hides the logic a bit and makes it a bit harder to track the flow.
Given the above, my main question is about payment status checks. I will have a backend with authentication that integrates with Stripe. I'm wondering if there's some way I can maybe check with my server on a daily basis for paid status, store that status in chrome.storage, and then have checks throughout my code that check chrome.storage without making it stupidly easy for someone to just do chrome.storage.sync.set({ paid: true }). My thought to adding just another hurdle at least is to have the server return an encrypted payload containing the id of the user and the time they last authenticated as well as a key to decrypte it. The Chrome extension would then have the ability to decrypt the payload and check that the date and id are accurate. For the user to get around this, they'd have to have some basic encryption understanding and do it on a daily basis, which would hopefully be too annoying to be worth it.
To be clear, I understand that sending the key to the client makes it so that this isn't actually secure, and the user could even go through the code to manually remove the checks, but the goal here is to just make it hard enough that the average user would have a hard time figuring out how to overcome the challenges and it wouldn't be worth it.
Does anyone have any other strategies they're employing or just ideas in general in this new era of Chrome extensions?
The only other option I could think of that would actually secure a Chrome extension but that wouldn't fly by the Chrome team is having the extension code be encrypted at the time of download and the user would need to subscribe to get a key to decrypt it. But this would violate the obfuscation rule. Would be nice if we could talk to the Chrome team about allowing something like that where we could give them a key at time of submission.

How to allow only one user to register with Stormpath

Context: I have never work with Stormpath before and want to fully learn how to do certain stuff. To practice I'm creating my own portfolio, including the CMS.
My question is, how can I restrict the registration of accounts to a handful of specific emails using Google API (only me should be able to add and remove content from my own portfolio).
E.g. Allow ONLY example1#gmail.com and example2#gmail.com to register.
I could do it manually, but I do not want to do that. Steps I would like to follow are:
Specify emails
User tries to access the CMS
User is prompted to login or register
Only if user is in the specified list of emails, user can register using Google's API.
I do understand this is a very general question that involves several fields: Google's API, Stormpath, not to mention Express and Node, but maybe someone else solved this problem and I can see some code. Thanks.
I'm the author of the express-stormpath library which I'm assuming you're using. There's nothing out-of-the-box that does this, so I'd like to point out the best way to do this:
Create a custom registration route, and model it after the built-in stuff here: https://github.com/stormpath/stormpath-express/blob/master/lib/controllers.js#L143
In your custom registration route code, add in some code that checks to see if the email address supplied by the user is a valid one or not.
If not, reject their request.
Now, in the real world you probably wouldn't want to do this sort of thing (it's a lot of extra work, and doesn't buy you much). What you'd probably want to do instead is: completely disable account registration on your website. This way, only YOU can create an account using the Stormpath dashboard on https://stormpath.com, but login still works on your site so that you can log in.
Does that make sense?
So basically, what I'm suggesting is that you disable registration on your site by saying:
app.use(stormpath.init(app, {
enableRegistration: false, // this will disable the registration page / functionality
// ...
}));
Hopefully this helps =)

Facebook Javascript SDK security

I'm in the process of using the facebook javascript sdk to provide user login functionality for a website.
What I'd like to do is simply take the logged in user's unique facebook id and then put/fetch data to/from a mysql database using the id to determine what data is available to said user.
However I don't really feel like this is very secure. Whilst I'm not storing anything sensitive like credit-card details etc, I'd obviously prefer it to be as secure as practically possible.
My fear is that with javascript being what is it, someone could fake the facebook id and just pull whatever they wanted.
I'm aware that the php sdk would provide a solid solution to this problem, but i like the javascript one mainly because it's easy to use and I have the basis of it set up (I admit it, I'm lazy).
So, my questions are:
Would this set up be as insecure as I feel it might be?
Is there anything I can do to improve the security of such a system, other than switching to the php sdk?
Thanks!
Facebook Ids are pretty hard to make up (at most a user will only know their own). Depending on what you store in the database (which will not be anything that the user cannot get on their own, unless you ask for extended permissions)
If you are worried about a user trying to get information from the database, add an access token or signed request to each row and us that and facebook id to get data. That will greatly increase security.
EDIT
There are few occasions where you get a signed request from a user:
* A signed_request is passed to Apps on Facebook.com when they are loaded into the Facebook environment
* A signed_request is passed to any app that has registered an Deauthorized Callback in the Developer App whenever a given user removes the app using the App Dashboard
* A signed_request is passed to apps that use the Registration Plugin whenever a user successfully registers with their app
Signed requests will contain a user id only if the use has accepted permissions though, and are not passed again if the user enters the application, and accepts permissions (meaning that the signed request would not contain the ID). Because of this saving an access token may be a better idea. Here is more on the signed request
Also the signed request is in the url (param = "signed_request"). I always parse it through c# but I am sure you can at least get one through javascript
It's pretty easy to spoof the origin using curl. I'd imagine Facebook has another mecanism in place to make this possible. If you inspect their code, it appears that they generate an iframe and pass requests through. If I had to guess, they have setup the requests to only be made from the Facebook domain, and ensure that the iframe can only be embedded in a page that has a white listed domain.

What are best practices for activation/registration/password-reset links in emails with nonce

Applications send out emails to verify user accounts or reset a password. I believe the following is the way it should be and I am asking for references and implementations.
If an application has to send out a link in an email to verify the user's address, according to my view, the link and the application's processing of the link should have the following characteristics:
The link contains a nonce in the request URI (http://host/path?nonce).
On following the link (GET), the user is presented a form, optionally with the nonce.
User confirms the input (POST).
The server receives the request and
checks input parameters,
performs the change,
and invalidates the nonce.
This should be correct per HTTP RFC on Safe and Idempotent Methods.
The problem is that this process involves one additional page or user action (item 3), which is considered superfluous (if not useless) by a lot of people. I had problems presenting this approach to peers and customers, so I am asking for input on this from a broader technical group. The only argument I had against skipping the POST step was a possible pre-loading of the link from the browser.
Are there references on this subject that might better explain the idea and convince even a non-technical person (best practices from journals, blogs, ...)?
Are there reference sites (preferably popular and with many users) that implement this approach?
If not, are there documented reasons or equivalent alternatives?
Thank you,
Kariem
Details spared
I have kept the main part short, but to reduce too much discussion around the details which I had intentionally left out, I will add a few assumptions:
The content of the email is not part of this discussion. The user knows that she has to click the link to perform the action. If the user does not react, nothing will happen, which is also known.
We do not have to indicate why we are mailing the user, nor the communication policy. We assume that the user expects to receive the email.
The nonce has an expiration timestamp and is directly associated with the recipients email address to reduce duplicates.
Notes
With OpenID and the like, normal web applications are relieved from implementing standard user account management (password, email ...), but still some customers want 'their own users'
Strangely enough I haven't found a satisfying question nor answer here yet. What I have found so far:
Answer by Don in HTTP POST with URL query parameters — good idea or not?
Question from Thomas -- When do you use POST and when do you use GET?
This question is very similar to Implementing secure, unique “single-use” activation URLs in ASP.NET (C#).
My answer there is close to your scheme, with a few issues pointed out - such as short period of validity, handling double signups, etc.
Your use of a cryptographic nonce is also important, that many tend to skip over - e.g. "lets just use a GUID"...
One new point that you do raise, and this is important here, is wrt the idempotency of GET.
Whilst I agree with your general intent, its clear that idempotency is in direct contradiction to one-time links, which is a necessity in some situations such as this.
I would have liked to posit that this doesn't really violate the idempotentness of the GET, but unfortunately it does... On the other hand, the RFC says GET SHOULD be idempotent, its not a MUST. So I would say forgo it in this case, and stick to the one-time auto-invalidated links.
If you really want to aim for strict RFC compliance, and not get into non-idempotent(?) GETs, you can have the GET page auto-submit the POST - kind of a loophole around that bit of the RFC, but legit, and you dont require the user to double-optin, and you're not bugging him...
You dont really have to worry about preloading (are you talkng about CSRF, or browser-optimizers?)... CSRF is useless because of the nonce, and optimizers usually wont process javascript (used to auto-submit) on the preloaded page.
About password reset:
The practice of doing this by sending an email to the user's registered email address is, while very common in practice, not good security. Doing this fully outsources your application security to the user's email provider. It does not matter how long passwords you require and whatever clever password hashing you use. I will be able to get into your site by reading the email sent out to the user, given that I have access to the email account or am able to read the unencrypted email anywhere on its way to the user (think: evil sysadmins).
This might or might not be important depending on the security requirements of the site in question, but I, as a user of the site, would at least want to be able to disable such a password reset function since I consider it unsafe.
I found this white paper that discusses the topic.
The short version of how to do it in a secure way:
Require hard facts about the account
username.
email address.
10 digit account number or other information
like social security number.
Require that the user answers at least three predefined questions (predefined by you,
don't let the user create his own questions) that can not be trivial. Like "What's
your favorite vacation spot", not "What's your favorite color".
Optionally: Send a confirmation code to a predefined email address or cell number (SMS) that the user has to input.
Allow the user to input a new password.
I generally agree with you with some modification suggested below.
User registers at your site providing an email.
Verification email is sent to the users account with two links:
a) One link with the GUID to verify the registration b) One link with the GUID to reject the verification
When they visit the verification url from their email they are automatically verified and the verification guid is marked as such in your system.
When they visit the rejection url from their email they are automatically removed from the queue of possible verifications but more importantly you can tell the user that you are sorry for the email registration and give them further options such as removing their email from your system. This will stop any custom service type complaints about someone entering my email in your system...blah blah blah.
Yes, you should assume that when they click the verification link that they are verified. Making them click a second button in a page is a bit much and only needed for double opt in style registration where you plan to spam the person that registered. Standard registration/verification schemes don't usually require this.

Resources