fix(net): avoid panics on malformed encryption/velocity login responses (#2310)

`handle_encryption_response` unwrapped the RSA decrypt of the
client-supplied shared secret, panicking the connection task on a
malformed value; kick the client instead, mirroring the adjacent
`set_encryption` error handling.

`receive_velocity_plugin_response` called `data.split_at(32)` without a
length check, panicking on a velocity response shorter than 32 bytes;
guard the length and return `FailedVerifyIntegrity`.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
dongzh1
2026-07-12 00:34:24 +08:00
committed by GitHub
parent f13736def9
commit 5c1558788a
2 changed files with 8 additions and 4 deletions

View File

@@ -114,10 +114,11 @@ impl JavaClient {
encryption_response: SEncryptionResponse,
) {
debug!("Handling encryption");
let shared_secret = server
.decrypt(&encryption_response.shared_secret)
.await
.unwrap();
let Ok(shared_secret) = server.decrypt(&encryption_response.shared_secret).await else {
self.kick(TextComponent::text("Failed to decrypt shared secret"))
.await;
return;
};
if let Err(error) = self.set_encryption(&shared_secret).await {
self.kick(TextComponent::text(error.to_string())).await;

View File

@@ -112,6 +112,9 @@ pub fn receive_velocity_plugin_response(
) -> Result<(GameProfile, SocketAddr), VelocityError> {
debug!("Received velocity response");
if let Some(data) = response.data {
if data.len() < 32 {
return Err(VelocityError::FailedVerifyIntegrity);
}
let (signature, mut data_without_signature) = data.split_at(32);
if !check_integrity((signature, data_without_signature), &config.secret) {