Quinn is a pure-Rust, async-compatible implementation of the IETF QUIC transport protocol. As of quinn-proto 0.11, it is possible for a…
GitHub_M·CWE-670·Published 2024-09-02
Quinn is a pure-Rust, async-compatible implementation of the IETF QUIC transport protocol. As of quinn-proto 0.11, it is possible for a server to `accept()`, `retry()`, `refuse()`, or `ignore()` an `Incoming` connection. However, calling `retry()` on an unvalidated connection exposes the server to a likely panic in the following situations: 1. Calling `refuse` or `ignore` on the resulting validated connection, if a duplicate initial packet is received. This issue can go undetected until a server's `refuse()`/`ignore()` code path is exercised, such as to stop a denial of service attack. 2. Accepting when the initial packet for the resulting validated connection fails to decrypt or exhausts connection IDs, if a similar initial packet that successfully decrypts and doesn't exhaust connection IDs is received. This issue can go undetected if clients are well-behaved. The former situation was observed in a real application, while the latter is only theoretical.
Quinn is a pure-Rust, async-compatible implementation of the IETF QUIC transport protocol. As of quinn-proto 0.11, it is possible for a server to `accept()`, `retry()`, `refuse()`, or `ignore()` an `Incoming` connection. However, calling `retry()` on an unvalidated connection exposes the server to a likely panic in the following situations: 1. Calling `refuse` or `ignore` on the resulting validated connection, if a duplicate initial packet is received. This issue can go undetected until a server's `refuse()`/`ignore()` code path is exercised, such as to stop a denial of service attack. 2. Accepting when the initial packet for the resulting validated connection fails to decrypt or exhausts connection IDs, if a similar initial packet that successfully decrypts and doesn't exhaust connection IDs is received. This issue can go undetected if clients are well-behaved. The former situation was observed in a real application, while the latter is only theoretical.
In 0.11.0, we overhauled the server-side `Endpoint` implementation to enable more careful handling of incoming connection attempts. However, some of the code paths that cleaned up state after connection attempts were processed confused the initial destination connection ID with the destination connection ID of a substantial package. This resulted in the internal `Endpoint` state becoming inconsistent, which could then lead to a panic. https://github.com/quinn-rs/quinn/commit/e01609ccd8738bd438d86fa7185a0f85598cb58f Thanks to [@finbear](https://github.com/finnbear) for reporting and investingating, and to [@BiagoFesta](https://github.com/BiagoFesta) for coordinating.
### Summary As of quinn-proto 0.11, it is possible for a server to `accept()`, `retry()`, `refuse()`, or `ignore()` an `Incoming` connection. However, calling `retry()` on an unvalidated connection exposes the server to a likely panic in the following situations: - Calling `refuse` or `ignore` on the resulting validated connection, if a duplicate initial packet is received - This issue can go undetected until a server's `refuse()`/`ignore()` code path is exercised, such as to stop a denial of service attack. - Accepting when the initial packet for the resulting validated connection fails to decrypt or exhausts connection IDs, if a similar initial packet that successfully decrypts and doesn't exhaust connection IDs is received. - This issue can go undetected if clients are well-behaved. The former situation was observed in a real application, while the latter is only theoretical. ### Details Location of panic: https://github.com/quinn-rs/quinn/blob/bb02a12a8435a7732a1d762783eeacbb7e50418e/quinn-proto/src/endpoint.rs#L213 ### Impact Denial of service for internet-facing server
Quinn es una implementación compatible con async y puramente Rust del protocolo de transporte IETF QUIC. A partir del protocolo quinn 0.11, es posible que un servidor `accept()`, `retry()`, `refuse()` o `ignore()` una conexión `Incoming`. Sin embargo, llamar a `retry()` en una conexión no validada expone al servidor a un posible pánico en las siguientes situaciones: 1. Llamar a `refuse` o `ignore` en la conexión validada resultante, si se recibe un paquete inicial duplicado. Este problema puede pasar desapercibido hasta que se ejerza la ruta de código `refuse()`/`ignore()` de un servidor, como para detener un ataque de denegación de servicio. 2. Aceptar cuando el paquete inicial para la conexión validada resultante no logra descifrar o agota los ID de conexión, si se recibe un paquete inicial similar que descifra con éxito y no agota los ID de conexión. Este problema puede pasar desapercibido si los clientes se comportan bien. La primera situación se observó en una aplicación real, mientras que la segunda es sólo teórica.
| Version | Type | Source | Base | Exp | Impact | Vector |
|---|---|---|---|---|---|---|
| 3.1 | Primary | cve.org | 7.5 | — | — | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H |
| 3.1 | Primary | cve.org | 7.5 | — | — | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H |
| 3.1 | Primary | NVD | 7.5 | 3.9 | 3.6 | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H |
| 3.1 | Secondary | GHSA | 7.5 | — | — | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H |
| 3.1 | Secondary | NVD | 7.5 | 3.9 | 3.6 | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H |
| 4.0 | Secondary | GHSA | 8.7 | — | — | CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N |