In certain applications and libraries using the ServerConfig.PublicKeyCallback callback, there may be a vulnerability that could lead to an authorization bypass. This security issue is caused by the misuse of this callback function and developers need to be cautious while handling it to avoid potential risks. In this long-read post, we will explore the details of the vulnerability, discuss its implications, and provide recommendations to mitigate it.

Background: ServerConfig.PublicKeyCallback

The ServerConfig.PublicKeyCallback is a function in the golang.org/x/crypto/ssh package, designed to handle the authentication of users connecting to an SSH server by providing their public key. The documentation for this callback function states:

"_A call to this function does not guarantee that the key offered is in fact used to authenticate._"

This effectively means that the SSH protocol allows clients to inquire about whether a public key is acceptable before they prove control of the corresponding private key. Furthermore, PublicKeyCallback may be called with multiple keys, and the order of the keys cannot indicate which key the client successfully authenticated with, if any.

The Vulnerability: Authorization Bypass

Some applications and libraries make crucial security determinations based on the outcome of PublicKeyCallback. However, this approach can lead to incorrect assumptions and expose the system to attack.

For instance, an adversary may send public keys A and B to the SSH server, then proceed to authenticate using key A. In this scenario, PublicKeyCallback would only be called twice: first with key A, then with key B. A vulnerable application might then make authorization decisions based on key B, which the attacker does not control the private key for. Consequently, the attacker successfully bypasses the intended authorization mechanism.

As this API is widely misused, golang.org/x/crypto@v.31. has implemented a partial mitigation for this issue. They have enforced that when a client successfully authenticates with a public key, the last key passed to ServerConfig.PublicKeyCallback will be the key used for authentication. However, this callback may still be called multiple times with the same key if necessary.

It is essential to note that if the connection is authenticated through other methods such as PasswordCallback, KeyboardInteractiveCallback, or NoClientAuth, the client might not control the last key passed to PublicKeyCallback.

Mitigation: Using Extensions and Permissions

Developers should utilize the Extensions field of the Permissions return value obtained from various authentication callbacks to record data corresponding to the authentication attempt. By doing so, they refrain from referencing external state that could be manipulated.

Once the connection is established, the state associated with the successful authentication can easily be retrieved using the ServerConn.Permissions field.

However, there is an important consideration for users of third-party libraries: some libraries misuse the Permissions type by sharing it across authentication attempts. In these cases, users should refer to the particular projects for guidance and appropriately handle PublicKeyCallback to ensure security.

Conclusion

The misuse of ServerConfig.PublicKeyCallback can leave applications susceptible to an authorization bypass, allowing adversaries to exploit the vulnerability. Therefore, it is crucial for developers to handle authentication callbacks appropriately, employ the Extensions field of the Permissions return value, and retrieve data corresponding to successful authentication through the ServerConn.Permissions field. Users of third-party libraries should always refer to their respective projects for guidance on secure handling of this callback function.

Timeline

Published on: 12/12/2024 02:02:07 UTC
Last modified on: 12/12/2024 21:15:08 UTC