I've read here that HTTPS replay attacks aren't possible from MITM attacks but I want to be sure that it's not saying that HTTPS replay attacks aren't possible at all. I want to know if I have to implement my own obscure method for temporarily preventing the inevitable or if something like this already exists.

Suppose the attacker is the client. They have access to the client and are communicating with the server legitimately, analyzing the traffic. Therefore the attacker has access to the client's private key (or at least, the ability to replicate its generation). What's stopping them from just replaying the traffic through a fake client after sniffing the payload before it's encrypted? That is to say, running it through the client to encrypt it then send it themselves.

My client relies on the hardware information from the system to validate one-user-per-subscription and want to know what all of the weak points are for this system. Spoofing it seems really easy if they generate it normally once then spoof it every time after.

2 Answers 2


Your attacker can replicate any HTTP message and is indistinguishable from a legitimate client.

In this case, the replay defense has to be at the HTTP application layer (the web server or web application needs explicit code to prevent replays). Something like POE (POST Once Exactly) can help prevent a literal re-POST.

Note, however, that an attacker in this position likely also gets the nonces used for POE, so its unlikely a reliable defense against a concerted attacker in this position is possible or practical to fully defend against.

You should consider upgrading your one-per-user subscription shared secret to be based on public key cryptography and digital signatures. The initial subscription would generate an asymmetric key pair, store the private key, and submit the public key to the server and thereafter the server would submit challenges the client must sign with their private key and the server would validate the signature against the public key on file. This is not something I would recommend inventing, but instead looking at options for using existing digital signature libraries or even the secure enclave on the client to perform if its available to your client app. The private key should never be exchanged so the attacker should not have access without persistent total compromise of the client.

  • 1
    Expanded my answer to include a possible solution using public key crypto and digital signatures. Jun 21, 2020 at 19:41
  • 1
    Fantastic idea of sending digital signing challenges. I'll think this through some more then attempt an implementation. Could you tell me more about the client having the private key without it being transferred from the server? Would this be embedded in the client or something generated per session?
    – user237038
    Jun 21, 2020 at 19:47
  • 1
    You've used SSH, right? Maybe for GitHub, maybe to admin a web server? The client can use ssh-keygen to make a key and then supplies the key to an administrator or an API which makes it usable in subsequent SSH sessions. In this case the private key never leaves the client. I'm not suggesting ssh-keygen for your case. Ideally you could use a secure enclave API to do signing with a private key that never leaves the enclave. Worst case you could generate an RSA or ECC key on the client and attempt to store the private key securely (very hard to do right). Jun 21, 2020 at 19:52
  • 1
    On iOS you can use the Secure Enclave frameworkfor this as described here. developer.apple.com/documentation/security/… Jun 21, 2020 at 19:54
  • 1
    What is your client running on? I would not attempt to build an enclave. It's a hardware thing. Your platform either has one or it doesn't. If it doesn't, you'll need a suitable software-based keystore as a fallback. Jun 21, 2020 at 20:15

A replay attack at the TLS level (and thus HTTPS) as you imagine would mean that some attacker could simply replay a captured TLS session or inject a previously captured packet into an existing TLS session.

None of this is possible: Replaying a full session cannot be done since the master_secret as the base for encryption includes both client and server random data, i.e. the master_secret does not depend on the client alone. Injecting a previously sniffed record is not possible since each record has a sequence number and simply replaying a record will be detected due to an old sequence number. Changing the sequence number will not work either since it is protected against manipulation like the rest of the record.

But if an attacker has access to the plain (unencrypted) request he can simply replay this request within some new TLS session. This would be HTTP level replay though and not TLS or HTTPS level replay.

My client relies on the hardware information from the system to validate one-user-per-subscription ...

Based on this your client relies on the client not cheating in the first place - which is contrary to the attack vector you describe. But a client could do cheating: for example the client could run in some emulated environment which can be cloned and exhibit the same behavior in another system.

The client could also partially reverse engineer or hook your app to capture and modify the plain request before it gets send. This way it can capture the plain (unencrypted) request on one system and make sure that the other system uses the same request.

  • The system itself is too tedious to reverse engineer. I can guarantee no attacker will spend the time on the client itself. But, I suspect they will attempt an easy replay to get information from the server.
    – user237038
    Jun 21, 2020 at 19:48
  • @superdeveloper: Again, TLS/HTTPS level replay is not possible. If all what the attacker can is sniffing and modifying the traffic and trying to replay it then it will fail. Jun 21, 2020 at 19:49
  • Sure, from a MITM perspective. But assume they create their own, minimal version of the client that just spoofs communication -- what can I do to validate that this message is only from right now and not from long ago, being re-encrypted and replayed?
    – user237038
    Jun 21, 2020 at 19:52
  • @superdeveloper: This would require access to the original unencrypted HTTP request. This is only possible when hooking or reverse engineering the app - which you said that this would be too tedious. Or the malicious client would need to have access to the master_secret of the connection in order to decrypt traffic - but this is also only available when hooking or reverse engineering the client. Jun 21, 2020 at 19:57
  • Hm, I suppose then this is a non-issue and I'm simply being paranoid.
    – user237038
    Jun 21, 2020 at 19:59

You must log in to answer this question.