Skip to main content
Vulnerability Database/CVE-2026-61695

CVE-2026-61695: Wire Swift Runtime DOS Vulnerability

CVE-2026-61695 is a denial of service flaw in Wire's Swift runtime that allows attackers to crash processes decoding untrusted protobuf bytes. This post explains its technical details, affected versions, and mitigation steps.

Published:

CVE-2026-61695 Overview

CVE-2026-61695 is a denial-of-service vulnerability in Square's Wire library, which provides gRPC and protocol buffers for Android, Kotlin, Swift, and Java. The Swift runtime's ProtoReader.skipGroup(expectedEndTag:unknownFieldsWriter:) accepts a negative length for a LENGTH_DELIMITED field nested inside an unknown START_GROUP field. The negative count reaches Foundation Data(bytes:count:), triggering an unrecoverable process trap rather than a catchable ProtoDecoder.Error. Any Swift process that decodes untrusted protobuf bytes can be crashed without authentication, user interaction, or knowledge of the target schema.

Critical Impact

Unauthenticated remote attackers can crash any Swift application decoding protobuf data by sending a single crafted message, resulting in service disruption.

Affected Products

  • Square Wire Swift runtime versions prior to 6.4.1
  • Square Wire Swift runtime 7.0.0-alpha through 7.0.0-alpha03
  • Swift applications and services using Wire to decode untrusted protobuf input

Discovery Timeline

  • 2026-09-23 - CVE-2026-61695 published to the National Vulnerability Database (NVD)
  • 2026-09-23 - Last updated in NVD database

Technical Details for CVE-2026-61695

Vulnerability Analysis

The flaw is an improper validation of an array index [CWE-129] in the Wire Swift runtime. When ProtoReader.skipGroup encounters an unknown START_GROUP field containing a LENGTH_DELIMITED sub-field, the length varint is truncated to Int32 and then widened to Int without validating that the value is non-negative. That negative length propagates through ProtoReader.readData() to ReadBuffer.readData(count:).

ReadBuffer performs only an upper-bound check comparing the advanced pointer against end. A negative count still satisfies the comparison, so the negative value is passed to Foundation's Data(bytes:count:). The Foundation initializer treats the count as an unsigned quantity and terminates the process with an unrecoverable trap. Because the trap occurs below the Swift error-handling layer, it cannot be caught with try or do/catch.

Root Cause

The root cause is a missing signed-integer validation in two Swift files: ProtoReader.swift and ReadBuffer.swift. Neither the varint decoder nor the buffer bounds check rejected negative lengths before they reached memory-copy primitives.

Attack Vector

An attacker sends a crafted protobuf payload containing an unknown group with a length-delimited inner field whose varint decodes to a negative Int32. Any network-reachable Swift service accepting protobuf input, including gRPC endpoints, is vulnerable without authentication.

text
// Patched call site in ProtoReader.swift
                throw ProtoDecoder.Error.unexpectedEndGroupFieldNumber(expected: nil, found: tag)

            case .lengthDelimited:
-                let length = try Int32(truncatingIfNeeded: buffer.readVarint())
-                state = .lengthDelimited(length: Int(length))
+                state = .lengthDelimited(length: try readLengthDelimitedLength(tag: tag))
                currentTag = tag
                return tag

Source: GitHub Commit 24043b6

text
// Patched bounds check in ReadBuffer.swift
    func verifyAdditional(count: Int) throws {
-        guard pointer.advanced(by: count) <= end else {
+        guard count >= 0, pointer.advanced(by: count) <= end else {
            throw ProtoDecoder.Error.unexpectedEndOfData
        }
    }

Source: GitHub Commit 81ff7f2

Detection Methods for CVE-2026-61695

Indicators of Compromise

  • Unexpected Swift process crashes with Foundation Data trap signatures in crash reports or os_log output.
  • Repeated abnormal terminations of gRPC or protobuf-handling services immediately after receiving inbound messages.
  • Inbound protobuf payloads containing START_GROUP wire type (tag & 0x07 == 3) with nested negative-varint length fields.

Detection Strategies

  • Inventory Swift Package Manager and CocoaPods manifests for Wire dependencies at versions below 6.4.1 or 7.0.0-alpha04.
  • Deploy protobuf-aware network inspection that flags LENGTH_DELIMITED fields whose decoded varint exceeds Int32.max or has the sign bit set after Int32 truncation.
  • Correlate process-restart telemetry from service supervisors with request logs to identify crash-inducing peers.

Monitoring Recommendations

  • Ship crash reports and service supervisor restart events into a centralized log platform for aggregation.
  • Alert on repeated crashes from the same source IP or client identity within short time windows.
  • Track Wire runtime versions across build pipelines and enforce version-floor policies in CI.

How to Mitigate CVE-2026-61695

Immediate Actions Required

  • Upgrade Wire Swift runtime to 6.4.1 on the stable branch or 7.0.0-alpha04 on the pre-release branch.
  • Audit all Swift services that decode protobuf input from untrusted sources, including gRPC servers, mobile clients, and message consumers.
  • Rebuild and redeploy affected iOS, macOS, and server-side Swift applications after dependency upgrade.

Patch Information

Square released fixes in Wire 6.4.1 and Wire 7.0.0-alpha04. The changes are described in GitHub Security Advisory GHSA-86wm-r4c5-2rc9 and merged via Pull Request #3616. The patch adds a count >= 0 guard in ReadBuffer.verifyAdditional and centralizes length parsing through a new readLengthDelimitedLength helper.

Workarounds

  • Terminate protobuf input at a non-Swift reverse proxy or gateway that validates message structure before forwarding.
  • Restrict protobuf endpoints to authenticated clients until the Wire runtime is upgraded.
  • Wrap protobuf decode calls in isolated worker processes so a crash does not terminate the parent service.
bash
# Update Wire dependency via Swift Package Manager
# In Package.swift, pin the minimum Wire version to the patched release:
.package(url: "https://github.com/square/wire.git", from: "6.4.1")

# Then resolve and rebuild:
swift package update
swift build

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.