Between 2011 and 2020, a run of named attacks (BEAST, CRIME, BREACH, Lucky Thirteen, Heartbleed, POODLE, FREAK, Logjam, DROWN, ROBOT and Raccoon) each broke one legacy part of SSL and TLS: predictable CBC IVs, compression, MAC-then-encrypt padding, export ciphers, RSA key transport, reused Diffie-Hellman keys, or simply a missing bounds check. TLS 1.3 (RFC 8446, August 2018) deleted almost every one of those features, and RFC 8996 (March 2021) formally retired TLS 1.0 and 1.1. What remains for defenders is configuration, library hygiene and the new risk TLS 1.3 itself introduced: replayable 0-RTT data.
This post is the history behind two of our shorter guides. If you want the handshake itself, read the TLS 1.3 handshake step by step. If you want a configuration checklist, read TLS 1.3 vs TLS 1.2: what to disable. The 0-RTT section here is a summary; our 0-RTT early data post goes further. For a close cousin in another protocol, see Terrapin, the SSH downgrade attack.
A note on scope: this is a defender's history. Each attack is described by mechanism, fix and lesson, with no payloads or attack steps.
Key takeaways
- Almost every attack targeted a feature already known to be weak and kept alive for compatibility. "Supported but rarely used" turned out to mean "attackable".
- Three families explain most of the list: CBC with MAC-then-encrypt (BEAST, Lucky Thirteen, POODLE), compression (CRIME, BREACH) and legacy key exchange (FREAK, Logjam, DROWN, ROBOT, Raccoon).
- Heartbleed is the outlier: a missing bounds check in one library. Its lessons are inventory, patching and key rotation.
- Downgrades were the multiplier, which is why TLS 1.3 puts a downgrade sentinel in the server random.
- TLS 1.3 removed static RSA, custom DH groups, compression, renegotiation and every non-AEAD cipher. It did not remove implementation bugs, BREACH, or the replay risk of 0-RTT early data.
- A modern audit is a few
openssl s_clientcommands, a check that no legacy service shares your private key, and a comparison against the TLSRef (formerly Mozilla) Server Side TLS profiles and NIST SP 800-52 Rev. 2.
The timeline at a glance
| Date | Event | What it targeted | Primary source |
|---|---|---|---|
| 1996 | SSL 3.0 released | Baseline protocol | RFC 7568 |
| January 1999 | TLS 1.0 published (RFC 2246) | Successor to SSL 3.0 | RFC 8996 |
| April 2006 | TLS 1.1 published (RFC 4346) with explicit CBC IVs | Fix for predictable IVs | RFC 4346, RFC 8996 |
| September 2011 | BEAST (CVE-2011-3389) | TLS 1.0 CBC chained IVs | RFC 7457, NVD |
| September 2012 | CRIME (CVE-2012-4929) | TLS level compression | RFC 7457, BREACH site, NVD |
| 4 February 2013 | Lucky Thirteen (CVE-2013-0169) | CBC padding and MAC timing | Royal Holloway Lucky 13 page |
| 2013 | BREACH presented at Black Hat USA | HTTP level compression | BREACH site |
| 7 April 2014 | Heartbleed (CVE-2014-0160) fixed in OpenSSL 1.0.1g | Implementation bug in heartbeat extension | OpenSSL advisory, CISA TA14-098A |
| October 2014 | POODLE (CVE-2014-3566); OpenSSL adds TLS_FALLBACK_SCSV on 15 October | SSL 3.0 padding plus fallback | POODLE advisory, OpenSSL advisory, NVD |
| 3 March 2015 | FREAK announced (OpenSSL client side fix CVE-2015-0204 shipped 6 January 2015) | RSA export downgrade | freakattack.com, OpenSSL vulnerabilities list |
| 20 May 2015 | Logjam (CVE-2015-4000) | DHE export downgrade and shared 1024-bit primes | weakdh.org |
| June 2015 | RFC 7568, "SSLv3 MUST NOT be used" | End of SSL 3.0 | RFC 7568 |
| 1 March 2016 | DROWN (CVE-2016-0800) | SSLv2 as a Bleichenbacher oracle | drownattack.com, OpenSSL vulnerabilities list |
| 3 May 2016 | CVE-2016-2107: a padding oracle introduced by the Lucky Thirteen fix | Constant time CBC code | OpenSSL vulnerabilities list |
| 12 December 2017 | ROBOT paper posted | RSA PKCS #1 v1.5 key transport | IACR ePrint 2017/1189 |
| August 2018 | TLS 1.3 (RFC 8446) | Removes most legacy features | RFC 8446 |
| August 2019 | NIST SP 800-52 Rev. 2 | Federal TLS configuration | NIST |
| 9 September 2020 | Raccoon (OpenSSL CVE-2020-1968) | Leading zero stripping in TLS 1.2 DH | raccoon-attack.com, OpenSSL vulnerabilities list |
| March 2021 | RFC 8996 deprecates TLS 1.0 and 1.1 | Retires old versions | RFC 8996 |
| November 2022 | RFC 9325 (BCP 195) replaces RFC 7525 guidance | Current IETF recommendations | RFC 9325 |
What state SSL 3.0 and TLS 1.0 were in, and why the attacks clustered between 2011 and 2016
The protocols attacked in this decade were old. RFC 7568 notes that SSL 3.0 was released in 1996 and replaced by TLS 1.0 in 1999, TLS 1.1 in 2006 and TLS 1.2 in 2008, yet "availability of these replacement versions has not been universal", so many implementations kept negotiating SSL 3.0. In 2011, a large share of browsers and servers still topped out at TLS 1.0.
Four design choices in those versions set up nearly every attack that followed.
MAC-then-encrypt with CBC. SSL 3.0 and every TLS version before 1.3 compute a MAC over the plaintext, add padding, then encrypt with a block cipher in CBC mode. The receiver must decrypt, then check padding, then check the MAC. Any difference in how it reacts to bad padding versus a bad MAC, in error messages or in time, becomes a padding oracle. RFC 7457 calls padding oracle attacks "a consequence of the MAC-then-encrypt design in all current versions of TLS" as of 2015.
Predictable IVs in TLS 1.0. TLS 1.0 used the last ciphertext block of the previous record as the IV of the next. An attacker who sees one record knows the IV of the next. TLS 1.1 changed this: RFC 4346 says the implicit IV "was replaced with an explicit IV to protect against CBC attacks". But TLS 1.1 adoption was slow.
Weak and optional algorithms kept for compatibility. RC4, export grade RSA and DH (deliberately limited to 512-bit keys under 1990s US export rules), static RSA key transport, DSA, MD5 and SHA-1 all remained negotiable. RFC 8996 points out that the handshake integrity of TLS 1.0 and 1.1 itself depends on SHA-1, or on an MD5 and SHA-1 concatenation that is "not appreciably stronger than a SHA-1 hash".
A version negotiation that clients worked around. Some servers broke when offered a higher version than they knew, so browsers retried failed handshakes at lower versions. The POODLE advisory notes this "downgrade dance" can be triggered "by active attackers". That workaround turned many paper weaknesses into practical attacks.
Why did the attacks cluster after 2011? Most underlying weaknesses had been described years earlier (Bleichenbacher's RSA attack dates from 1998), but Internet wide scanning now let researchers publish how many real servers were exposed. "Theoretically weak" became "33 percent of HTTPS servers", a number operators could not ignore.
BEAST, CRIME and BREACH: what each exploited and how it was fixed
BEAST (2011): chained IVs in TLS 1.0 CBC
What it exploited. RFC 7457 says BEAST (Browser Exploit Against SSL/TLS, by Juliano Rizzo and Thai Duong) used "the predictable initialization vector" of TLS 1.0 CBC to decrypt HTTP cookies. If you know the next IV and can make the victim's browser encrypt data you partly choose, you can test guesses about a secret one byte at a time. It needed script in the victim's browser and a network position.
The fix. The protocol fix already existed in TLS 1.1 (explicit per record IVs). Because TLS 1.1 was not widely deployed, the short term fixes were changes inside clients, mainly splitting records so that the first block an attacker could influence no longer had a predictable IV. Many operators also moved to RC4 to avoid CBC entirely, an option the Lucky Thirteen authors still listed in 2013 as a temporary measure. That advice aged badly: RFC 7465 banned RC4 in February 2015 after keystream bias attacks.
Lesson. A fix in a newer protocol version does nothing until both ends negotiate it, and swapping one weak primitive for another only buys time.
CRIME (2012): compression leaks length
What it exploited. CRIME, also by Rizzo and Duong, presented at Ekoparty in September 2012, targets TLS level compression. An attacker who can inject partly chosen plaintext into a victim's requests and measure the encrypted size can recover secrets, because compression shrinks repeated strings: a correct guess about a cookie yields a slightly smaller record. Encryption hides content, not length.
The fix. Turn off TLS compression. The BREACH site notes TLS compression was "already little-used, and in fact disabled in most browsers", so the attack as demonstrated was "completely mitigated" by disabling it. NIST SP 800-52 Rev. 2 now says the null compression method shall be used, RFC 9325 says deployments should not support TLS level compression, and TLS 1.3 requires the compression field to contain exactly one byte set to zero.
BREACH (2013): the same idea, one layer up
What it exploited. BREACH applies the CRIME idea to HTTP response compression (gzip and deflate), which is far more common than TLS compression. Its authors list three conditions: the response is HTTP compressed, it reflects user input, and it contains a secret such as a CSRF token. They stress that the attack "is agnostic to the version of TLS/SSL" and "works against any cipher suite".
The fix. There is no protocol level fix; RFC 7457 points to application changes. The BREACH site lists, in order of effectiveness: disabling HTTP compression, separating secrets from user input, randomising or masking secrets per request, CSRF protection, length hiding and rate limiting.
Lesson. Length is metadata, and metadata leaks. TLS 1.3 does not fix BREACH; a compressed page mixing attacker input with a secret is still at risk in 2026.
| Attack | Year | Layer | Attacker needs | Fix at the time | Status under TLS 1.3 |
|---|---|---|---|---|---|
| BEAST | 2011 | TLS 1.0 record layer | Network position plus script in the victim's browser | Record splitting in clients; TLS 1.1 explicit IVs | Gone: no CBC, no TLS 1.0 |
| CRIME | 2012 | TLS compression | Network position plus chosen plaintext injection | Disable TLS compression | Gone: compression removed |
| BREACH | 2013 | HTTP compression | Same as CRIME, against responses | Application changes (masking, separation) | Still applies |
Lucky Thirteen and POODLE: padding oracles and the end of SSL 3.0
Lucky Thirteen (2013): a timing oracle in the TLS specification
Nadhem AlFardan and Kenny Paterson of Royal Holloway, University of London, published Lucky Thirteen on 4 February 2013. Their page states the attacks "arise from a flaw in the TLS specification rather than as a bug in specific implementations" and apply to all TLS 1.1 and 1.2 and DTLS 1.0 and 1.2 implementations that follow the spec, plus SSL 3.0 and TLS 1.0 implementations that carry earlier padding oracle countermeasures. All CBC suites were potentially affected.
Why "thirteen". The TLS MAC covers 13 bytes of header data: 5 bytes of record header plus an 8 byte sequence number. That number shifts where block boundaries fall in the MAC computation, and with it how many hash compression function calls a malformed record costs. The authors explain that this is "in part" what makes a small timing difference measurable.
How bad it was. Against OpenSSL they reported full plaintext recovery; against GnuTLS, partial recovery. The TLS variant is multi-session: the secret must be resent in the same position across many connections.
The fixes. The authors note random delays fail because averaging removes them, and RC4 was only a stopgap. The real answers were AEAD suites such as AES-GCM, or constant time CBC decryption. RFC 7457 adds encrypt-then-MAC (RFC 7366, September 2014); NIST SP 800-52 Rev. 2 requires servers that offer CBC suites to support it.
The lesson within the lesson. Constant time code is hard. OpenSSL's own vulnerability list records that CVE-2016-2107, published 3 May 2016, was "introduced as part of the fix for Lucky 13". The rewritten padding check no longer verified that a record was long enough to hold both MAC and padding, which created a new padding oracle on servers using AES-NI. A protocol that needs heroic implementation care to be safe will eventually ship an implementation that is not.
POODLE (2014): the oracle SSL 3.0 could not patch
POODLE stands for Padding Oracle On Downgraded Legacy Encryption. The advisory by Bodo Möller, Thai Duong and Krzysztof Kotowicz is dated September 2014; the CVE record (CVE-2014-3566) was published 15 October 2014.
What it exploited. In SSL 3.0, CBC padding "is not deterministic, and not covered by the MAC", so a receiver cannot fully check it. Under the right conditions an attacker can swap a block and observe whether the server accepts the record. The advisory gives the cost: acceptance happens "on average, once in 256 requests", for an expected effort of "256 SSL 3.0 requests per byte". For a 32 byte session cookie that is on the order of 8,192 requests: a lot for a person, very little for a script.
Why downgrade mattered. Few clients chose SSL 3.0. But browsers that retried with lower versions after a failed handshake could be pushed into SSL 3.0 by an attacker who simply broke the first attempts. Unlike BEAST and Lucky Thirteen, the advisory says, "there is no reasonable workaround" for SSL 3.0 CBC, and RC4 was already biased. That left SSL 3.0 with no safe cipher at all.
The fixes. Short term, TLS_FALLBACK_SCSV: a signalling value a client adds when it is retrying at a lower version, so a server that supports something higher can refuse the downgrade. OpenSSL shipped support in its 15 October 2014 release (1.0.1j, 1.0.0o and 0.9.8zc), and the IETF published it as RFC 7507 in April 2015. Long term, RFC 7568 (June 2015) says plainly that "SSLv3 MUST NOT be used" and that a server receiving a hello at version 3.0 must answer with a protocol_version alert. RFC 7568 lists why SSL 3.0 could not be repaired in place: its CBC construction is broken, RC4 is unfit, its key exchange is open to renegotiation and resumption attacks that TLS fixed through extensions, and extensions themselves did not exist in SSL 3.0.
Lesson. Padding oracles reward any observable difference; the durable fix is AEAD. Client downgrade logic is attack surface. A version that cannot carry extensions cannot be patched, only retired.
RFC 8996 later obsoleted RFC 7507 as well: once TLS 1.0 and 1.1 are gone, there is nothing left to fall back to.
Heartbleed: an implementation bug, not a protocol flaw
Heartbleed (CVE-2014-0160) belongs in this history because of its scale, but it is a different kind of failure. The Heartbleed site answers the question "Is this a design flaw in SSL/TLS protocol specification?" with "No. This is implementation problem". RFC 7457 calls it an attack that "exploits a simple coding mistake (bounds check)".
What happened. OpenSSL's heartbeat extension (RFC 6520) echoes back data a peer sends. The vulnerable code trusted a length field without checking it against the actual payload, so a peer could ask for more bytes than it sent and receive whatever sat next in memory. OpenSSL's advisory of 7 April 2014 says this could "reveal up to 64k of memory to a connected client or server", and CISA's alert TA14-098A adds that an attacker can repeat the request "to retrieve as many 64k chunks of memory as are necessary". It worked in both directions: servers could read client memory too.
How long it was there. According to the Heartbleed site, the bug entered OpenSSL in December 2011 and shipped in OpenSSL 1.0.1 on 14 March 2012. OpenSSL 1.0.1 through 1.0.1f and 1.0.2-beta1 were affected; 1.0.1g fixed it; the 0.9.8 and 1.0.0 branches never had it. The site notes they had been "rapidly adopted by modern operating systems". Two research teams found it independently.
What the response looked like. The response had four layers, and most organisations learned the hard way that patching was only the first.
- Patch the library. Upgrade to 1.0.1g, or, as OpenSSL's advisory allowed for those who could not upgrade at once, rebuild with
-DOPENSSL_NO_HEARTBEATS. - Restart everything that loaded it. A patched shared library on disk does nothing for a process that already mapped the old one into memory.
- Treat keys as stolen. CISA's guidance was that "any keys generated with a vulnerable version of OpenSSL should be considered compromised and regenerated" after patching, which meant new certificates and revocation of old ones.
- Reset what the keys protected. The Heartbleed site sorts leaked data into primary key material, secondary key material (user names and passwords), protected content, and collateral such as memory addresses. Session cookies and passwords had to be invalidated after the service itself was trustworthy again.
CISA also recommended forward secrecy: with static RSA key exchange a stolen key decrypts every recorded session; with ephemeral (EC)DHE it does not.
Lesson. You cannot patch what you cannot find: OpenSSL sat in appliances, static binaries and language runtimes, and many teams spent weeks just listing where. An extension you never use is still code you ship. And key rotation must be rehearsed before the day you need it.
FREAK and Logjam: export cipher downgrades and Diffie-Hellman parameter lessons
Export grade crypto in one paragraph
In the 1990s, US export rules limited cryptographic strength in software shipped abroad, so SSL and early TLS carried "export" suites with 512-bit RSA or DH and 40-bit or 56-bit symmetric keys. The rules were later relaxed, but the suites lingered in code and configurations until 2015. RFC 9325 now forbids suites under 112 bits of security and names export ciphers as insecure.
FREAK (2015): a client bug that accepted export RSA
FREAK was announced on 3 March 2015, discovered by Karthikeyan Bhargavan at INRIA and the miTLS team, with tracking data kept by researchers at the University of Michigan. The underlying flaw was in clients: they would accept a short, export grade RSA key from a server even though they had not asked for an export suite. OpenSSL's description of its instance, CVE-2015-0204 (fixed on 6 January 2015), is that "an OpenSSL client will accept the use of an RSA temporary key in a non-export RSA key exchange ciphersuite". A network attacker could steer a connection to a server that still supported RSA_EXPORT, then factor the 512-bit key and read or alter the session.
On 3 March 2015, 36.7 percent of HTTPS servers with browser trusted certificates accepted RSA_EXPORT suites; the tracking site later recorded that figure at 6.5 percent as operators removed them.
The fix. Patch clients and remove every EXPORT suite from servers.
Logjam (2015): the same downgrade, against Diffie-Hellman, in the protocol itself
Logjam was made public on 20 May 2015 by a team of fourteen researchers from French research institutes, US universities and an industry lab (the paper later won best paper at ACM CCS in October 2015). The weakdh.org site says it lets a network attacker "downgrade vulnerable TLS connections to 512-bit export-grade cryptography". The important difference from FREAK: Logjam was "due to a flaw in the TLS protocol rather than an implementation vulnerability". In TLS 1.2 and earlier, the server's signature over DHE parameters did not bind the cipher suite, so an export group could be passed off as a normal one.
The researchers measured that 8.4 percent of the Top 1 Million HTTPS domains, 14.8 percent of SMTP with STARTTLS hosts and 8.9 percent of POP3S hosts were vulnerable at disclosure.
The bigger finding was about shared primes. The most efficient way to break finite field DH, the number field sieve, does most of its work on the prime alone. Once that precomputation is done for a given prime, individual connections using it fall quickly. Millions of servers used the same few primes. The team carried out the precomputation for the most common 512-bit prime and showed Logjam could then downgrade connections to 80 percent of servers supporting DHE_EXPORT. They estimated an academic team could break a 768-bit prime and a nation state a 1024-bit one, and that breaking the single most common 1024-bit prime would expose 17.9 percent of Top 1 Million HTTPS domains to passive decryption. A second common prime would expose 66.1 percent of IPsec VPN servers and 25.7 percent of SSH servers.
The fixes. Disable export suites, use DH groups of at least 2048 bits, prefer elliptic curve DH, and make clients refuse small groups: OpenSSL's 11 June 2015 release (1.0.2b, 1.0.1n) began rejecting DH parameters under 768 bits, with 1024 planned. RFC 7919 (August 2016) then defined named groups (ffdhe2048 and up) so servers stop inventing their own. The wider lesson: a 1024-bit prime shared by millions of hosts is a far bigger target than one used by a single host, and a signature that does not cover its context does not protect it.
| Item | FREAK | Logjam |
|---|---|---|
| Announced | 3 March 2015 | 20 May 2015 |
| Key exchange | RSA (export) | DHE (export) |
| Root cause | Client implementation bug (for example CVE-2015-0204) | TLS protocol flaw (CVE-2015-4000) |
| Scale at disclosure | 36.7% of browser trusted HTTPS servers accepted RSA_EXPORT | 8.4% of Top 1M HTTPS domains supported DHE_EXPORT |
| Server fix | Remove EXPORT suites | Remove EXPORT suites; 2048-bit or larger groups |
| Client fix | Reject unexpected export RSA keys | Reject small DH groups (OpenSSL: 768 bits, then 1024) |
| Wider lesson | Dead cipher suites are live attack surface | Shared primes concentrate risk; use named groups or ECDHE |
DROWN, ROBOT and Raccoon: RSA and DH side channels
DROWN (2016): SSLv2 on any host breaks TLS on every host sharing the key
DROWN, short for Decrypting RSA with Obsolete and Weakened eNcryption, was disclosed on 1 March 2016 (CVE-2016-0800). Its site calls it "a new form of cross-protocol Bleichenbacher padding oracle attack".
What it exploited. A server still accepting SSLv2 (prohibited by RFC 6176 in 2011) could act as an oracle to decrypt RSA key exchanges from TLS 1.2 connections that used the same RSA key. The site reports the general variant took under 8 hours, and a variant using older OpenSSL bugs under a minute on a single PC.
Why it surprised people. Two details made DROWN far bigger than "turn off SSLv2". First, the oracle did not have to be the web server. The site says a server is vulnerable if its private key "is used on any other server that allows SSLv2 connections, even for another protocol", for example a mail server sharing a certificate with the website. Second, OpenSSL had a bug (CVE-2015-3197) that let a client negotiate SSLv2 ciphers the server had disabled, so some servers that looked safe in their configuration were not.
At disclosure the team measured 33 percent of all HTTPS servers as vulnerable; by 2019 they cite an estimate of 1.2 percent. Forward secrecy did not fully protect a server, since an active variant could reach clients and servers that preferred non RSA key exchange.
The fix. Make sure no software anywhere that holds a given private key accepts SSLv2. OpenSSL 1.0.2g and 1.0.1s disabled SSLv2 at build time by default and removed EXPORT and LOW ciphers from default builds. No certificate reissue was needed, because DROWN decrypts sessions; it does not recover the private key.
ROBOT (2017): Bleichenbacher, nineteen years later
ROBOT, the Return Of Bleichenbacher's Oracle Threat, by Hanno Böck, Juraj Somorovsky and Craig Young, was posted to the IACR ePrint archive on 12 December 2017 and later published at USENIX Security 2018.
What it exploited. In 1998 Daniel Bleichenbacher showed that if a server reveals, by error message, timing or connection behaviour, whether an RSA ciphertext had valid PKCS #1 v1.5 padding, an attacker can decrypt it with many adaptive queries. TLS papered over this with countermeasures instead of removing RSA key transport. The ROBOT team found that "with some slight variations" the oracle still existed in many products. Their paper says it affected "almost a third of the top 100 domains" in the Alexa Top 1 Million at the time, across implementations from at least eight vendors and open source projects.
The fix. Patch the affected implementation, but the authors' main advice is blunter: "Disable RSA encryption!" That means every suite whose name starts with TLS_RSA_WITH. Suites with ECDHE or DHE that use RSA only for signatures are not affected. They found the compatibility cost low.
Raccoon (2020): a timing leak written into the TLS 1.2 specification
Raccoon was disclosed on 9 September 2020 by Robert Merget, Marcus Brinkmann, Nimrod Aviram, Juraj Somorovsky, Johannes Mittmann and Jörg Schwenk. Its site calls it "a timing vulnerability in the TLS specification".
What it exploited. In TLS 1.2 and earlier, the DH shared secret has leading zero bytes stripped before it enters the key derivation function. A shorter input can hash in fewer compression function calls, so with very precise timing an attacker can learn whether a computed secret began with a zero byte. If a server reuses the same DH secret across connections, an attacker who recorded one handshake can send related values in new handshakes, collect "starts with zero" answers and solve for the original secret with a lattice technique called the Hidden Number Problem.
Why it was rated low for most. Two prerequisites cut exposure sharply: the server must reuse its DH key (static DH suites, or DHE with ephemeral key reuse), and the attacker must be close enough to take very precise timings. The researchers advise most admins "Probably not" to drop everything. They measured 3.33 percent of the Alexa Top 100k reusing ephemeral DH keys at least once. OpenSSL rated its instance (CVE-2020-1968) Low and fixed it in 1.0.2w; Firefox dropped DH and DHE suites in Firefox 78 in June 2020.
The fix in the protocol. RFC 8446 section 7.4.1 says the finite field DH secret is "left-padded with zeros up to the size of the prime", noting this "differs from previous versions of TLS which removed leading zeros". The Raccoon site credits the change to TLS 1.3 draft 14.
What DROWN, ROBOT and Raccoon taught defenders
- A private key's exposure is the union of every service that uses it. Inventory keys, not just hosts.
- RSA key transport cannot be made safe by countermeasures alone. Twenty years of patches still left oracles. RFC 9325 says implementations should not negotiate static RSA suites, and TLS 1.3 dropped them.
- Forward secrecy is necessary but not always sufficient. RFC 8446 appendix E.8 warns that a TLS 1.3 server still supporting static RSA in older versions may allow impersonation, and that disabling static RSA "across all versions" prevents it.
- Ephemeral means ephemeral. Reusing DH keys for performance turned a theoretical leak into a practical one. RFC 9325 now advises TLS 1.2 implementations not to negotiate TLS_DHE suites at all, citing Raccoon and the slow uptake of RFC 7919.
How TLS 1.3 removed each attack class, and what remains
TLS 1.3 was published as RFC 8446 in August 2018. Its section 1.2 reads like a list of the attacks above.
| Attack class | TLS 1.2 and earlier feature it relied on | What TLS 1.3 did |
|---|---|---|
| BEAST, Lucky Thirteen, POODLE, CVE-2016-2107 | CBC with MAC-then-encrypt | Only AEAD algorithms remain; no CBC suites exist |
| RC4 biases | RC4 stream cipher | Removed |
| CRIME | TLS compression | Removed; the compression field must be a single zero byte |
| FREAK, Logjam | Export suites; custom DHE groups; signatures that did not bind the suite | No export suites; custom DHE groups removed in favour of named groups; the server signs the whole handshake transcript |
| ROBOT, DROWN (against TLS), Heartbleed key theft decrypting old traffic | Static RSA key transport | Static RSA and static DH removed; "all public-key based key exchange mechanisms now provide forward secrecy" |
| Raccoon | Stripping leading zeros from the DH secret | Secret left padded to the size of the prime |
| Renegotiation and triple handshake attacks | Renegotiation; resumption without session binding | Renegotiation removed; resumption replaced with a single PSK mechanism; key schedule redesigned around HKDF |
| POODLE style downgrade | Version fallback | Version list in an extension; downgrade sentinel in ServerHello.random |
| Passive metadata exposure | Certificates and extensions sent in clear | All handshake messages after ServerHello encrypted |
The downgrade sentinel
TLS 1.3 adds a check aimed squarely at the downgrade attacks of 2014 and 2015. RFC 8446 section 4.1.3 requires a TLS 1.3 server that negotiates TLS 1.2 to set the last 8 bytes of its random value to 44 4F 57 4E 47 52 44 01, and to 44 4F 57 4E 47 52 44 00 if it negotiates TLS 1.1 or lower. Those bytes spell "DOWNGRD" in ASCII. A TLS 1.3 client that sees either value in a ServerHello for an older version must abort. Because the server signs the random values in TLS 1.2 ECDHE and DHE handshakes, an attacker cannot strip the marker. The RFC is candid that this provides "limited protection" and does not help when static RSA is used, which is one more reason to disable static RSA.
What TLS 1.3 did not remove
Implementation bugs, application leaks and validation mistakes. A Heartbleed class bug can happen in any version, BREACH lives in HTTP, and RFC 7457's list of clients that skip certificate or name validation is not a protocol issue.
Legacy versions on the same server. A server that speaks TLS 1.3 but still accepts TLS 1.0 with RSA key exchange keeps the old attack surface.
0-RTT replay. TLS 1.3 added zero round trip early data so a resuming client can send its first request with the handshake. RFC 8446 section 8 says plainly that "TLS does not provide inherent replay protections for 0-RTT data". An attacker who captures the first flight can send it again. Appendix E.5 lists what that enables: duplicated side effects such as a repeated purchase or transfer, reordering of messages, and cache timing probes. RFC 8446 describes server side defences (single use tickets, ClientHello recording, freshness checks) but accepts that not every deployment will run them, so clients must send only replay safe data early. RFC 8470 gives HTTP its rules, including the Early-Data request header and the 425 Too Early status a server returns to make the client retry after the handshake. RFC 9325 sets the bar for everyone else: applications must avoid 0-RTT unless an explicit specification for their protocol says when it is safe.
The practical rule: leave 0-RTT off unless you have a reason and a replay defence; our 0-RTT post covers configuration.
How to audit a server's TLS configuration today
For each endpoint, the audit answers: which versions, key exchanges, record protection and DH sizes it accepts, whether it shares its key with anything older, and whether its library is current. An OpenSSL 3.x client covers most of it. Test only hosts you own or are authorised to test.
Step 1: list every endpoint and every key
Include mail (25, 465, 587, 993, 995), LDAPS (636), databases, admin interfaces, VPN portals and internal TLS services, and record which private key each uses. DROWN made this mandatory. Fingerprint each presented key to spot reuse:
HOST=example.com
PORT=443
openssl s_client -connect "$HOST:$PORT" -servername "$HOST" </dev/null 2>/dev/null \
| openssl x509 -noout -pubkey \
| openssl pkey -pubin -outform DER \
| openssl dgst -sha256
For mail, add -starttls smtp and the mail port. Identical hashes mean a shared key, so both endpoints must meet the same standard.
Step 2: see what a modern client negotiates
openssl s_client -connect example.com:443 -servername example.com -brief </dev/null
The brief output shows the protocol version, cipher, peer signature type and the key exchange group. You want TLSv1.3 with an AEAD suite such as TLS_AES_128_GCM_SHA256, and an ECDHE group (X25519, P-256) or a hybrid post quantum group if both sides support one.
Step 3: check that old versions are refused
# Each of these should fail with a protocol or handshake error.
openssl s_client -connect example.com:443 -servername example.com -tls1_1 -cipher 'DEFAULT@SECLEVEL=0' </dev/null
openssl s_client -connect example.com:443 -servername example.com -tls1 -cipher 'DEFAULT@SECLEVEL=0' </dev/null
The @SECLEVEL=0 matters: OpenSSL's documentation says that from security level 1 upward "TLS 1.0, TLS 1.1 and DTLS 1.0 are all disabled", so without it a failure describes your client, not the server. Current s_client has no SSL 3.0 option and SSLv2 left default builds in 2016, so check the server configuration for those, or use a purpose built legacy client.
Step 4: check TLS 1.2 key exchange and record protection
# Static RSA key transport (ROBOT, DROWN exposure). Should fail.
openssl s_client -connect example.com:443 -servername example.com -tls1_2 -cipher 'kRSA' </dev/null
# Finite field DHE (Raccoon, Logjam exposure). Ideally fails; if it succeeds, check the group size.
openssl s_client -connect example.com:443 -servername example.com -tls1_2 -cipher 'kDHE' </dev/null
# CBC suites with ECDHE. Acceptable only for old clients you have decided to support.
openssl s_client -connect example.com:443 -servername example.com -tls1_2 -cipher 'ECDHE:!AESGCM:!CHACHA20' </dev/null
If the DHE handshake succeeds, the full (non brief) output includes a Server Temp Key line; it should show at least 2048 bits. Anything at 1024 bits or below is the Logjam profile.
Step 5: check compression, renegotiation and early data
Run a full handshake without -brief and read the summary:
openssl s_client -connect example.com:443 -servername example.com -tls1_2 </dev/null 2>/dev/null \
| grep -E 'Compression|Secure Renegotiation|Protocol|Cipher'
You want Compression: NONE (CRIME) and Secure Renegotiation IS supported on TLS 1.2 (the RFC 5746 fix). For TLS 1.3, the session block printed after a resumption includes the maximum early data the server will accept; a value of 0 means 0-RTT is off. The -sess_out, -sess_in and -early_data options of s_client let you test a resumed session against your own server.
Step 6: confirm the library under the server
openssl version -a # the OpenSSL on this host
dpkg -l | grep -E 'libssl|openssl' # Debian and Ubuntu packages
rpm -q openssl openssl-libs # RHEL, Fedora, SUSE
python3 -c 'import ssl; print(ssl.OPENSSL_VERSION)' # the OpenSSL Python links against
node -p 'process.versions.openssl' # Node.js ships its own copy
docker run --rm --entrypoint openssl your-image:tag version # inside a container image
Heartbleed's lesson is that the version that matters is the one loaded by the running process, which may be a container layer, a vendored copy or a runtime's bundled build, not the host package. After upgrading, restart the services that loaded the old library.
Step 7: compare against a published profile
- TLSRef Server Side TLS. Mozilla's Server Side TLS wiki page now says the public guidelines have moved to a community project at docs.tlsref.org. Its Intermediate profile, recommended for general purpose servers, allows TLS 1.2 and 1.3 only, six ECDHE suites with AES-GCM or ChaCha20-Poly1305 for TLS 1.2, ffdhe2048 if DH is used, two year HSTS, and client cipher choice. The Modern profile is TLS 1.3 only. Both list X25519MLKEM768 first among key exchange groups.
- NIST SP 800-52 Rev. 2 (August 2019). Government only servers shall use TLS 1.2, should use TLS 1.3, should not use TLS 1.1 and shall not use TLS 1.0, SSL 3.0 or SSL 2.0. Citizen and business facing servers shall negotiate TLS 1.2 and may keep 1.1 and 1.0 only where needed, with Appendix F explaining how to decide. Agencies had to support TLS 1.3 by 1 January 2024. It also requires null compression and the extended master secret extension (RFC 7627).
A minimal server configuration that matches the Intermediate profile looks like this in nginx:
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;
ssl_early_data off;
add_header Strict-Transport-Security "max-age=63072000" always;
The cipher list is the TLSRef Intermediate list for TLS 1.2. Generate configs for your exact server version with the TLSRef configurator rather than copying from any blog post, including this one.
Step 8: map findings to the attack they enable
| Finding | Attack history it maps to | Action |
|---|---|---|
| SSLv2 accepted anywhere the key is used | DROWN | Disable SSLv2 on every service with that key; upgrade OpenSSL |
| SSL 3.0 accepted | POODLE | Disable; RFC 7568 forbids it |
| TLS 1.0 or 1.1 accepted | BEAST, SHA-1 handshake, RFC 8996 | Disable unless a documented legacy client population needs it |
| TLS_RSA_WITH suites accepted | ROBOT, DROWN, no forward secrecy | Remove all static RSA suites, in every version |
| EXPORT or LOW suites accepted | FREAK, Logjam | Remove; upgrade the library |
| DHE with 1024-bit or smaller group | Logjam | Remove DHE or move to ffdhe2048 or larger |
| DH key reused across connections | Raccoon | Upgrade; prefer ECDHE; drop static DH |
| CBC suites preferred over AEAD | Lucky Thirteen, CVE-2016-2107 | Prefer AEAD; keep CBC only for named old clients |
| RC4 offered | RC4 biases, RFC 7465 | Remove |
| TLS compression on | CRIME | Disable |
| HTTP compression on pages that mix user input and secrets | BREACH | Mask tokens; separate secrets; consider disabling compression on those responses |
| 0-RTT accepted for non idempotent requests | RFC 8446 section 8 replay | Turn off, or restrict to safe methods and pass the early data signal to the app |
| Library version predates key fixes | Heartbleed and successors | Upgrade, restart processes, rebuild images |
What deprecating TLS 1.0 and 1.1 (RFC 8996) means for old clients
RFC 8996, published in March 2021 as part of BCP 195, moved TLS 1.0 and 1.1 to Historic status and states that each "MUST NOT be used". Clients must not offer them; servers that receive a ClientHello for them must answer with a protocol_version alert. It also deprecates DTLS 1.0 (DTLS 1.2 is unaffected and there is no DTLS 1.1). The stated reasons are the lack of modern algorithms, the dependence of both versions on SHA-1 for handshake integrity and peer authentication, and the simple fact that TLS 1.2 had been the IETF recommendation since 2008. The RFC also notes that removing old versions "reduces the attack surface, reduces opportunity for misconfiguration, and streamlines library and product maintenance".
Who breaks
Anything that cannot speak TLS 1.2. The oldest clients the TLSRef Intermediate profile supports are Firefox 31.3.0, Android 4.4.2, Chrome 49, IE 11 on Windows 10, Java 8u161, OpenSSL 1.0.1l and Safari 9; it excludes "legacy clients such as Windows XP or old versions of OpenSSL". Older Android and Java runtimes, unpatched late 2000s Windows, and embedded devices with TLS stacks frozen at manufacture (printers, building controllers, payment terminals, industrial equipment) are the usual casualties.
Clients can also break the other way. Modern OpenSSL refuses TLS 1.0 and 1.1 at its default security level, so an up to date script or service calling an old internal server may fail even though nothing changed on that server.
How to handle the stragglers
| Situation | Recommended approach |
|---|---|
| Public website, general audience | TLSRef Intermediate: TLS 1.2 and 1.3 only |
| API or service with only modern clients you control | TLSRef Modern: TLS 1.3 only |
| Internal device that only speaks TLS 1.0 and cannot be upgraded | Isolate it on its own network segment; put a TLS terminating proxy in front so the rest of the network talks TLS 1.2 or 1.3 to the proxy; plan replacement |
| US federal system | Follow NIST SP 800-52 Rev. 2; TLS 1.0 not allowed for government only servers; TLS 1.3 support required since 1 January 2024 |
| Business partner integration stuck on TLS 1.0 | Give a dated cut off; run a separate endpoint with its own key for the legacy partner so the main key is never exposed to legacy protocols |
That last row is DROWN's lesson applied: if you must keep a legacy endpoint, never let it share a private key with your modern ones.
Measure before you cut: a week of logs with the negotiated protocol per connection turns a policy argument into a short list of client owners to contact.
Common mistakes
- Testing only port 443. DROWN and Logjam both counted mail protocols. Every TLS listener that shares a key belongs in scope.
- Trusting the config file alone. DROWN's CVE-2015-3197 let clients negotiate SSLv2 ciphers the server had disabled. Test the live endpoint as well as reading the config.
- Concluding a server is safe because your client refused. Modern OpenSSL will not offer TLS 1.0 or 1.1 at the default security level. Lower the level on the test client or the result is meaningless.
- Removing TLS_RSA suites from TLS 1.2 but leaving them in a legacy virtual host on the same key. RFC 8446 appendix E.8 warns that static RSA in any version can undermine TLS 1.3 on the same key.
- Keeping DHE "for compatibility" with a 1024-bit group. RFC 9325 now advises against TLS_DHE in TLS 1.2 altogether. ECDHE covers the same clients in nearly every case.
- Patching OpenSSL on the host while containers ship their own copy. The host package says fixed; the image layer says otherwise. Rebuild and redeploy images.
- Rotating certificates without new keys after a memory disclosure. A new certificate on the same key does not help if the key leaked. Generate a new key pair.
- Turning on 0-RTT at the edge for every request. Replay is a property of the protocol; the application has to decide what is safe to accept early.
- Copying cipher strings from an old guide. Many 2014 era configs still list RC4 or put CBC before GCM. Generate a fresh config from a maintained profile.
FAQ
Is Heartbleed a TLS protocol vulnerability?
No. Heartbleed (CVE-2014-0160) was a missing bounds check in OpenSSL's implementation of the heartbeat extension. The protocol was fine; the code was not. It affected OpenSSL 1.0.1 through 1.0.1f and was fixed in 1.0.1g on 7 April 2014.
Does TLS 1.3 prevent POODLE, BEAST and Lucky Thirteen?
Yes. All three attack CBC mode with MAC-then-encrypt, and TLS 1.3 removed every non AEAD cipher. TLS 1.3 also adds a downgrade sentinel to stop an attacker pushing a capable client back to an older version, though a server that still accepts SSL 3.0 or CBC suites in older versions remains exposed through those versions.
What is the difference between FREAK and Logjam?
Both downgrade connections to 512-bit export grade key exchange. FREAK (March 2015) targeted RSA and was a client implementation bug that accepted an export RSA key it had not asked for. Logjam (May 2015) targeted Diffie-Hellman and was a flaw in the TLS 1.2 protocol, because the server's signature over DH parameters did not bind the chosen cipher suite.
Is my server vulnerable to DROWN if it does not support SSLv2?
It can be. DROWN works if any server that uses the same RSA private key accepts SSLv2, even a mail server on another protocol. Check every service that holds the key, not only the website.
What should I do about ROBOT?
Patch the affected TLS implementation, and remove every cipher suite that uses RSA key transport (names beginning TLS_RSA_WITH). Suites that use ECDHE or DHE with RSA signatures are not affected. TLS 1.3 has no RSA key transport at all.
Is Raccoon something I need to fix urgently?
For most servers, no. It needs a server that reuses its DH key and an attacker able to take very precise timing measurements. Fix it by disabling static DH and DHE suites in TLS 1.2, preferring ECDHE, and upgrading old libraries. TLS 1.3 removes the leading zero stripping that caused it.
Is TLS 1.2 still safe to use in 2026?
Yes, when configured well: ECDHE key exchange, AEAD ciphers (AES-GCM or ChaCha20-Poly1305), no static RSA, no compression, extended master secret and secure renegotiation. RFC 9325 and NIST SP 800-52 Rev. 2 both still allow TLS 1.2. TLS 1.3 should be enabled alongside it.
Is TLS 0-RTT safe?
Only for requests that are safe to replay. RFC 8446 says TLS gives no inherent replay protection for early data, and RFC 9325 says applications must avoid 0-RTT unless their protocol defines safe use. For HTTP, RFC 8470 lets a server reject early requests with a 425 Too Early status.
What breaks when I disable TLS 1.0 and 1.1?
Clients that cannot speak TLS 1.2: very old Android and Java versions, unpatched late 2000s Windows, and many embedded devices. Check your access logs for negotiated versions first, then isolate or proxy anything that cannot be upgraded.
Why software supply chain hygiene matters for TLS
Every attack in this history ended with a library upgrade somewhere: OpenSSL for Heartbleed, FREAK, Logjam, DROWN and Raccoon, plus other TLS libraries and appliance firmware for ROBOT. Those libraries do not only live in the operating system: they are vendored into container images, statically linked into binaries and bundled with language runtimes, which is exactly why Heartbleed's patch day turned into weeks of searching.
Safeguard's fit here is the software inventory, not the wire. It scans repositories, container images and SBOM files, matches the TLS library versions it finds against vulnerability data, and shows which projects carry a given component and version, so the "where is the old OpenSSL" question has an answer before an advisory lands. The protocol and configuration checks in this guide are done with openssl s_client, your server configuration and a published profile; Safeguard does not replace them, and it does not rotate keys, issue certificates or change a device's TLS settings. For a TLS library bundled inside a vendor appliance or a hosted service, the fix still has to come from that vendor.
Fix it without waiting for upstream
Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.
3. Gold Registry: start from components that are already fixed
registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | The Gold scan GitHub Action in CI, plus Safeguard policies and gates |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch (early access) |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
See how Safeguard would help
None of these demos test a live TLS endpoint. They show the dependency side of the story: finding and fixing the library versions that sit under your TLS stack.
This is a real Safeguard CLI session: install, open the interactive terminal, ask it to fix a lodash CVE, and approve each command as it edits package.json to lodash 4.17.21 and runs npm install and npm test, with nothing pushed. The same approve every step flow applies when a TLS client library or a crypto dependency in your repository needs a version bump after an advisory.
Click through it at your own pace, or open it full screen.
This demo sets up the Safeguard runner on your own machine, approves it with a device code and runs a scan from the terminal. Pointed at a repository or an image that ships OpenSSL or another TLS library, the same scan reports the component versions it finds and matches them against vulnerability data, which is the inventory step Heartbleed taught everyone to have ready.
Click through it at your own pace, or open it full screen.
Here Claude connects to the Safeguard MCP server with OAuth, and you choose which Safeguard tools Claude may use. That lets you ask in plain language which of your projects carry a given TLS library version, while keeping the assistant limited to the tools you picked.
Click through it at your own pace, or open it full screen.
To try it on your own projects, download Safeguard or read the CLI documentation.
Quick check
Why did DROWN put servers at risk even when they had SSLv2 turned off?
DROWN only needs some server that accepts SSLv2 and uses the same RSA private key. A mail server sharing the website's key was enough. A separate OpenSSL bug, CVE-2015-3197, also let clients negotiate SSLv2 ciphers that a server had disabled.
Which TLS 1.3 change stopped Raccoon, and which stopped ROBOT?
Raccoon was stopped by keeping leading zero bytes in the finite field DH secret (RFC 8446 section 7.4.1). ROBOT was stopped by removing RSA key transport, since every TLS 1.3 key exchange is ephemeral and forward secret. A server that still offers static RSA in TLS 1.2 on the same key keeps some of the ROBOT risk.
Sources
- RFC 7457: Summarizing Known Attacks on TLS and DTLS, RFC Editor
- RFC 7568: Deprecating Secure Sockets Layer Version 3.0, RFC Editor
- RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3, RFC Editor
- RFC 8996: Deprecating TLS 1.0 and TLS 1.1, RFC Editor
- RFC 9325: Recommendations for Secure Use of TLS and DTLS, RFC Editor
- RFC 7525: Recommendations for Secure Use of TLS and DTLS (2015), RFC Editor
- RFC 4346: TLS Protocol Version 1.1, RFC Editor
- RFC 7366: Encrypt-then-MAC for TLS and DTLS, RFC Editor
- RFC 7465: Prohibiting RC4 Cipher Suites, RFC Editor
- RFC 7507: TLS Fallback Signaling Cipher Suite Value, RFC Editor
- RFC 7627: TLS Session Hash and Extended Master Secret Extension, RFC Editor
- RFC 7919: Negotiated Finite Field Diffie-Hellman Ephemeral Parameters for TLS, RFC Editor
- RFC 8470: Using Early Data in HTTP, RFC Editor
- NIST SP 800-52 Rev. 2: Guidelines for the Selection, Configuration, and Use of TLS Implementations, NIST CSRC
- NIST SP 800-52 Rev. 2 PDF, NIST
- Security/Server Side TLS, MozillaWiki
- Server-Side TLS, TLSRef
- TLSRef documentation home
- Server Side TLS guidelines JSON, ssl-config.mozilla.org
- Alert TA14-098A: OpenSSL Heartbleed vulnerability (CVE-2014-0160), CISA
- The Heartbleed Bug, heartbleed.com
- OpenSSL Security Advisory, 7 April 2014
- OpenSSL Security Advisory, 15 October 2014
- OpenSSL Security Advisory, 11 June 2015
- OpenSSL vulnerabilities list, OpenSSL Library
- This POODLE Bites: Exploiting The SSL 3.0 Fallback, Möller, Duong and Kotowicz
- Lucky Thirteen: Breaking the TLS and DTLS Record Protocols, Royal Holloway Information Security Group
- Lessons Learned From Previous SSL/TLS Attacks, Meyer and Schwenk, IACR ePrint 2013/049
- BREACH attack, breachattack.com
- Tracking the FREAK Attack, freakattack.com
- Weak Diffie-Hellman and the Logjam Attack, weakdh.org
- The DROWN Attack, drownattack.com
- The ROBOT Attack, robotattack.org
- Return Of Bleichenbacher's Oracle Threat (ROBOT), IACR ePrint 2017/1189
- Raccoon Attack, raccoon-attack.com
- openssl-s_client, OpenSSL documentation
- SSL_CTX_set_security_level, OpenSSL documentation
- CVE-2011-3389 (BEAST), NVD
- CVE-2012-4929 (CRIME), NVD
- CVE-2013-3587 (BREACH), NVD
- CVE-2014-3566 (POODLE), NVD
- CVE-2014-0160 (Heartbleed), NVD
Last reviewed: 23 October 2026. Recommended TLS profiles change as clients age out; check the TLSRef guidelines, RFC 9325 and your TLS library's release notes for current settings.