# OpenSSL Advisory: June 27th, 2024

OpenSSL have published a [security advisory](https://openssl-library.org/news/secadv/20240627.txt). Here's how it affects BoringSSL:

CVE | Summary | [Severity] in OpenSSL | Impact to BoringSSL
----|---------|-----------------------|---------------------
CVE-2024-5535 | SSL_select_next_proto buffer overread | Low | See discussion below. Fixed in [c1d9ac02](https://boringssl.googlesource.com/boringssl/+/c1d9ac02514a138129872a036e3f8a1074dcb8bd).

[Severity]: https://openssl-library.org/policies/general/security-policy/index.html#issue-severity

## CVE-2024-5535

This issue concerns fragile and, in OpenSSL, underdocumented, preconditions in the NPN and ALPN helper function, `SSL_select_next_proto`. If called with invalid inputs, notably an empty final argument, the function may crash or return an out-of-bounds buffer to the caller. This was fixed in BoringSSL on June 5, 2024 in commit [c1d9ac02514a138129872a036e3f8a1074dcb8bd](https://boringssl.googlesource.com/boringssl/+/c1d9ac02514a138129872a036e3f8a1074dcb8bd).

Typical uses of `SSL_select_next_proto` are not affected. Applications are affected if they pass in an invalid `peer` or `supported` parameter. That is, either:

* `peer` and `supported` was not a valid encoded NPN/ALPN protocol list.
* `supported` was empty

We are not aware of any instance of the first condition, but older versions of some applications met the second condition. In this case, the application may crash or, if it outputs the “opportunistic” protocol (see below) when the function returns `OPENSSL_NPN_NO_OVERLAP`, may leak private data. Outputting this protocol is common for NPN but rare for its successor, ALPN.

### Background and details

`SSL_select_next_proto` is a helper function for implementing protocol selection. It was originally added for NPN, and then reused for its successor, ALPN. It is expected to be used in the application’s protocol selection callbacks, set by `SSL_CTX_set_next_proto_select_cb` and SSL_CTX_set_alpn_select_cb, respectively.  The function takes two protocol preference lists, peer and supported, each encoded as a byte string, and selects a protocol out of the intersection. If there is no intersection, it returns a special `OPENSSL_NPN_NO_OVERLAP` value and then returns the first protocol in supported as an NPN [“opportunistic”](https://datatracker.ietf.org/doc/html/draft-agl-tls-nextprotoneg-03#section-6) protocol. It is not expected to be returned in ALPN, where a protocol mismatch should terminate the connection. But, as these are arbitrary callbacks, callers may implement arbitrary selection policies.

(In OpenSSL, the parameters are named `server` and `client`, after the original NPN semantics. We use different names in BoringSSL to reflect NPN and ALPN’s reversed roles. In NPN, the client picks a protocol based on the server list. In ALPN, the server picks a protocol based on the client list. This ensures the “opportunistic” protocol is picked out of the calling application’s supported list.)

This function has two preconditions which the caller must satisfy:

1. `peer` and `supported` must both be valid encoding of NPN/ALPN protocol lists.
2. `supported` must not be empty; the function otherwise cannot return an opportunistic protocol. (Callers that support no protocols are not enabling NPN/ALPN at all, and thus do not need this function.)

In the original implementation, these preconditions were unchecked, with memory errors when violated. In particular, if `supported` is empty (the second precondition), the opportunistic protocol may point to an out-of-bounds buffer. Outputting that opportunistic protocol, common in NPN, may then leak sensitive information.

BoringSSL documented both preconditions, but OpenSSL did not document that `supported` must not be empty. We are aware of some older versions of calling applications which could both violate this second precondition and also output the opportunistic protocol. Those applications may then leak private data in some cases.

The fix removes this fragility. While callers are still expected to heed the preconditions for `SSL_select_next_proto` to function properly, a violation will only cause it to cleanly return `OPENSSL_NPN_NO_OVERLAP` and an empty opportunistic protocol.
