CVE-2026-45799
Wire: skipGroup() missing negative-length check allows 10-byte payload to crash any Wire-decoding service
Wire provides gRPC and protocol buffers for Android, Kotlin, Swift, and Java. Prior to 6.3.0 and 7.0.0-alpha03, ByteArrayProtoReader32.skipGroup() and ProtoReader.skipGroup() in wire-runtime do not validate that a LENGTH_DELIMITED field length is non-negative before skip(), allowing a crafted protobuf varint encoding -128 as a signed Int to make skip(-128) move the internal position negative and make the next readByte() throw ArrayIndexOutOfBoundsException instead of the documented IOException or ProtocolException, which can crash services using ProtoAdapter.decode(byte[]) on untrusted payloads. This issue is fixed in versions 6.3.0 and 7.0.0-alpha03.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
7.5
Wire: skipGroup() missing negative-length check allows 10-byte payload to crash any Wire-decoding service
Wire provides gRPC and protocol buffers for Android, Kotlin, Swift, and Java. Prior to 6.3.0 and 7.0.0-alpha03, ByteArrayProtoReader32.skipGroup() and ProtoReader.skipGroup() in wire-runtime do not validate that a LENGTH_DELIMITED field length is non-negative before skip(), allowing a crafted protobuf varint encoding -128 as a signed Int to make skip(-128) move the internal position negative and make the next readByte() throw ArrayIndexOutOfBoundsException instead of the documented IOException or ProtocolException, which can crash services using ProtoAdapter.decode(byte[]) on untrusted payloads. This issue is fixed in versions 6.3.0 and 7.0.0-alpha03.
- Record
CVE-2026-45799- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-129
- Updated
- 2026-11-02
EUVDEUVD-2026-45301
7.5
Wire provides gRPC and protocol buffers for Android, Kotlin, Swift, and Java. Prior to 6.3.0 and 7.0.0-alpha03, ByteArrayProtoReader32.skipGroup() and ProtoReader.skipGroup() in wire-runtime do not validate that a LENGTH_DELIMITED field length is non-negative before skip(), allowing a crafted protobuf varint encoding -128 as a signed Int to make skip(-128) move the internal position negative and make the next readByte() throw ArrayIndexOutOfBoundsException instead of the documented IOException or ProtocolException, which can crash services using ProtoAdapter.decode(byte[]) on untrusted payloads. This issue is fixed in versions 6.3.0 and 7.0.0-alpha03.
- Record
EUVD-2026-45301- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-7xpr-hc2w-34m9
7.5
Wire: skipGroup() missing negative-length check allows 10-byte payload to crash any Wire-decoding service
CVE-2026-45799
Maintainer summary
Wire's protobuf group-skipping logic did not reject negative lengths before skipping a
length-delimited field inside a group. A crafted protobuf payload could cause Wire to throw an
unchecked runtime exception during decoding instead of the documented IOException /
ProtocolException failure path.
This can crash services that decode untrusted protobuf payloads and only handle Wire's documented checked decoding failures.
Affected artifacts
com.squareup.wire:wire-runtime
Affected versions: vulnerable releases before 6.3.0.
Patched versions: 6.3.0 and later.
Users should upgrade to com.squareup.wire:wire-runtime:6.3.0 or later.
com.squareup.wire:wire-runtime-jvm
Affected versions: vulnerable releases before 6.3.0.
Patched versions: 6.3.0 and later.
Users should upgrade to com.squareup.wire:wire-runtime:6.3.0 or later.
Wire 7 alpha releases
The fix has been merged to master and will be included in the next Wire 7 alpha release. Until
that release is available, Wire 7 alpha users should avoid decoding untrusted protobuf payloads with
affected alpha versions or build from a commit containing the fix.
Fix
The issue is fixed in Wire 6.3.0.
The fix rejects negative lengths while skipping groups and throws ProtocolException instead of
allowing the reader to move to an invalid position and later throw an unchecked runtime exception.
Credit
Reported by @TrekLaps.
Technical details
The following technical details are based on the original report, updated by the maintainers to
reflect the assigned CVE, the supported fixed artifact, and the discontinued status of
com.squareup.wire:wire-runtime-jvm.
ByteArrayProtoReader32.skipGroup() in wire-runtime did not validate that a
LENGTH_DELIMITED field's length is non-negative before calling skip(). A crafted protobuf
varint encodes -128 as a signed Int. When skip(-128) runs, the internal position counter
underflows to an invalid negative position. The next readByte() accesses the source with that
negative position, throwing ArrayIndexOutOfBoundsException, a RuntimeException that escapes
Wire's documented IOException boundary and can crash the request handler.
ProtoAdapter.decode(byte[]) is declared to throw IOException. Callers following the documented
API may catch only IOException, so unchecked runtime exceptions from malformed input can escape
the expected error boundary.
The originally confirmed vulnerable legacy versions include 5.3.1 and 5.3.3 for the
discontinued com.squareup.wire:wire-runtime-jvm coordinate. The supported replacement coordinate
is com.squareup.wire:wire-runtime, fixed in version 6.3.0.
Root cause
In the originally reported vulnerable code path, ByteArrayProtoReader32.skipGroup() read the
length as a signed Int and used it without validating that it was non-negative:
STATE_LENGTH_DELIMITED -> {
val length = internalReadVarint32() // returns signed Int and can be negative
skip(length) // no negative check
}
The internal skip() implementation then accepted the negative count because the computed
position was not greater than the limit:
private fun skip(byteCount: Int) {
val newPos = pos + byteCount // for example, 7 + (-128) = -121
if (newPos > limit) throw EOFException()
pos = newPos // pos = -121
}
The next read could then index the source with the invalid negative position:
private fun readByte(): Byte {
if (pos == limit) throw EOFException()
return source[pos++] // source[-121] throws ArrayIndexOutOfBoundsException
}
Wire already rejected negative lengths in normal length-delimited field decoding. The same validation was missing from group-skipping code.
The fix adds this validation when skipping groups:
STATE_LENGTH_DELIMITED -> {
val length = internalReadVarint32()
…
- Record
GHSA-7xpr-hc2w-34m9- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-129
- Updated
- 2026-11-02
NVD
7.5
Wire provides gRPC and protocol buffers for Android, Kotlin, Swift, and Java. Prior to 6.3.0 and 7.0.0-alpha03, ByteArrayProtoReader32.skipGroup() and ProtoReader.skipGroup() in wire-runtime do not validate that a LENGTH_DELIMITED field length is non-negative before skip(), allowing a crafted protobuf varint encoding -128 as a signed Int to make skip(-128) move the internal position negative and make the next readByte() throw ArrayIndexOutOfBoundsException instead of the documented IOException or ProtocolException, which can crash services using ProtoAdapter.decode(byte[]) on untrusted payloads. This issue is fixed in versions 6.3.0 and 7.0.0-alpha03.
- Record
CVE-2026-45799- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-129
- Updated
- 2026-11-02
OSV
7.5
Wire: skipGroup() missing negative-length check allows 10-byte payload to crash any Wire-decoding service
Wire provides gRPC and protocol buffers for Android, Kotlin, Swift, and Java. Prior to 6.3.0 and 7.0.0-alpha03, ByteArrayProtoReader32.skipGroup() and ProtoReader.skipGroup() in wire-runtime do not validate that a LENGTH_DELIMITED field length is non-negative before skip(), allowing a crafted protobuf varint encoding -128 as a signed Int to make skip(-128) move the internal position negative and make the next readByte() throw ArrayIndexOutOfBoundsException instead of the documented IOException or ProtocolException, which can crash services using ProtoAdapter.decode(byte[]) on untrusted payloads. This issue is fixed in versions 6.3.0 and 7.0.0-alpha03.
- Record
CVE-2026-45799- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-129
- Updated
- 2026-11-02
OSVGHSA-7xpr-hc2w-34m9
7.5
Wire: skipGroup() missing negative-length check allows 10-byte payload to crash any Wire-decoding service
CVE-2026-45799
Maintainer summary
Wire's protobuf group-skipping logic did not reject negative lengths before skipping a
length-delimited field inside a group. A crafted protobuf payload could cause Wire to throw an
unchecked runtime exception during decoding instead of the documented IOException /
ProtocolException failure path.
This can crash services that decode untrusted protobuf payloads and only handle Wire's documented checked decoding failures.
Affected artifacts
com.squareup.wire:wire-runtime
Affected versions: vulnerable releases before 6.3.0.
Patched versions: 6.3.0 and later.
Users should upgrade to com.squareup.wire:wire-runtime:6.3.0 or later.
com.squareup.wire:wire-runtime-jvm
Affected versions: vulnerable releases before 6.3.0.
Patched versions: 6.3.0 and later.
Users should upgrade to com.squareup.wire:wire-runtime:6.3.0 or later.
Wire 7 alpha releases
The fix has been merged to master and will be included in the next Wire 7 alpha release. Until
that release is available, Wire 7 alpha users should avoid decoding untrusted protobuf payloads with
affected alpha versions or build from a commit containing the fix.
Fix
The issue is fixed in Wire 6.3.0.
The fix rejects negative lengths while skipping groups and throws ProtocolException instead of
allowing the reader to move to an invalid position and later throw an unchecked runtime exception.
Credit
Reported by @TrekLaps.
Technical details
The following technical details are based on the original report, updated by the maintainers to
reflect the assigned CVE, the supported fixed artifact, and the discontinued status of
com.squareup.wire:wire-runtime-jvm.
ByteArrayProtoReader32.skipGroup() in wire-runtime did not validate that a
LENGTH_DELIMITED field's length is non-negative before calling skip(). A crafted protobuf
varint encodes -128 as a signed Int. When skip(-128) runs, the internal position counter
underflows to an invalid negative position. The next readByte() accesses the source with that
negative position, throwing ArrayIndexOutOfBoundsException, a RuntimeException that escapes
Wire's documented IOException boundary and can crash the request handler.
ProtoAdapter.decode(byte[]) is declared to throw IOException. Callers following the documented
API may catch only IOException, so unchecked runtime exceptions from malformed input can escape
the expected error boundary.
The originally confirmed vulnerable legacy versions include 5.3.1 and 5.3.3 for the
discontinued com.squareup.wire:wire-runtime-jvm coordinate. The supported replacement coordinate
is com.squareup.wire:wire-runtime, fixed in version 6.3.0.
Root cause
In the originally reported vulnerable code path, ByteArrayProtoReader32.skipGroup() read the
length as a signed Int and used it without validating that it was non-negative:
STATE_LENGTH_DELIMITED -> {
val length = internalReadVarint32() // returns signed Int and can be negative
skip(length) // no negative check
}
The internal skip() implementation then accepted the negative count because the computed
position was not greater than the limit:
private fun skip(byteCount: Int) {
val newPos = pos + byteCount // for example, 7 + (-128) = -121
if (newPos > limit) throw EOFException()
pos = newPos // pos = -121
}
The next read could then index the source with the invalid negative position:
private fun readByte(): Byte {
if (pos == limit) throw EOFException()
return source[pos++] // source[-121] throws ArrayIndexOutOfBoundsException
}
Wire already rejected negative lengths in normal length-delimited field decoding. The same validation was missing from group-skipping code.
The fix adds this validation when skipping groups:
STATE_LENGTH_DELIMITED -> {
val length = internalReadVarint32()
…
- Record
GHSA-7xpr-hc2w-34m9- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-129
- Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-45799
7.5
Wire provides gRPC and protocol buffers for Android, Kotlin, Swift, and Java. Prior to 6.3.0 and 7.0.0-alpha03, ByteArrayProtoReader32.skipGroup() and ProtoReader.skipGroup() in wire-runtime do not validate that a LENGTH_DELIMITED field length is non-negative before skip(), allowing a crafted protobuf varint encoding -128 as a signed Int to make skip(-128) move the internal position negative and make the next readByte() throw ArrayIndexOutOfBoundsException instead of the documented IOException or ProtocolException, which can crash services using ProtoAdapter.decode(byte[]) on untrusted payloads. This issue is fixed in versions 6.3.0 and 7.0.0-alpha03.
- Record
UBUNTU-CVE-2026-45799- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
com.squareup.wire:wire-runtimeMaven |
through 6.2.0 | 6.3.0 |
com.squareup.wire:wire-runtimeMaven |
7.0.0-alpha01 to 7.0.0-alpha02 | 7.0.0-alpha03 |
com.squareup.wire:wire-runtime-jvmMaven |
through 6.2.0 | 6.3.0 |
com.squareup.wire:wire-runtime-jvmMaven |
7.0.0-alpha01 to 7.0.0-alpha02 | 7.0.0-alpha03 |
com.squareup.wire:wire-runtime-jvmMaven |
before 6.3.0, plus listed versions 3.0.0-alpha034.0.04.0.0-alpha.104.0.0-alpha.114.0.0-alpha.12 Show 45 moreShow less4.0.0-alpha.154.0.0-alpha.164.0.0-alpha.174.0.0-alpha.184.0.0-alpha.194.0.0-alpha.204.0.0-alpha.84.0.0-alpha.94.0.14.1.04.1.14.2.04.3.04.4.04.4.14.4.24.4.34.5.04.5.14.5.24.5.34.5.44.5.54.5.64.6.04.6.14.6.24.7.04.7.14.7.24.8.04.8.14.9.04.9.14.9.114.9.24.9.34.9.44.9.54.9.64.9.74.9.84.9.95.0.05.0.0-alpha01 |
6.3.0 |
com.squareup.wire:wire-runtimeMaven |
before 6.3.0, plus listed versions 1.0.01.0.11.1.01.1.11.2.0 Show 45 moreShow less1.3.01.3.11.3.21.3.31.4.01.5.01.5.11.5.21.6.01.6.11.7.01.8.02.0.02.0.0-BETA12.0.0-BETA102.0.0-BETA22.0.0-BETA32.0.0-BETA42.0.0-BETA52.0.0-BETA62.0.0-BETA72.0.0-BETA82.0.0-BETA92.0.12.0.22.0.32.1.02.1.12.1.22.2.02.3.0-RC13.0.03.0.0-alpha013.0.0-alpha023.0.0-alpha033.0.0-rc013.0.0-rc023.0.0-rc033.0.13.0.23.0.33.1.03.2.03.2.13.2.2 |
6.3.0 |
com.squareup.wire:wire-runtimeMaven |
7.0.0-alpha01 up to 7.0.0-alpha03, plus listed versions 7.0.0-alpha02 |
7.0.0-alpha03 |
com.squareup.wire:wire-runtime-jvmMaven |
7.0.0-alpha01 up to 7.0.0-alpha03, plus listed versions 7.0.0-alpha02 |
7.0.0-alpha03 |
grpcUbuntu:16.04:LTS |
All versions, plus listed versions 0.10.2-10.11.1-1 |
None known |
grpcUbuntu:18.04:LTS |
All versions, plus listed versions 1.3.2-11.3.2-1ubuntu11.3.2-1.1~build1 |
None known |
Show 5 moreShow less
| Package | Affected | Fixed |
|---|---|---|
grpcUbuntu:20.04:LTS |
All versions, plus listed versions 1.16.1-11.16.1-1ubuntu11.16.1-1ubuntu31.16.1-1ubuntu41.16.1-1ubuntu5 |
None known |
grpcUbuntu:22.04:LTS |
All versions, plus listed versions 1.30.2-31.30.2-3build11.30.2-3build31.30.2-3build51.30.2-3build6 |
None known |
grpcUbuntu:24.04:LTS |
All versions, plus listed versions 1.51.1-3build31.51.1-3build41.51.1-41.51.1-4build11.51.1-4build21.51.1-4.1build31.51.1-4.1build41.51.1-4.1build5 |
None known |
grpcUbuntu:26.10 |
All versions, plus listed versions 1.51.1-8ubuntu11.51.1-91.51.1-9ubuntu31.51.1-10ubuntu1 |
None known |
grpcUbuntu:26.04:LTS |
All versions, plus listed versions 1.51.1-6build11.51.1-71.51.1-7ubuntu21.51.1-7ubuntu31.51.1-8ubuntu1 |
None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-45799 is a high vulnerability (CVSS 7.5) in Square Wire, published May 19, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.73%, the 54th percentile. Fixed in com.squareup.wire:wire-runtime 6.3.0.
References
github.com/square/wire/security/advisories/GHSA-7xpr-hc2w-34m9
github.com/square/wire/pull/3595
github.com/square/wire/pull/3597
github.com/square/wire/commit/47d5b0dba53935d5332cd41a80a353b3fc90e7b0
github.com/square/wire/commit/e4e56fab38a547d9625f05c97f1d8f0bcc3a5773
github.com/square/wire/releases/tag/6.3.0
Show 7 moreShow less
Left out here: 118 versions and the rest of 2 source descriptions. The JSON record has them.