This is one of those "I dont even know what I dont know" situations. Sorry if I sound confused or make rookie mistakes. Any help, including reading material, would be appreciated.

I am trying to build for work a service that relies on confidential data from another service.

Say, a user is logged in in service1. The user clicks a link to service2.

service2 need to be aware of sensitive data stored in service1 servers. Also, service2 allows users to consume credits that they payed for with money and that might be useful to attackers, so it needs to be sure of the users identity, as provided by service1.

It is a requirement that service1 and service2 live on different servers and use different domains. Is also is a requirement that the user goes from service1 to service2 clicking a link. Afaik, this means that the only data service2 can obtain is on the URL itself.

My proposed solution:

1) User clicks to go from service1 to service2

2) service1 generates a unique, one use key and appends to the URL. Javascript opens this URL.

3) service2 receives this key and sends it to service1. Service1 sends the data directly to service2

As far as I can tell, the data is (by definition) secure. But there is still the problem that an attacker might obtain the one time key and use it instead.

But there is much I don't understand, and I don't even know what to search.

Any help/comment/reading material appreciated.

  • 2
    I think your question, as is, is too broad for us to answer, but what you want to do is essentially Single Sign-On (SSO). So you can look into SSO implementations and libraries that you can use rather than inventing it all yourself. – PwdRsch Jun 29 '17 at 19:18
  • Just to be clear, a few questions: -1- Do you own/control both services? That is, can you add arbitrary code to both of them? -2- Assuming #1 is true (and possibly even if not), you should be able to communicate between services, server-to-server, directly; is there any reason you cannot or that it's expensive to do so? – CBHacking May 28 '18 at 20:19

This is very like a single-sign-on service, except usually there you don't control all of the services yourself (instead, one of them is controlled by the SSO provider, such as Facebook or Google). You can look at OAuth2 for some ideas of how SSO is most commonly implemented, but it's honestly overkill for a scenario where you control both services.

Assuming for the moment that you control both services and calls between them are sufficiently cheap, one simple solution is to have one of them be the source of truth on identity, so service2 simply checks service1 for confirmation of who the user is and what they can do (what their secret data is, how many credits they have, etc.), without storing any of that information itself. The problem then is linking the user's session across both services.

You can use the URL approach:

  1. service1 generates a single-use secure random token and passes it to service2 in the URL
  2. service2 sends that token to service1 through a direct channel
  3. service1 replies with a session identifier for the user's session and also any additional data service2 will definitely want
  4. service2 sets the session identifier from service1 as its own session identifier on the client (probably in a secure cookie) and optionally stores the required data in its own session state for that session

Alternatively, you can use CORS (Cross-Origin Resource Sharing), which is a way for a web browser to break the same-origin policy in a controlled way between sites that trust each other (and are possibly controlled by the same entity). CORS lets you make XMLHttpRequest or Fetch calls across origins and see the responses. An example might look like this:

  1. service2 gets a request from a new user who doesn't have a session, or a user whose session had expired
  2. service2 replies with a page containing script that makes a CORS request, with authentication, to service1
  3. Assuming the user is signed into service1, service1 accepts the CORS request and responds with a single-use securely random token
  4. The client-side script sends this token down to service2
  5. service2 sends this token to service1 via a direct back-channel
  6. service1 verifies the token and sends a session identifier to service2, etc.

This scheme is the same as passing the token in the URL, with two exceptions:

  • The token is never sent in the URL, and therefore much less likely to wind up somewhere it shouldn't like a server log or browser history.
  • The user can go directly to a service2 URL without clicking through a special link from service1, so long as they have an active session on service1.

Note that the session token itself is never sent in a response body (that the client sees). You could simplify this scheme if you did - then the client script would set the session ID in a cookie for service2, eliminating a client-service2 roundtrip and a service2-service1 roundtrip - but then an attacker with an XSS could steal the session token (as opposed to "merely" having complete remote control over the compromised session for as long as the user has the page loaded).

| improve this answer | |

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.