0

Let's say I have 2 SPAs (single page applications), SPA A and SPA B.

I want to share data between the 2 applications for an end-to-end flow.

How can I safely share data such that it would not be susceptible to a MITM attack. Even if the data is encrypted and it is passed via POST, it could still be generated by a different client and then a victim could be dropping into the middle of the end-to-end flow.

e.g.

  1. SPA A (Attacker) -> finds out what data is passed to SPA B via POST/GET/etc.
  2. Victim gets redirected to SPA B via Attacker's website with data from SPA A.
  3. Victim now did not complete the steps in SPA A but is dropped in to SPA B via MITM.

We can't check referrers because they are not reliable (Referrer-Policy no-referrer). We could use a whitelist but that is challenging if you have many different legitimate clients that direct to SPA B in the middle of the flow. We could drop a client cookie and include it in the data that gets sent to SPA B and then verify it doesn't change end-to-end.

Is there a more standardized way to take care of this situation to determine it's the same user end-to-end or check the referrer to make sure it wasn't a MITM?

19
  • "redirected to SPA B via Attacker's website with data from SPA A" - What do you mean by this? How can the attacker's web site the user's data from SPA A?
    – mentallurg
    Apr 1 at 15:02
  • @mentallurg since the data is passed between the SPAs via GET params in plain sight even though it's encrypted, it's still passed in a way that anyone could act as a MITM, or is there a better way to pass it that would solve this? Apr 1 at 17:42
  • To be clear, let's say I am the attacker on SPA A, I just get the URL that would go to SPA B then client redirect 302 the victim when they are on my site then it seems like they did the whole flow but the user actually changed.. Apr 1 at 17:43
  • OP, typically we use digital signatures to authenticate data. You might want to consider using client-side (in browser) crypto (see developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) to have user A sign the data that gets passed from SPA A to SPA B, using the user A's keypair. Then, user B at SPA B can verify the signature using user A's public key. This would thwart a MITM attack, as any attempt by a MITM to modify the data would break the signature. You just need a way for user B to authenticate user A's public key, but this can be done using a trusted CA.
    – mti2935
    Apr 1 at 18:38
  • 1
    OP, Yes, each client has a unique private/public keypair, and encryption takes place on the client-side, 'in browser' (using javascript). There are a number of ways that keys can be stored and managed by the client in such a system. See security.stackexchange.com/questions/247918/… for more info.
    – mti2935
    Apr 2 at 0:38

1 Answer 1

1

After a lot of back and forth in the comments with OP and @mentallurg, this question finally makes sense. OP has a system where the user starts some process at SPA A, then SPA A causes the user's browser to make a GET request to the server hosting SPA B, in order to redirect the user to SPA B, where the user completes the process. Information from the user's session with SPA A is included in this GET request, so that this information is transferred from SPA A to SPA B.

OP wants to ensure that the user actually starts the process at SPA A first, before completing the process at SPA B. This is to thwart an attack where an attacker starts the process at SPA A, then lures the user to the attacker's site (perhaps by phishing), then uses a 302 redirect to cause the user to make the same GET request to SPA B that the attacker would have made had the attacker completed the process himself. By doing this, the attacker dupes to the user into completing the second step of the process at SPA B, using information that the attacker 'planted' in the first step of the process at SPA A.

[Note: Part of the confusion around this question stems from the use of terms like 'MITM' and 'end-to-end' in ways that these terms are not normally used in information security.]

OP mentions the use of cookies as a possible solution. In general, a cookie can only be read by the same domain that set it. This is part of Same Origin Policy. So, if SPA A sets a cookie, SPA B would not be able to read the cookie. There is good reason for this - cookies often store sensitive information that users to not want to share with other sites. In other words, browsers try to prevent you from doing exactly what you are trying to do. However, there are some hacks workarounds to get around this, if it's possible for SPA A page to include some content from the domain that serves SPA B. See https://stackoverflow.com/questions/6761415/how-to-set-a-cookie-for-another-domain for some ideas around this.

As another way of getting around this, some sites use browser fingerprinting to track users from site to site. But, this is considered controversial, and is not recommended.

Perhaps a simple and non-invasive solution is to simply to ask the user for some secret that an attacker would not know when the user starts the process at SPA A (e.g. 'what city were you born in?'). Then, cryptographically tangle this secret in the GET request that takes the user from SPA A to SPA B. Then, ask the user to provide the same secret when he gets to SPA B, then verify that this secret is the one tangled in the GET request.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .