2

Why data exchange between two web applications using redirection with query parameters or auto-form-post CANNOT be trusted by each web application, even when using HTTPS?

Note:

I understand that data exchange using query parameters has inherent security risks like CSRF, leaking of data via browser history and access logs, and auto-form-post has inherent CSRF security risk. However, that is not the point of discussion here. Lets assume that we mitigated CSRF. The question at hand is, "Why can't each web application trust the exchanged data, even with HTTPS?"

Use Case: Consider two web applications running on https://one.abc.com and https://two.xyz.com. They both desire to exchange data but cannot communicate directly.

Detailed Flow: Upon visiting https://one.abc.com, a page displays a button. When clicked, it submits to https://one.abc.com, then redirects to https://two.xyz.com. On https://two.xyz.com, another button exists, which when clicked, submits to https://two.xyz.com and redirects to https://one.abc.com.

As everything occurs over HTTPS, all elements including URLs, query parameters, and headers are encrypted during redirection.

With this setup, data exchange between the two web applications can be achieved using query parameters or auto-form-post.

However, why can't each web application trust the exchanged data, even with HTTPS?

In simpler terms, during the first step, if https://one.abc.com sends data using redirection with query parameters or auto-form-post to https://two.xyz.com, https://two.xyz.com cannot trust that the data indeed originated from https://one.abc.com, even when HTTPS is used.

Similarly, during the second step, if https://two.xyz.com sends data using redirection with query parameters or auto-form-post to https://one.abc.com, https://one.abc.com cannot trust that the data indeed originated from https://one.abc.com, even when HTTPS is used.

The above technique is used in SAML, OIDC for SSO.

Please let me know if my following understanding is correct:

In the described redirect flow from one.abc.com to two.xyz.com and back to one.abc.com, the TLS (Transport Layer Security) encryption is established separately between your browser and each server involved. Let's break down the flow:

From one.abc.com to two.xyz.com:

  • When you click on the button on one.abc.com, your browser initiates a request to one.abc.com over HTTPS (HTTP over TLS).
  • one.abc.com responds with a redirect response (HTTP 302 Found) instructing your browser to go to two.xyz.com.
  • Your browser then initiates a new HTTPS request to two.xyz.com, establishing a separate TLS connection between your browser and two.xyz.com.

From two.xyz.com back to one.abc.com:

  • When you click on the button on two.xyz.com, your browser initiates a request to two.xyz.com over HTTPS (HTTP over TLS).
  • two.xyz.com responds with a redirect response (HTTP 302 Found) instructing your browser to go to one.abc.com.
  • Your browser then initiates a new HTTPS request to one.abc.com, establishing a separate TLS connection between your browser and one.abc.com.

Each of these connections (from your browser to two.xyz.com and from your browser back to one.abc.com) is encrypted using TLS independently. The TLS encryption ensures the confidentiality and integrity of the communication between your browser and each server, protecting the data exchanged during the redirect flow.

However, there's no direct TLS connection established between two.xyz.com and one.abc.com during the redirect flow. Instead, the HTTPS connections are terminated and re-established separately at each server endpoint.

For this reason in SAML, IDP signs the SAML assertion and in OIDC, OIDC Provider signs id_token.

1

3 Answers 3

2

Your understanding is correct, but when you ask about trusting data, it depends on who is supposed to trust what data.

HTTPS protects data in transit. This means when the client sends data to one.abc.com or two.xyz.com using HTTPS, then both the client and the server may assume the data can neither be read nor manipulated by a man-in-the-middle attacker. In this specific sense, they can trust the transmitted data.

However, HTTPS does not protect data before or after encryption. It also does not provide mutual authentication, unless client certificates are used (or some other authentication mechanism outside of HTTPS). And third, it's important to understand that HTTPS as a stateless protocol does not, by itself, allow you to keep track of a sequence of requests -- which is an issue if you assume there's a consistent flow of data from one.abc.com to two.xyz.com and back to one.abc.com.

This means:

  1. Attacks can happen both on one.abc.com and two.xyz.com despite the use of HTTPS. For example, if there's a cross-site scripting vulnerability on one.xyz.com, then an attacker may very well be able to manipulate the data which is sent to two.xyz.com -- the same can happen in the reverse direction.
  2. In HTTPS, the server authenticates to the client with a certificate, but the opposite is not necessarily true. Therefore, if one.abc.com and two.xyz.com receive requests, it may be unclear who is making those requests. It could be a legitimate client which follows the intended workflow, but it might as well be an attacker which just sends data directly to the servers. You need mutual authentication -- i.e., the client must also authenticate to the server -- both on one.abc.com and two.xyz.com. HTTPS supports client certificates for this purpose, but you can also use some other form of authentication (passwords, tokens etc.).
  3. Since HTTPS is stateless, you cannot tell from the protocol data whether the client is following the intended sequence of requests and redirects. Each request happens independently, and there's no reliable way to link requests to prior redirects. For example, if one.abc.com receives a request, it's unclear whether the client has previously visited two.abc.com and is now following the redirect back to one.abc.com. As far as HTTPS is concerned, the client can send any data to any server in any order. If you want to enforce a specific sequence, you must implement this outside of HTTPS.

I think this makes it clear that HTTPS alone is not sufficient to implement workflows. You need a lot more than in-transit protection if you want to exchange data between two servers over a series of requests.

1
  • Thanks for the response @Ja1024. I have modified the question, to make the use case more clear. I agree I did not make it clear that, who wants to trust data from whom. I made it very clear now.
    – mee
    Commented Mar 23 at 12:09
3

I'll first assume that the http method used with the query parameters is GET. Then data exchange using query parameters is not secure to send sensible data and this even when HTTPS is used.

Query parameters are just part of the url for example a website could make videos available using the following syntax: https://example.com/watch?v=XXXXXXXXXX where XXXXXXXXXX represent the video's ID. But when we're dealing with sensible informations/actions we should not use this method. If a bank uses query params with the following endpoint accessible by logged in customers: https://bank.example.com/send?money=123&to=destination then it becomes vulnerable because an attacker could spam the bank customers with a malicious link like https://attacker.example.com redirecting to https://bank.example.com/send?money=9999&to=attacker and eventually one of them will click on the link and send money by mistake.

The same attack can be performed when http method POST is used, the attacker can simply send a form with method POST to the bank endpoint automatically from victim's browser when the victim load the attacker website, with the following source code:

<form method="POST" action="https://bank.example.com/send" id="csrfform">
<input type="hidden" name="money" value="9999" autofocus onfocus="csrfform.submit();" /> 
<input type="hidden" name="to" value="attacker" autofocus onfocus="csrfform.submit();" /> <!-- Way 1 to autosubmit -->
<input type="submit" value="Submit request" />
<img src=x onerror="csrfform.submit();" /> <!-- Way 2 to autosubmit -->
</form>
<script>
document.forms[0].submit(); //Way 3 to autosubmit
</script>

All of the shown attacks are called Cross Site Request Forgery (CSRF) attacks and they have nothing to do with using https or not. HTTPS is here to ensure you're talking with the right server it doesn't prevent from all other attacks. To prevent those attacks it's recommended to use csrf-tokens which are tokens associated with user sessions to make sure the request comes from the website itself.

1
  • Thanks for the response @Mathys. I have modified the question, to make the use case more clear. I understand that data exchange using query parameters has inherent security risks like CSRF, leaking of data via browser history and access logs, and auto-form-post has inherent CSRF security risk. However, that is not the point of discussion here. The question at hand is, "Why can't each web application trust the exchanged data, even with HTTPS?"
    – mee
    Commented Mar 23 at 11:58
2

First, the connection using https is important (so that your browser connects to the real one.abc.com and two.xyz.com, and only they can read what you send and receive), but not relevant for this particular scenario.

As to the actual question, it is possible to make such communication secure, but it's brittle and not too easy to do properly.

We should remember that in a typical login, you will provide some credentials to https://one.abc.com, and that will set a session providing you a cookie, which lets the website identify you.

That session is then relevant so that the website (one.abc.com) can identify you (but note it still needs a csrf on their forms).

However, two.xyz.com, being on a different domain, per the same-origin policy, is unable to access the cookies at one.abc.com, so you are not logged into two.xyz.com. You would need to make the redirect login the user. But at the same time, that could become an avenue for session fixation attacks.

So, if one.abc.com is your bank, it cannot use a link to two.xyz.com to, say, debit your account in some amount. It's fine if the two.xyz.com is public (e.g. it only uses the parameters to prefill a form with your bank account, but you are not logged into xyz.com), but directly paying that, could easily also allow a malicious actor to instruct into getting payments into third-party ones.

Solutions around this include the parties sending signed payloads through urls (or body), and the two websites communicating directly some of the information, not only through the client browser.

2
  • Thanks for the response @Angel. I have modified the question, to make the use case more clear. The 2 servers can not communicate with each other. From your response I am assuming you are confirming my answer.
    – mee
    Commented Mar 23 at 12:03
  • @mee they might still manage to communicate through the client with some signed and encrypted blob...
    – Ángel
    Commented Mar 26 at 15:58

You must log in to answer this question.

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