Office365 IMAP Access: User is Authenticated but not Connected - javascript

I'm building my own IMAP client using node-imap, and I'm testing it against accounts on office365.
Since it's under development, I tend to hammer on the IMAP server more that I would in production, but not necessarily what I would consider to be too much.
Occasionally, I start getting the IMAP response "BAD User is authenticated but not connected". This comes after the first command after a successful login.
This is not related to password changes as other similar articles indicate, as my passwords are not changing during this time.
When this happens, the account seems to get locked up for a period of time. I seem to be able to jiggle it free by disabling then re-enabling IMAP on the account via the office365 admin panel.
So it looks like there's a circuit breaker of some sort in the IMAP interface on office365. Microsoft documents a limit of 20 concurrent sessions. In my case I am only opening one session at a time, but I am then closing it and re-opening it again soon after (debugging), so if I am running afoul of a limitation, it's not documented anywhere i have read.
Microsoft support has been helpful but unable to help me root cause this.
In order to take this app to production, I need to know what causes this to happen.
Has anyone else had a similar experience with office365?

You may want to take a look at the Outlook REST APIs rather than IMAP. The REST APIs are the recommended development API for Office 365 and are much better suited for app development with features like webhook based notifications, and are constantly evolving with the new features and functionality in the service. They also don't have the session oriented nature that IMAP has that results in the kinds of problems you are hitting.
There is a NodeJS quickstart guide to O365 here: https://dev.outlook.com/RestGettingStarted/Tutorial/node

you need to perform 2 operations on exchange online using powershell
You need to create the service principal
New-ServicePrincipal -AppId {clientid} -ServiceId {enterprise application objectid} -Organization {tenantid}
you need to grant your service principal access to the mailbox,
If the principal does not have the access, you get "user not connected"
Add-MailboxPermission -Identity {email} -User -ServiceId {enterprise application objectid} -AccessRights FullAccess
See "Register service principals in Exchange" at
https://learn.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth

If you have already verified that your password is correct (by logging into your mailbox from the web) then the issue might be Exchange server keeping a list of all your active login sessions.
Try signing out from all other locations by clicking "sign out everywhere" on the account security page https://mysignins.microsoft.com/security-info and then retry signing in again.

Office365 will accept connections and successfully authenticate even when the user doesn't have permissions to access the server by IMAP, and this is the exact error it gives in that situation.
To resolve it, go into the Office365 panel, open the user, and ensure that the IMAP permission is checked.

Related

Facebook app review for API permissions still rejected

Our web application aims to allow our users to share photos with comments directly from our platform.
Since May 10, I have made several permission requests from Facebook for the following permissions:
pages_manages_posts
pages_show_list
instagram_content_publish
pages_reads_engagement
ads_management
instagram_basic
https://drive.google.com/file/d/1fv83sv8Z7EVmTEuNrIaVCpcYnHKY5H4A/view?usp=sharing
As and when requests some pass others not. In addition, our web application has not undergone any change since the first request, since everything has been working on our side from the beginning. And yet some permission seems to be released randomly as the different requests.
We only have the "instagram content publish" permission left, however as it always resulted in a refusal, we changed our Facebook developer account. Indeed, our new developer Facebook account has a company verification and we thought it would have more weight then.
However, on the first request on this other account, all permissions were denied, while there was only one left on the other application. And again, nothing had been touched on our web application.
We don't know what to do anymore because we can't get in touch with anyone.
Has anyone encountered the same problem? How to get in touch with an engineer / developer at Facebook?

Google Oauth - Where to sign in users, backend/frontend

What is the difference between using Google OAuth and signing in users at the frontend of the application, and signing in users at the backend side of the application?
Example: Signing in users and getting the ID and a auth object in React or letting Node/Express handle everything, the prosess, redirecting and store it in a database.
Is there any advantages for one or the other methods, which are most common and are there any "rules"?
What is the difference between using Google OAuth and signing in users
at the frontend of the application, and signing in users at the
backend side of the application?
So to clarify to everyone reading this, signing in users at the backend side of the application is another way of saying OAuth for servers and signing in users at the frontend of the application is OAuth for JavaScript browser applications such as React.
Signing in users via OAuth for servers and browsers results in a 'token' that a server/browser can use to make requests on behalf of the user. We are asking the user to provide us access to their information via an outside service provider such as an email address, identification of some sort and it will be inside that token as well as some possible permissions that allow us to take actions on behalf of that user.
Is there any advantages for one or the other methods, which are most
common and are there any "rules"?
Server-side OAuth is usually used when we have an app that needs to access user data when they are not logged in. So if you are attempting to build an application that needs to access the users email every ten minutes and possibly delete emails on the users' behalf, you would want to be able to access their email account every 10 minutes regardless of whether they are logged into our application. So for this use case we want to make use of Oauth for server.
Otherwise, if we are not trying to do anything on behalf of the user except sign them into our app, then we can just go with OAuth for browser.
Those two things are very different. Without knowing the specifics of what you're trying to accomplish, you should know as a general rule that front-end-only authentication and authorization leaves you extremely vulnerable.
If someone knows JavaScript well, or is using editing plugins, or any of a million different things, they can bypass much front-end authorization. Or they could just watch to see what calls your app makes to the back end, then simulate those calls from something like Postman, bypassing your web front end entirely.
If you're not securing your backend, you're not secure. Typically systems do both.
It is just a different ways of registering users to our website.
Signing in users at the frontend using OAuth can be very handy as it enables our users to not go through our boring forms in our website. Using OAuth is just one click away from registering users in our website. Beneficial to both the clients and developer.We are provided with the general information about clients by the provider(google,facebook) just clicking on one button.
Signing in users at the backend side is the traditional way of registering our clients. Here we force our client to fill the forms in our website(which may be painfull if it is a long form) and all the filled data is stored in our database.
So they are both different ways to register clients to our websites. Both are used very often. It depends on usecase and needs. Oauth can be used if you want to attract more clients by registering them just by one click.

How can I prevent bots and spam API requests?

I'm working on an Android app in react-native and the app communicates with an API I'm working on for the app. The API is built with Laravel and Laravel Passport.
I know that Android apps can be decompiled so any secret keys stored within the app could be easily found. This is the reason for my current approach.
You can only gain an access code during registration. The application uses anonymous accounts so if you lose the access token, it's too bad. The app makes an API request to /api/register which creates the account and returns an access token. The app would store the token and use it to make further API requests.
The problem is that the registration route does not use any client secrets or access tokens. It is very easy to automate requests to the route and create an army of bots. I could potentially limit the amount of requests like a lot of API providers do but that wouldn't stop the issue.
I've heard about payload hashing but this usually requires a salt that is in both the app and api. Again, this is not secure and couldn't someone just hash it themselves if they know the salt to spam requests? Maybe I'm misunderstanding how payload hashes work.
Hopefully someone can assist.
You'll probably want to use something to detect the user agent hitting the route. This package has a lot of useful features:jenssegers/agent. For example, it offers crawler detection:
$agent->isRobot();
Depending on your hosting provider, you may have access to tools that automatically blacklists ip addresses after X number of requests per minute (or other metrics). I know AWS offers this service.
Another option is antonioribeiro/firewall. Track users based on ip or geography and redirect/block accordingly.
I'm at this junction at the moment and the route I'm taking is one where the user is challenged to solve a simple puzzle:
registration process on app/web picks up a challenge from my registration server
the challenge is shown to the user with the input fields: email/username, password and the answer input for the challenge
it all gets sent to the registration server and if the answer is incorrect, the registration is denied
This "are you human" challenge is what will stop bot-registration so it needs to be a little smarter than the one coding the bots, so a selection of various challenges on the server would be nice.
I'm thinking of "select the n-th value from the dropdown", "select the first/last option", "write the color 'blue'" or "what whole number is between 3 and 5", and so on, for which variables can easily be generated by the server, the challenge and answer input can easily be created by the registration script, and it's easy and not very time consuming for the user to solve.
Another option I'll explore is to throttle requests by IP, combined with black-and white-listing those.

OAuth2 NodeJS using oauth2orizerecipes

I am using https://github.com/FrankHassanabad/Oauth2orizeRecipes to make an authentication server for a cordova movile app.
I have read the past few days a lot about OAuth2, and went a lot of times through what Frank Hassanabad has done there, and I tried to establish a workflow for my application.
But, alas, I am giving up and asking you guys because it seems I am stuck.
My main idea is that I want each Client (APP downloaded from the X Store) to create a new client on the auth server. This is, as far as I can think it is correct.
We have 2 kinds of workflows:
1. New Account
in the application I am accessing the server's new account page and make a new account, at this phase I have to create a new accepted Client on the server, the application is automatically created when we access the NEW ACCOUNT PAGE and the details to the app are pushed outside of the server iframe with postMessage so we can save them inside my application.
From now on, when/if something expires and no refresh token is given, the user can log in again by making an auth string like described here https://github.com/FrankHassanabad/Oauth2orizeRecipes/wiki/Resource-Owner-Password-Credentials, that when combined with the user and password, will return us a valid token and a refresh token.
All is nice and dandy, on the client I am calculating in how much time the token will expire and if the user has accessed the application after the token has expired we will send the refresh token to get new ones.
2. Login from a different device
This is where I am in the dark, I have to idea to make/think this workflow, for access/auth we would need a set of clientID and clientSecret, but we don't have those, so that the user can log in with his own account.
I am truly lost :)
The purpose for all this is for the user to have a management tab where he can see what devices/clients have accessed the application and with revocation rights.
I am starting to question if the authentication model in by itself is the good one :), thinking about this so much I realized that this is a sound workflow for having a server side application, which you access there, and there you have the management and from there you can allow new devices with generated clientID and secret copied into your OTHER device you want to log in with.
total blur

how to make sure only my own website (clientside code) can talk to Firebase backend?

I've read about Firebase and it looks awesome for what I want to do.
I've read about authentication and how based on rules certain logged-in users are authorized to do different stuff. Al good.
However, I'm unsure about another type of security: how do I make sure that only my own site (using client-side javascript) can talk to my firebase-backend? I'm asking because afaik there's no way to prevent anyone from looking up my firebase endpoint from the client-side code (url pointing to my specific firebase backend) and start using that for god knows what.
This is especially worrisome in situations in which I want to open up writes to the anonymous user role. (e.g: some analytics perhaps)
Any help in clearing my mind on this much appreciated.
Update (May 2021): Thanks to the new feature called Firebase App Check, it is now actually possible to limit calls to your backend service to only those requests coming from iOS, Android and Web apps that are registered in your Firebase project.
You'll typically want to combine this with the user authentication based security that Kato describes below, so that you have another shield against abusive users that do use your app.
In my opinion, this isn't so much a question about Firebase's security as a general discussion of the internet architecture as it stands today. Since the web is an open platform, you can't prevent anyone from visiting a URL (including to your Firebase) any more than you can prevent someone from driving past your house in the real world. If you could, a visitor could still lie about the site of origin and there is no way to stop this either.
Secure your data with authentication. Use the Authorized Domains in Forge to prevent CSRF. Put security rules in place to prevent users from doing things they should not. Most data writes you would use a server to prevent can be accomplished with security rules alone.
This is actually one of the finer qualities of Firebase and API services in general. The client is completely isolated and thus easily replaced or extended. As long as you can prove you're allowed in, and follow the rules, where you call in from is unimportant.
Regarding anonymous access, if you could make them visit only from your site, that still won't stop malicious writes (I can open my JavaScript debugger and write as many times as I want while sitting on your site). Instead, place tight security rules on the format, content, and length of data writable by anonymous users, or save yourself some time and find an existing service to handle your analytics for you, like the ubiquitous Google Analytics.
You can, of course, use a server as an intermediary as you would with any data store. This is useful for some advanced kinds of logic that can't be enforced by security rules or trusted to an authenticated user (like advanced game mechanics). But even if you hide Firebase (or any database or service) behind a server to prevent access, the server will still have an API and still face all the same challenges of identifying clients' origins, as long as it's on the web.
Another alternative to anonymous access is to use custom login, which would allow a server to create its own Firebase access tokens (a user wouldn't necessarily have to authenticate for this; the signing of the tokens is completely up to you). This is advantageous because, if the anonymous user misbehaves, the access token can then be revoked (by storing a value in Firebase which is used by the security rules to enforce access).
UPDATE
Firebase now has anonymous authentication built into simple login, no need to use custom login for common use cases here.

Categories