GHSA-2mc4-j865-9q4r: Infoleak

Published Aug 20, 2026
·
Updated

Summary

io.netty.incubator:netty-incubator-codec-ohttp-hpke-classes-boringssl exposes raw HPKE private key bytes in string representations and error messages. BoringSSLAsymmetricCipherKeyPair.toString() includes the private-key parameter object, and BoringSSLAsymmetricKeyParameter.toString() renders the full byte array with Arrays.toString(bytes). Separately, failed native key initialization includes Arrays.toString(privateKeyBytes) in the thrown IllegalArgumentException message. Applications that log key-pair objects or exceptions can persist private key material in logs.

Details

codec-ohttp-hpke-classes-boringssl/src/main/java/io/netty/incubator/codec/hpke/boringssl/BoringSSLAsymmetricCipherKeyPair.java renders private key material through toString():

- BoringSSLAsymmetricCipherKeyPair.toString() at lines 72-78 concatenates "privateKey=" + privateKey. - privateKey is a BoringSSLAsymmetricKeyParameter created with isPrivate=true at lines 26-36.

codec-ohttp-hpke-classes-boringssl/src/main/java/io/netty/incubator/codec/hpke/boringssl/BoringSSLAsymmetricKeyParameter.java then renders all bytes:

- BoringSSLAsymmetricKeyParameter.toString() at lines 70-76 returns "bytes=" + Arrays.toString(bytes) regardless of whether isPrivate is true.

A separate error path in codec-ohttp-hpke-classes-boringssl/src/main/java/io/netty/incubator/codec/hpke/boringssl/BoringSSL.java also exposes caller-provided private key bytes:

- EVPHPKEKEYinitorthrow(...) at lines 228-232 throws IllegalArgumentException("privateKeyBytes does not contain a valid private key: " + Arrays.toString(privateKeyBytes)) when BoringSSL rejects the key.

Because Java logging frameworks commonly call toString() for structured objects and commonly persist exception messages, these paths can place complete HPKE private key material in logs or telemetry.

Proof of concept

Safe local verification was performed without native BoringSSL by compiling the relevant Java classes and a no-op native stub for the unused finalizer reference. The observed output includes the full private key byte array:

text BoringSSLAsymmetricCipherKeyPair{privateKey=BoringSSLAsymmetricKeyParameter{bytes=[1, 2, 3, 4], isPrivate=true}, publicKey=BoringSSLAsymmetricKeyParameter{bytes=[5, 6, 7, 8], isPrivate=false}}

Minimal reproducer concept in the same package:

java package io.netty.incubator.codec.hpke.boringssl;

public final class VerifyPrivateKeyToString { public static void main(String[] args) { byte[] privateKey = new byte[] {1, 2, 3, 4}; byte[] publicKey = new byte[] {5, 6, 7, 8}; BoringSSLAsymmetricCipherKeyPair pair = new BoringSSLAsymmetricCipherKeyPair(privateKey, publicKey); System.out.println(pair.toString()); } }

The code path is deterministic: the production toString() methods concatenate the raw private-key byte array.

Impact

If an affected key pair or initialization exception is logged, application logs contain complete HPKE private key material. Anyone with access to those logs can recover the key. Depending on key reuse and log retention, this can compromise:

- confidentiality of OHTTP messages encrypted to the exposed key; - integrity/authenticity expectations for future messages if the key remains active; - incident response and key rotation assumptions, because logs may retain key material long after the in-memory key is rotated.

Suggested remediation

- Redact private key material in BoringSSLAsymmetricKeyParameter.toString() when isPrivate is true, for example bytes=<redacted> or only key type/length. - Redact privateKey in BoringSSLAsymmetricCipherKeyPair.toString(). - Remove Arrays.toString(privateKeyBytes) from BoringSSL.EVPHPKEKEYinitorthrow(...); report only length and KEM metadata. - Add regression tests asserting that toString() and exception messages do not contain private key byte values. - Consider making key pair classes avoid implementing detailed toString() for sensitive material entirely.

References

- codec-ohttp-hpke-classes-boringssl/src/main/java/io/netty/incubator/codec/hpke/boringssl/BoringSSLAsymmetricCipherKeyPair.java:72-78 - codec-ohttp-hpke-classes-boringssl/src/main/java/io/netty/incubator/codec/hpke/boringssl/BoringSSLAsymmetricKeyParameter.java:70-76 - codec-ohttp-hpke-classes-boringssl/src/main/java/io/netty/incubator/codec/hpke/boringssl/BoringSSL.java:228-232

Affected Software

1 affected componentFixes available
maven/io.netty.incubator:netty-incubator-codec-ohttp-hpke-classes-boringssl<=0.0.22.Final
0.0.23.Final

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade maven/io.netty.incubator:netty-incubator-codec-ohttp-hpke-classes-boringssl to a version that resolves this vulnerability.

    Fixed in 0.0.23.Final
  2. Configuration

    In BoringSSLAsymmetricCipherKeyPair.toString() (lines 72-78), stop including the privateKey object in the string via "privateKey=" + privateKey; instead redact so the private key parameter’s private material is not rendered in logs/telemetry.

    codec-ohttp-hpke-classes-boringssl/src/main/java/io/netty/incubator/codec/hpke/boringssl/BoringSSLAsymmetricCipherKeyPair.java toString() redaction of privateKey = Redact privateKey so BoringSSLAsymmetricCipherKeyPair.toString() does not concatenate "privateKey=" + privateKey (i.e., avoid emitting private key material)
  3. Configuration

    In BoringSSLAsymmetricKeyParameter.toString() (lines 70-76), when isPrivate is true, redact private key bytes (e.g., render as "bytes=<redacted>" or only key type/length) instead of returning "bytes=" + Arrays.toString(bytes).

    codec-ohttp-hpke-classes-boringssl/src/main/java/io/netty/incubator/codec/hpke/boringssl/BoringSSLAsymmetricKeyParameter.java toString() handling when isPrivate=true = When isPrivate is true, output only redacted content (e.g., bytes=<redacted> or only key type/length) instead of "bytes=" + Arrays.toString(bytes)
  4. Configuration

    In EVP_HPKE_KEY_init_or_throw(...) (lines 228-232), change IllegalArgumentException("privateKeyBytes does not contain a valid private key: " + Arrays.toString(privateKeyBytes)) to an error message that does not include Arrays.toString(privateKeyBytes); report only the privateKeyBytes length and KEM metadata.

    codec-ohttp-hpke-classes-boringssl/src/main/java/io/netty/incubator/codec/hpke/boringssl/BoringSSL.java IllegalArgumentException message content for invalid privateKeyBytes = Replace "..." + Arrays.toString(privateKeyBytes) with only length and KEM metadata
  5. Configuration

    Add regression tests verifying that (1) BoringSSLAsymmetricCipherKeyPair.toString() does not include privateKey byte values and (2) the EVP_HPKE_KEY_init_or_throw() exception message does not include Arrays.toString(privateKeyBytes) (private key byte values).

    codec-ohttp-hpke-classes-boringssl Regression tests for toString() and exception messages = Add regression tests asserting that toString() and exception messages do not contain private key byte values
  6. Operational

    Rotate/assume exposure if any application logs or exception messages may already contain HPKE private key bytes (because logs and telemetry may retain toString() output and exception messages long after in-memory key rotation).

Event History

Aug 20, 2026
Advisory Published
via GitHub·06:43 PM
Data Sourced
via GitHub·06:43 PM
DescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

Which applications are exposed to private-key disclosure?

Applications using io.netty.incubator:netty-incubator-codec-ohttp-hpke-classes-boringssl are exposed if they log BoringSSL asymmetric key-pair objects or log exceptions from failed native key initialization. Those outputs can contain the complete private-key byte array.

2

Does exploitation require an unauthenticated remote attacker?

The provided information identifies leakage through application string representations and exception messages, not a direct remote extraction path. Exposure depends on private keys reaching logs through key-pair logging or failed native key initialization errors.

3

What can be done before updating?

Avoid logging BoringSSL asymmetric key-pair objects and ensure exception logging does not persist messages from failed native key initialization. Review log storage and access controls because prior logs may already contain private key material.

4

How can I determine whether key material may already have been exposed?

Review application logs for serialized BoringSSL key-pair objects and IllegalArgumentException messages associated with native key initialization. The affected representations include private-key bytes rendered with Arrays.toString(bytes).

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203