0

Scenario: you run an app OurApp which deals with users' sensitive data, some of which you are allowed to share with third parties (with the user's consent, of course) and some of which you are not allowed to share even if the user consents. You wish to integrate with a site MiddlemanSite which the user already has an account with. MiddlemanSite will display a dashboard page which directly incorporates the data you are allowed to share, with click-through links to ourapp.com to view the data that isn't allowed to be shared.

Example: MiddlemanSite is the classic petstore app, and OurApp is a veterinary practice, which is allowed to share data like notifications that a user's pet is due a vaccination or checkup, but not the pet's full medical history.

Challenge: what workflow do I use for authenticating the user to OurApp which ensures that the private data is only accessible to the user directly, and not to a compromised or malicious MiddlemanSite, notwithstanding the fact that most of the user's interaction takes place on MiddlemanSite?

Thus far the best authentication workflow I can come up with is this:

Slightly ridiculous workflow

It's clear that we need to have a direct dialogue with the user when first linking the two accounts: we need to do this anyway because we need to collect a secret (in our case an API key for yet another service, which we need in order to make our service work) directly from the user. So when MS posts details to the "this user of ours has just asked to affiliate their account with OurApp, here are their details" endpoint, we return a redirect url for the user to be directed to, where we ask for the SuperSecret. We can consider the user to be 'verified' if they know the SuperSecret.

Then we can set a cookie in the response to that submission which will allow us to identify that user in future visits; so when they click links on the MS dashboard they authenticate with both a token in the link query string (which MS will have access to) and the cookie (which MS won't).

However, re-validating the user on a different device or after a long time is more challenging. I don't want to require the user to re-submit the SuperSecret because generating it is a pain, and we don't want the user to have to set a separate password for OurApp. The best I can come up with is a quasi-two-factor-auth link sent directly from OurApp to the user's email or phone, which the user has to access in order to re-validate. But given that the email/phone data was submitted to OurApp by MiddlemanSite in the first place, I'm uneasy about this being easily spoofable. The best I can think of in terms of mitigation is to display the submitted information back to the user on the signup screen, so the user has a chance to see if it's being mitm'd. And I can't think of a way of supporting the user changing their email/phone settings on MiddlemanSite and safely propagating that change to OurApp.

Questions:

0) Is there a standard protocol for this sort of authentication workflow that I should be using instead of reinventing a wheel?

1) Are there obvious security weaknesses in this workflow, beyond its extreme verbosity? Assume that MiddlemanSite is either fully compromised or itself malicious, and seeks to gain access to users' non-shareable data.

2) Is there a better protocol I could use for re-validating users to replace using their email/phone records? Needs to support the user logging in to MiddlemanSite on a new device and immediately clicking through from their dashboard to a page on OurApp.

0

This is a really big question, and one that might benefit from being broken down a bit. I'll start with question #0, though.

Is there a standard protocol? Several. It depends on exactly how you want to do this. Consider this extremely simple approach:

Cross-Origin Resource Sharing (CORS): The user logs into MS, and MS sends an authenticated CORS request to a /SharableData endpoint on OurApp (this endpoint, and only this endpoint, will return Access-Control-Allow-Origin: https://middlemansite.com and Access-Control-Allow-Credentials: true). If the user has an active session on OurApp, the sharable data is returned such that MS can read it. If the user's browser has no current session on OurApp, an error indicating this is returned and MS offers a link to OurApp so the user can sign in OurApp. If the user has a session on OurApp but has not allowed data sharing with MS, OurApp can either send back the same error as before (may lead to user confusion but conceals from MS the fact that the user even has an OurApp account), or can return an "unauthorized" error and MS could offer the user a link to their data sharing settings page on OurApp.

  • Advantage: Easy to scale to multiple middleman sites. Each MS, when on-boarding to OurApp, supplies some basic info about itself (name, icon, whatever) and the origin that the requests will come from. You verify that the details are valid, and allow the user to toggle sharing with that site. No need for secret keys, etc.
  • Advantage: No need for a server-to-server request flow. The MS server cannot access even the sharable data directly - it can only do so via the user's browser when the user is signed into both sites and browsing MS - and neither server needs to store any server-to-server keys or be configured to allow outbound requests.
  • Disadvantage: Requires sessions on OurApp to last long enough that the user can complete their browsing on MS without needing to log into OurApp annoyingly often (can be mitigated by having two sessions for OurApp, a short-lived session that is used when actually interacting with OurApp and a long-lived session that only gives access to the user's sharing-allowed data, with at least the latter stored as a token in a cookie).
  • Disadvantage: Potentially inconvenient back-and-forth between sites when setting up (could be mitigated with a "returnTo" query parameter that enables sending the user back to trusted third-party sites like MS, though beware creating an open redirect by accident).
  • Disadvantage: Potentially allows cross-user access to shared data, if on a shared browser a user logs out of MS but not out of OurApp, and then another user logs into MS (can be mitigated by having MS supply some kind of identification string - a name, phone number, email address, or whatever - with the CORS request, and rejecting the request if the ID string doesn't match the current session on OurApp). On the other hand, nothing you can really do about this; if a user shares a browser with somebody they don't trust and fails to log out of everything they were logged into (perhaps by using Private/Incognito mode and closing the window), there's not a lot that you can do to protect them).

Other options could include using a shared authentication provider (SSO) that attests the user's identity to each site (complicated when the users already have accounts, though; you need to support linking them) and letting a user on OurApp grant access to MS, or using a "connected app" model (probably via OAuth, which is widely used and supports all the desired functionality) where an authenticated user on MS can request that the user's browser provide an access token from OurApp, and OurApp first makes sure the user is logged into OurApp and then that they want to share the data. There are tradeoffs, of course; the SSO route requires all the sites cooperate on their SSO identity provider and existing account management, and the OAuth route allows a MS to query all the sharable data for all users who have granted access at any time, instead of only when the user is actually browsing the MS and also logged into OurApp (with at least a long-term low-access session).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.