0
$\begingroup$

I have a question, or rather multiple questions that all relate to the same topic.

I am building an application with both a frontend (FE) and a backend (BE). All communication between FE and BE is protected with TLS. The BE contains an endpoint on which the frontend can register a new session. When setting up such a new session, a few things happen:

  1. FE sends a request (TLS protected) to BE, sharing a Curve25519 public key from a freshly generated Curve25519 keypair.
  2. BE receives this request. Creates a new Curve25519 keypair, uses HKDF to calculate a shared secret (using as input FE public key, BE private key and a salt) and ultimately create a new symmetric session key (ChaCha20-Poly1305)
  3. BE creates a new 32-byte (256-bit) session ID and keeps it in memory together with the session key.
  4. BE sends back the session ID + salt + public key from freshly generated Curve25519 keypair.
  5. FE uses BE public key + salt + FE private key to calculate same secret and create the session key.

Again I want to emphasise all of the above communication (so the request + response) happens over TLS. For all future communication, FE will encrypt all requests using the session key. The encrypted request is encoded to base64, and put in a JSON request body together with the unencrypted sessionID:

{
    "sessionID": "SomeString",
    "encryptedRequest: "base64 encrypted request"
}

These requests are then send (along with the unencrypted session ID) over a TLS connection, resulting in double encryption. When BE receives these requests, it will lookup the required session key by using the provided session ID. Then, it will decrypt the encryptedRequest field and forward it to the appropriate endpoint.

Some questions I have with this setup are:

  1. Because all requests are encrypted with the session key, can that act as a form of proof that the client is the real owner of the session ID? e.g. If the session ID somehow is stolen, it can still not be used to communicate to the backend as you still would need to have ownership over the shared secret.
  2. How much added security does this setup give if for some reason the TLS connection is broken into? (e.g. due to MITM, or because the TLS-level encryption is broken)
  3. Does this setup aid in API obfuscation? E.g. client-side you can install software that - prior to TLS encryption occurring - can inspect all incoming and outgoing traffic. For my application, they would only see requests that are already encrypted. Is it easy to work around this?

I'm curious about what you guys think. I've been experimenting a bit with these topics (i'm by no means a cryptography expert) and I would love to learn more.

$\endgroup$
1
$\begingroup$
  1. Because all requests are encrypted with the session key, can that act as a form of proof that the client is the real owner of the session ID? e.g. If the session ID somehow is stolen, it can still not be used to communicate to the backend as you still would need to have ownership over the shared secret.

That depends. I don't see any explicit check for this defined. I also don't see any specific mention of defusing replay attacks (in both ways, as there is only one encryption key, it seems). Also, 32 bit isn't much to avoid either integer overruns or collisions, so an attacker with another valid TLS key may retry until such an ID is created.

  1. How much added security does this setup give if for some reason the TLS connection is broken into? (e.g. due to MITM, or because the TLS-level encryption is broken)

None, as you don't perform any authentication of or after the key exchange.

  1. Does this setup aid in API obfuscation? E.g. client-side you can install software that - prior to TLS encryption occurring - can inspect all incoming and outgoing traffic. For my application, they would only see requests that are already encrypted. Is it easy to work around this?

No, it won't aid in API obfuscation, and yes, it is easy to work around this because of 2. And if you have an unencrypted part then an attacker can do an MITM there.

Better to just rely on TLS.

$\endgroup$
7
  • $\begingroup$ I have some questions with regards to your first point; what do you mean with "An attacker with another valid TLS key may retry until such an ID is created"? As a client you need to have posession of both the session ID and the session key in order to perform requests successfully. Even if the attacker has a valid session key, it's exclusively linked to his own session ID and cannot be used in combination with other session IDs. So I don't really see how doin ginteger overruns or collisions on the session ID is a valid attack in this case? $\endgroup$ – ImJustACowLol Jan 31 at 9:55
  • $\begingroup$ With regards to your last comment: "And if you have an unencrypted part then an attacker can do an MITM there"; everything is protected by TLS as well. If somehow, TLS is broken then the only unencrypted part is the SessionID. The attacker could replace it with another value (either a valid session ID or an invalid one) but still can't read the actual payload (the encryptedRequest property itself). If the attacker changes the sessionID value, the request cannot be decrypted by backend and it will simply be rejected. So I'm not sure to what extend damage can be done there? $\endgroup$ – ImJustACowLol Jan 31 at 9:58
  • $\begingroup$ Also, thank you for your time to look into this :) I'm always happy to learn new things. $\endgroup$ – ImJustACowLol Jan 31 at 9:58
  • 1
    $\begingroup$ I didn't change the protocol, I made a typo which I corrected. With regards to "The session ID is linked to the session key. Really, how can we tell?": the post contains the following phrase: "When BE receives these requests, it will lookup the required session key by using the provided session ID.". So based on the sessionID it determines which key needs to be used to decrypt the request. I hope that clarifies it a bit. If you don't want to go deeper, I understand. Thank you for your time/contribution either way. $\endgroup$ – ImJustACowLol Jan 31 at 13:21
  • 1
    $\begingroup$ Yeah, OK, but it wasn't described what happened on an ID clash. If that would happen (unlikely now that the session ID size has suddenly multiplied by 8) then you get into trouble if you e.g. assign access conditions to the ID. $\endgroup$ – Maarten Bodewes Jan 31 at 14:45

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.