-
Notifications
You must be signed in to change notification settings - Fork 229
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
crypto/tls: reject change_cipher_spec record after handshake in TLS 1.3 #170
Conversation
该补丁对 uTLS 的特殊意义:uTLS 模仿的指纹大多使用 BoringSSL,或其它对 TLSv1.3 的正确实现,它们没有 Golang TLS 的这个问题。比如,中间人怀疑某个 Chrome TLSv1.3 连接实际上是 uTLS,插入 CCS 包后未触发 alert,则可以确定它为 uTLS。 该行为对已经建立的 TLSv1.3 连接可能是破坏性的,中间人不一定会这样操作,但需要防患于未然。
|
A nice catch @RPRX! I agree this would allow an attacker distinguish I wonder would it be easy to verify the alleged behavior that Real world TLS 1.3 implementation sends alert after seeing |
Btw I am assuming |
我使用 golang/go#58912 中的方法,即在每个真正的 application_data record 前插入 change_cipher_spec record,并作为服务端:
为了测试这些浏览器有无发送 alert,我在服务端 func
(对于握手完毕的 TLSv1.3 连接,消息外观均为 application_data record,所以我们发 I use the method in golang/go#58912, where I insert the change_cipher_spec record in front of each real application_data record, and as a server side. No connection exceptions when using the Go crypto/tls library or uTLS library with no bug fixes as a client. When using the latest Chrome and Edge as clients, the server receives alertLevelError and alertBadRecordMAC (after decryption). Translated with DeepL (https://www.deepl.com/app/?utm_source=ios&utm_medium=app&utm_campaign=share-translation |
RFC 8446 写的是 CCS 可以在握手过程中出现(特例),也就是说除此之外应走常规流程,即所有消息均加密、接收方先解密。 OpenSSL/BoringSSL 的做法和 Go crypto/tls 的现有注释也体现了这些,所以它其实是 Go crypto/tls 的一个 bug,应当被修复。 RFC 8446 states that the CCS can occur during the handshake (a special case), meaning that otherwise the normal process should be followed, i.e. all messages are encrypted and decrypted by the receiver first. This is reflected in the OpenSSL/BoringSSL approach and in the existing comments for Go crypto/tls, so it is actually a bug in Go crypto/tls that should be fixed. Translated with DeepL (https://www.deepl.com/app/?utm_source=ios&utm_medium=app&utm_campaign=share-translation |
Sounds like you were saying that "RFC implies ...". But if this restriction is not described using "MUST/SHOULD [NOT]", it is considered undefined. E.g., the behavior when the package received NOT having a TLS header is not defined by RFC even though everyone know it is considered as an "illegal behavior". Therefore the handling routines vary by a good amount. |
这是个好问题,我发现 RFC 8446, Section 5 对这种情况有强制规定: If an implementation detects a change_cipher_spec record received before the first ClientHello message or after the peer's Finished message, it MUST be treated as an unexpected record type ... If a TLS implementation receives an unexpected record type, it MUST terminate the connection with an "unexpected_message" alert. 并且 RFC 8446, Appendix E.2 写道: Confidentiality: An attacker should not be able to determine the plaintext contents of a given record. 所以该 bug 是一个切实的安全漏洞,攻击者可以通过插 16 个 CCS 包的方式来探测特定 application_data record 是否实际为空。 This is a good question, and I found RFC 8446, Section 5 to be mandatory for this case. If an implementation detects a change_cipher_spec record received before the first ClientHello message or after the peer's Finished message, it MUST be treated as an unexpected record type ... If a TLS implementation receives an unexpected record type, it MUST terminate the connection with an "unexpected_message" alert. And RFC 8446, Appendix E.2 reads. Confidentiality: An attacker should not be able to determine the plaintext contents of a given record. So the bug is a real security vulnerability that allows an attacker to detect whether a specific application_data record is actually empty by inserting 16 CCS packets. |
Good find. Perhaps also append the related section to your PR for golang/go. I don't think they would care though. I had an impression that golang/go doesn't accept community contributions. Actually such finding could be considered a CVE and I would encourage you to submit it. |
I was about to publish a security advisory but only to find myself not being an admin of this repo 😓. |
golang/go#58912