Safeguard
Supply Chain Security•

Apache bRPC 1.18.0: 35 CVEs Led by Auth Bypass CVE-2026-48830

Apache bRPC disclosed 35 CVEs on 21 Oct 2026, led by keep-alive auth bypass CVE-2026-48830. All hit 1.17.0 and older; upgrade to 1.18.0. No attacks known.

Safeguard Security Team
35 min read

On 21 October 2026 Apache bRPC disclosed 35 vulnerabilities, 16 rated high and 19 moderate, all fixed in bRPC 1.18.0. The headline issue, CVE-2026-48830, lets an authentication decision leak across requests on one HTTP keep-alive connection. Every version through 1.17.0 is affected. Upgrade to 1.18.0 or apply the listed patches. No exploitation is reported.

This is a vulnerability disclosure, not a breach. As of the CISA Known Exploited Vulnerabilities catalog release of 23 October 2026 (version 2026.10.23), no bRPC CVE is listed. NVD had placed CVE-2026-48830 in "Deferred" status with no score of its own, and CISA's vulnerability enrichment for three of the 35 records says "Exploitation: none". We found no public proof of concept, and we are not going to describe one.

Two things make this batch matter. The fix for the headline bug was merged on 25 May 2026 and shipped in 1.18.0 on 17 September, five weeks before the CVEs went public on 21 October. And bRPC is a C++ library usually compiled in from source, so the lockfile based scanning most teams rely on often cannot see it.

What happened

Weibing Wang, a member of the bRPC project management committee, sent a single advisory covering all 35 issues to the oss-security list at 10:58 China Standard Time on 21 October (02:58 UTC), and to the Apache announce@apache.org list two minutes later. The subject line of both was "Apache bRPC security advisory: 35 vulnerabilities fixed in 1.18.0". The Apache Software Foundation, as the CVE Numbering Authority, published the 35 CVE records between 11:30 and 12:19 UTC the same day.

bRPC started life inside Baidu and became an Apache top level project. It is an embeddable RPC framework: applications link libbrpc and run brpc::Server in their own process, and one port can speak many protocols at once, chosen by sniffing the first bytes of each connection. The project's threat model lists baidu_std, HTTP/1.x, HTTP/2 and gRPC, Thrift, Redis, memcached, RTMP, Mongo and the nshead family among them, plus a set of HTTP "builtin services" such as /status, /vars, /flags, /connections, /rpcz and /health for operators.

That design explains the advisory: most of the 35 bugs sit in parsers that run before authentication, and several sit in the logic deciding which protocols and builtin services a port may reach.

The advisory at a glance

MeasureValueSource
CVEs35Apache advisory
Rated high16Apache advisory
Rated moderate or medium19Apache advisory
Affected"through 1.17.0" for 34 CVEs; 1.11.0 through 1.17.0 for CVE-2026-79704Apache advisory
Fixed1.18.0, or the per CVE pull requestApache advisory
CVSS from the projectNone; Apache publishes word ratings onlyApache advisory
CVSS from CISA enrichment7.5 for CVE-2026-56386 and CVE-2026-82230; 5.4 for CVE-2026-84727CVE records, CISA ADP container
Known exploitationNone reported; not in KEV 2026.10.23CISA KEV, CVE records

Timeline

All times are UTC unless stated.

Date and timeEventSource
20 May 2026bRPC PMC confirms the scope for a threat model drafted by the ASF Security TeambRPC THREAT_MODEL.md
24 May 2026, 07:41CVE-2026-48830 reserved by ApacheCVE record
24 May 2026, 08:45Pull request 3308, "apply auth check to builtin requests on public port", openedGitHub PR 3308
25 May 2026PR 3308 merged into master as merge commit a47e349GitHub PR 3308
28 May 2026, 14:21bRPC 1.17.0 released; the advisory lists it as affectedGitHub releases
14 Jun to 12 Sep 2026The other 34 CVE IDs reserved in batchesCVE records
17 Sep 2026, 15:53:36bRPC 1.18.0 published on GitHub with all fixesGitHub release 1.18.0
21 Oct 2026, 02:58:40Advisory posted to oss-security (10:58:40 +0800)openwall.com
21 Oct 2026, 03:00:16Same advisory to announce@apache.orglists.apache.org
21 Oct 2026, 11:30 to 12:1935 CVE records publishedcve.org
21 Oct 2026, 12:17NVD receives CVE-2026-48830, status later shown as DeferredNVD API
21 Oct 2026, 13:07 to 15:11CISA enrichment added to three records, each "Exploitation: none"CVE records
23 Oct 2026, 19:30CISA KEV catalog 2026.10.23 released; no bRPC entriesCISA KEV feed

Holding CVE publication until a release has spread is normal practice. The point for defenders is that the fixed code sat in a tagged release for 34 days before anyone outside the project was told it mattered.

Who is affected

You are affected if you build or ship anything that links bRPC 1.17.0 or earlier. Whether a specific CVE is reachable depends on which bRPC features your service turns on. The table maps features to the CVEs that need them.

If your serviceCVEs that apply
Sets ServerOptions.auth and leaves builtin services on the public portCVE-2026-48830 (high)
Sets both ServerOptions.auth and ServerOptions.internal_portCVE-2026-86249
Sets internal_port and enables any protobuf protocol on the public portCVE-2026-84748
Sits behind a proxy that enforces path ACLsCVE-2026-84747, CVE-2026-86146
Exposes builtin services (/flags, /pprof) to untrusted networksCVE-2026-86147
Serves streaming RPC with an AuthenticatorCVE-2026-78334, plus 80463, 81755, 82210
Accepts HTTP/2 or gRPC (the h2 parser is on by default)CVE-2026-54425, 56386, 78048, 78058 (all high), 61902
Runs a Redis protocol serverCVE-2026-56388, 58064 (high)
Runs RTMPCVE-2026-54427, 56387, 74758, 82953 (high), 84727
Uses the nshead, ubrpc or mcpack2pb pathsCVE-2026-74757, 82230 (high), 74755
Accepts compressed bodies, sofa-pbrpc, RTMP or mcpack2pbCVE-2026-78066 (high)
Runs on ARM64 or another platform where plain char is unsignedCVE-2026-61916
Uses bRPC as a client of Redis, Thrift, MySQL, Discovery or multi-stream serversCVE-2026-54426, 82231 (high), 90484, 87849, 79704
Uses client TLS and relies on certificate verificationCVE-2026-66392
Uses client health checksCVE-2026-82425
Is built with RDMACVE-2026-82942

Services with authentication enabled should pay the most attention: several of these CVEs show ways the Authenticator could be bypassed. Services that only act as clients are also in scope.

Where bRPC hides

bRPC is usually fetched as a source tarball, added as a CMake or Bazel dependency, or vendored. Places to look:

  • Your own C++ services. Anything that includes brpc/server.h or brpc/channel.h.
  • Databases and analytics engines that vendor it. On 24 October the master branch build scripts of Apache Doris and StarRocks referenced bRPC 1.4.0 and 1.9.0. Either may patch or disable the affected features, and neither had published a statement we could find. Check them; do not assume exposure.
  • Package managers for C++. The vcpkg brpc port reads 1.18.0, but a pinned baseline will not pick it up.
  • Container images. A static libbrpc.a leaves no dpkg or rpm entry for image scanners to read.

Customised forks, which the project's case list shows are common, get no upstream release; someone has to port the patches.

How the issues work

This section explains the root causes at the level a defender needs to judge exposure. It does not give request sequences, and you do not need them to decide whether to patch.

CVE-2026-48830: an authentication decision that stuck to the connection

bRPC's Authenticator runs once per connection, on the first message, not on every request. The project documents this. Its threat model lists "Authenticator::VerifyCredential runs once per connection, not once per request" as a false friend property, and names treating it as per request authentication as a common misuse.

Separately, builtin services were handled differently from business endpoints when they arrived on the public listener. According to the advisory, if a builtin HTTP request was the first message on a socket, the connection could be marked as authenticated, and later requests on the same HTTP/1.1 keep-alive connection to protected, non-builtin endpoints were then served without the credential check. The conditions are both of these:

  1. ServerOptions.auth is set, so the operator intended authentication.
  2. Builtin HTTP services are reachable on the public listener, which is the default unless internal_port is set or has_builtin_services is false.

The fix in PR 3308 makes builtin HTTP requests arriving on the public port go through the same authentication as everything else. The pull request flags this as a breaking change: if you relied on unauthenticated access to /status or /vars on the public port of an authenticated server, that access now fails. Builtin requests on internal_port still skip authentication by design, which is why the next two CVEs mattered.

The finder is credited as Brubbish of VARAS@IIE.

CVE-2026-86249 and CVE-2026-84748: when internal_port was not the boundary it looked like

The documented way to keep builtin services away from the internet is to set ServerOptions.internal_port to a port only internal hosts can reach. Two CVEs show that, before 1.18.0, this was not a complete boundary.

  • CVE-2026-86249 affects servers that set both auth and internal_port. Builtin requests on the internal port are exempt from authentication by design, but ordinary services were also served there. Because the verdict latches per connection, the same carry over effect as CVE-2026-48830 applied on the internal port: an unauthenticated connection could end up reaching ordinary authenticated services. The fix restricts internal_port so it carries only builtin and Tabbed services and rejects ordinary services with HTTP 403. If you sent business traffic to the internal port, you must move it to the port passed to Server::Start().
  • CVE-2026-84748 is about protocols other than HTTP. The HTTP and h2 paths enforced the internal port rule, but the protobuf based protocols (baidu_std, hulu_pbrpc, sofa_pbrpc, and the nshead family such as public_pbrpc, nshead_mcpack, nova_pbrpc and ubrpc2pb) computed a security mode flag and never enforced it. Builtin services share the method map with user services, so a client on the public port could call builtin services such as brpc.vars or hotspots by name, disclosing metrics, flags and profiler data.

The practical lesson is that, on 1.17.0 and earlier, setting internal_port was necessary but not sufficient. A firewall rule that keeps the internal port off untrusted networks, and a separate check that the public port cannot reach builtin services over any protocol, were both needed.

Other access control and trust bugs

  • CVE-2026-84747, empty path segments. The HTTP dispatcher collapsed consecutive slashes, so a proxy that blocks builtin paths by exact match could be walked around, and HTTP/2 :path values were not validated. Such paths are now rejected unless -http_allow_empty_path_segments is set, which the advisory advises against on exposed servers.
  • CVE-2026-86146, HTTP/1.1 parsing differences. bRPC accepted header forms a strict proxy rejects or reads differently, including spaces around framing values, obsolete line folding and chunked trailers merged into the header map. Behind a proxy this allows request smuggling and smuggled Authorization or X-Forwarded-For headers. The fix rejects those forms and drops trailers; http_allow_obs_fold and http_strict_header_token adjust the behaviour.
  • CVE-2026-86147, /flags and /pprof. Where builtin services are reachable, /flags could change the dump path gflags (bvar_dump_file, bvar_dump_tabs, mbvar_dump_file) so the process created directories and truncated files with its own privileges, and /pprof had no duration cap. Those flags are now frozen at runtime and /pprof is capped by -max_profiling_seconds (default 300). This is why the bRPC docs say never to run it as root.
  • CVE-2026-78334, streaming frames. Streaming RPC frames bypassed the authentication hook, and a stream could accept frames from a different socket carrying its ID. Both are now rejected.
  • CVE-2026-66392, TLS peer names. The client checked the certificate chain but not the name, so any certificate from a trusted CA could impersonate the server. After upgrading, enable VERIFY_PEER with a positive verify_depth, and set VerifyOptions::expected_peer_name where the name differs from the URL host. verify_depth=0 means verification is off.

The parser cluster: crashes before authentication

Most of the remaining CVEs are parser bugs that a remote peer can reach before any application code runs. The threat model says the h2 parser "runs before any Authenticator check on the shared port", and the Redis, RTMP and mcpack paths behave the same way.

  • Memory corruption. CVE-2026-56388 is an out of bounds write in the Redis command parser, guarded only by a CHECK that does not abort in every build. CVE-2026-74758 and CVE-2026-84727 are use after free bugs triggered by RTMP Abort messages.
  • Out of bounds reads. CVE-2026-56386 is an underflow in the HTTP/2 DATA handler for a zero length padded frame. CVE-2026-61916 hits only platforms where plain char is unsigned, such as ARM64; typical x86_64 builds are not affected.
  • Recursion and assertions. CVE-2026-54425, 54426, 54427 and 82230 let nesting exhaust the stack; the fixes add iterative parsing or a depth limit of 128. CVE-2026-78048 is an HPACK table sized for a 34 byte minimum entry where RFC 7541 allows 33, so a full table hits a CHECK.
  • Resource exhaustion. CVE-2026-78058 covers missing HTTP/2 limits on streams, decoded header size and control frame acknowledgements. CVE-2026-78066 covers uncapped decompression and trusted length fields in several protocols.

Eight CVEs are client side: a malicious server, or anyone on the network path, can crash or mislead a bRPC client through Redis, Thrift, MySQL, Discovery or multi stream replies, the TLS name check, health checks or the h2 client limits. Services that only call other services still need the upgrade.

Technical details

All values below come from the Apache advisory as posted to oss-security and the Apache announce list, the CVE records on cve.org, and the bRPC 1.18.0 release notes.

All 35 CVEs: severity, weakness, affected and fixed versions, patch

Every row is fixed in 1.18.0. "Affected" is the advisory's range; "PR" is the patch the advisory names for teams that cannot take the full release.

CVEApache ratingTitle (shortened)CWEAffectedPR
CVE-2026-48830HighBuiltin HTTP request can mark a connection authenticatedCWE-287through 1.17.03308
CVE-2026-54425HighStack exhaustion via recursive HPACK table size updatesCWE-674through 1.17.03343
CVE-2026-54426HighStack exhaustion in Redis reply parser (client)CWE-674through 1.17.03344
CVE-2026-54427HighStack exhaustion in AMF parser (RTMP)CWE-674through 1.17.03344
CVE-2026-56386HighInteger underflow and OOB read in HTTP/2 DATA parserCWE-191, CWE-125through 1.17.03325
CVE-2026-56387HighMemory exhaustion in RTMP AMF parserCWE-789, CWE-770through 1.17.03353
CVE-2026-56388HighOut of bounds write in Redis command parserCWE-787, CWE-617, CWE-252through 1.17.03354
CVE-2026-58064HighUnbounded Redis inline command allocationCWE-770through 1.17.03363
CVE-2026-61902MediumInconsistent message body limitsCWE-400through 1.17.03382
CVE-2026-61916ModerateOOB read in lookup tables on unsigned char platformsCWE-125through 1.17.03376
CVE-2026-66392MediumTLS client accepts certificates for mismatched namesCWE-297through 1.17.03408
CVE-2026-74755ModerateInteger underflow in mcpack2pb parserCWE-191through 1.17.03450
CVE-2026-74757HighUncontrolled allocation via mcpack array item countCWE-770through 1.17.03451
CVE-2026-74758HighHeap use after free in RTMP Abort handlingCWE-416through 1.17.03452
CVE-2026-78048HighHPACK dynamic table sizing assertionCWE-617through 1.17.03462
CVE-2026-78058HighUnbounded resources and crash in HTTP/2 receive pathCWE-400, CWE-476through 1.17.03474
CVE-2026-78066HighUnbounded decompression and wire declared sizesCWE-770through 1.17.03476
CVE-2026-78334MediumMissing authentication for streaming RPC framesCWE-306through 1.17.03481
CVE-2026-79704MediumOOB read in multi stream RPC response (client)CWE-1251.11.0 through 1.17.03485
CVE-2026-80463MediumUnbounded stream message reassemblyCWE-770through 1.17.03489
CVE-2026-81755MediumExcessive streams in a single RPCCWE-400through 1.17.03493
CVE-2026-82210MediumCrash via malformed stream feedback framesCWE-617through 1.17.03494
CVE-2026-82230HighStack exhaustion in mcpack2pb parserCWE-674through 1.17.03499
CVE-2026-82231HighMalformed Thrift T_EXCEPTION reply terminates clientCWE-248through 1.17.03500
CVE-2026-82425ModerateReachable assertion in Socket::OnInputEventCWE-617through 1.17.03510
CVE-2026-82942ModerateRace on shared input buffer in RDMA transportCWE-362through 1.17.03505
CVE-2026-82953HighNULL dereference in RTMP createStream error pathCWE-476through 1.17.03508
CVE-2026-84727ModerateUse after free in RTMP chunk stream via AbortCWE-416through 1.17.03515
CVE-2026-84747ModerateAccess control bypass via empty path segmentsCWE-436through 1.17.03512
CVE-2026-84748ModerateBuiltin services reachable on public port via pb protocolsCWE-285through 1.17.03511
CVE-2026-86146ModerateHTTP request smuggling and header injectionCWE-444through 1.17.03521
CVE-2026-86147ModerateFile creation via /flags, unbounded /pprof durationCWE-73, CWE-400through 1.17.03523
CVE-2026-86249ModerateAuth bypass with internal_port plus authCWE-287through 1.17.03525
CVE-2026-87849ModerateOOB read in Discovery naming service reply parsingCWE-125through 1.17.03533
CVE-2026-90484ModerateNULL dereference in MySQL reply parser (client)CWE-476through 1.17.03536

One record oddity: the machine readable version field in the CVE record for CVE-2026-90484 reads <= 1.11.0 with an upper bound of "less than 1.18.0", while the advisory text says "through 1.17.0". Use the advisory text; any version before 1.18.0 should be treated as affected.

Scores and enrichment

Apache publishes word ratings only, and the CVE records carry no CNA CVSS vector. Any numeric score you see came from someone else. As of 24 October, CISA's enrichment container on three records gave:

CVECISA CVSS 3.1VectorSSVC
CVE-2026-563867.5AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:HExploitation none, Automatable no, Technical impact partial
CVE-2026-822307.5AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:HExploitation none, Automatable yes, Technical impact partial
CVE-2026-847275.4AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:LExploitation none, Automatable no, Technical impact partial

NVD showed CVE-2026-48830 as "Deferred" with no NVD metrics. Do not wait for an NVD score before acting; for this batch it may never come.

New limits and flags after upgrading

1.18.0 changes behaviour. Most changes reject traffic that was already malformed, but a few can reject deep or large legitimate payloads, so check them before rolling out.

SettingDefault after 1.18.0Linked CVEWhat it does
redis_max_reply_depth128CVE-2026-54426Rejects deeper Redis reply nesting
amf_max_depth128CVE-2026-54427Rejects deeper AMF nesting
amf_max_string_size64 MiBCVE-2026-56387Caps AMF string length
amf_max_array_size1,048,576 elementsCVE-2026-56387Caps AMF array count
redis_max_allocation_sizenow applied to inline commandsCVE-2026-58064Caps inline command lines
max_body_size64 MiB, now enforced consistentlyCVE-2026-61902, 80463HTTP/1 returns 413; h2 streams reset
max_decompressed_body_sizenew flagCVE-2026-78066Caps decompressed output
max_concurrent_streams1024 per connectionCVE-2026-78058h2 stream cap; 4294967295 restores unlimited
max_header_list_size1 MiB decoded per streamCVE-2026-78058h2 header cap; h2_client_max_header_list_size for clients
h2_ack_ignore_eovercrowdedoffCVE-2026-78058Restores the old acknowledgement behaviour if set
stream_max_streams_per_request64CVE-2026-81755Caps streams declared in one RPC
mcpack2pb MAX_DEPTH128 on parse pathCVE-2026-82230Matches the serializer's limit
max_profiling_seconds300CVE-2026-86147Now also caps /pprof
http_allow_empty_path_segmentsoffCVE-2026-84747Restores doubled slash dispatch; not recommended
http_allow_obs_foldoffCVE-2026-86146Restores folded framing headers
http_strict_header_tokenoffCVE-2026-86146Optionally rejects spaces in any header name
VerifyOptions::expected_peer_namenewCVE-2026-66392Sets the name the server certificate must carry

Two other behaviour changes come from the fixes rather than a flag. Ordinary services are no longer served on internal_port (CVE-2026-86249), and builtin HTTP requests on the public port of an authenticated server now need credentials (CVE-2026-48830). The release notes also say 1.18.0 aligns all builds on a C++14 baseline, so very old toolchains may need attention.

The release and its contents

The GitHub release for 1.18.0 is dated 2026-09-17T15:53:36Z; the RELEASE_VERSION file and set(BRPC_VERSION 1.18.0) in CMakeLists.txt both read 1.18.0. The release notes list the security fixes under "Bugfixes" and "Enhancements" without CVE IDs, for example "Apply auth check to builtin requests on public port" (PR 3308). Wording like "auth", "bound", "limit" and "reject" in release notes is a useful early signal. The same release added THREAT_MODEL.md and SECURITY.md (PR 3324); the threat model lists the defaults the project leaves to operators, including builtin services on the main port and client TLS verification off by default.

Credits

Counting each name once, the advisory credits 12 finders or teams. Fifteen CVEs, including CVE-2026-86249, 84748, 84747 and 86146, are credited to a finder listed only as "Claude", with no detail on who ran the analysis. Others include Brubbish of VARAS@IIE (CVE-2026-48830), Nikko Enggaliano Pratama (four), Feng Zhijie (three), Kaixuan Li and Ubeddulla Khan (two each), and a security vendor's research lab (two). CVE-2026-54427 and CVE-2026-84727 carry no credit.

Indicators of compromise

None were published. These are flaws, not a campaign. The closest thing to a signal is behaviour: unexpected process aborts with CHECK failures in HPACK, stream or socket code; requests to builtin paths such as /flags, /pprof, /vars or /hotspots from outside your operations network; and doubled slashes in request paths at your proxy. None of these proves an attack.

What to do now

1. Find every bRPC you build

Search source trees and build files, not lockfiles:

# Build definitions that pull bRPC
grep -rIn --include=CMakeLists.txt --include='*.cmake' --include=BUILD \
  --include=BUILD.bazel --include=WORKSPACE --include=MODULE.bazel \
  --include=vcpkg.json --include=conanfile.txt --include=conanfile.py \
  --include='*.sh' -i 'brpc' .

# Code that includes it
grep -rIl --include='*.h' --include='*.hpp' --include='*.cc' --include='*.cpp' \
  '#include [<"]brpc/' . | head

# Vendored copies carry their version in the tree
find . -path '*brpc*' \( -name RELEASE_VERSION -o -name CMakeLists.txt \) \
  -exec grep -H -E '^1\.[0-9]+\.[0-9]+$|set\(BRPC_VERSION' {} \;

For vcpkg, run vcpkg list brpc and check the baseline in vcpkg-configuration.json. For a third party script that downloads a tarball, the version is usually in the URL, as in the Doris and StarRocks vars.sh files.

2. Find bRPC in binaries and images

# Shared or static libraries on a host or in an unpacked image
find / -xdev \( -name 'libbrpc*.so*' -o -name 'libbrpc*.a' \) 2>/dev/null

# Binaries that link it dynamically
for b in /usr/local/bin/* /opt/*/bin/*; do
  ldd "$b" 2>/dev/null | grep -q libbrpc && echo "$b"
done

# Statically linked binaries still carry bRPC symbol names
nm -C --defined-only ./your-service 2>/dev/null | grep -c 'brpc::Server::Start'

A static link leaves symbols but no reliable version string, so for those you need the build record or the source tree that produced the binary.

3. Check what each server exposes

From a host on the same network as a would-be attacker, not from inside the service's own subnet, test whether builtin services answer on the public port:

curl -s -o /dev/null -w '%{http_code}\n' -m 3 http://SERVICE_HOST:PUBLIC_PORT/status
curl -s -o /dev/null -w '%{http_code}\n' -m 3 http://SERVICE_HOST:PUBLIC_PORT/vars

A 200 means builtin services are on the public listener. The bRPC documentation also gives a one line check for whether /dir and /threads are enabled, which should never be true on a public port. In code, look for ServerOptions settings: auth, internal_port, has_builtin_services, enabled_protocols, redis_service, rtmp_service, and the gflags -immutable_flags, -enable_dir_service and -enable_threads_service.

4. Reduce exposure until you can upgrade

These controls come from the project's own documentation and threat model:

  1. Set has_builtin_services = false where they are not needed, or set internal_port and firewall it. Before 1.18.0 internal_port alone was bypassable, so the firewall is the real control.
  2. Restrict enabled_protocols to what you serve; if you never speak RTMP, Redis or nshead, do not accept them.
  3. Front HTTP services with a proxy that forwards only named paths and rejects doubled slashes and ambiguous framing headers.
  4. Set -immutable_flags=true and run bRPC as an unprivileged user.
  5. Keep bRPC Redis, Thrift, MySQL and Discovery clients pointed at servers you control, with mutual TLS across untrusted networks.

5. Upgrade to 1.18.0, or backport the patches

Bump the version in whatever pulls bRPC in:

# CMake FetchContent example
FetchContent_Declare(brpc
  URL https://github.com/apache/brpc/archive/refs/tags/1.18.0.tar.gz)
# A vars.sh style third party script
BRPC_DOWNLOAD="https://github.com/apache/brpc/archive/refs/tags/1.18.0.tar.gz"

If you are on a fork or an old line you cannot leave this quarter, every CVE has a single named pull request. Start with 3308, 3525, 3511 and 3512 for the access control issues, then 3474, 3476, 3343, 3462, 3325 and 3354 for the parsers that face the network on the most common configurations, then the rest by which features you enable. Run the project's unit tests after each cherry pick; several fixes touch the same HPACK and stream files.

6. Rebuild and redeploy everything that links it

A library fix does nothing until the binaries that link it are rebuilt. For static links that means every service, not just a shared package. Track rebuilds by service and image digest, not by ticket.

7. Test the new limits, then verify

Replay representative traffic and watch for HTTP 413, h2 REFUSED_STREAM, EMSGSIZE on streams, depth errors and HTTP 403 on internal_port. Raise a limit only for a named client that needs it. Then re-run steps 1 to 3: builtin paths on an authenticated public port should demand credentials, and every build file should reference 1.18.0 or a fork with the named patches.

What changed since first reports

Early summaries listed 33 of the 35 titles. The full Apache text adds CVE-2026-80463 (unbounded stream reassembly memory) and CVE-2026-82425 (a reachable assertion on a revived client socket), both moderate and fixed in 1.18.0. Since 21 October the only changes are CISA's enrichment on three records and NVD's deferral; no exploitation reports had appeared by 24 October.

Open questions

  • Downstream exposure. No vendor shipping bRPC inside a product had published an assessment we could find by 24 October.
  • Patched forks. How many customised forks already carried equivalent fixes is unknown.
  • Scores. Most of these CVEs may never get an NVD score. Prioritise by reachability in your configuration.
  • Why 1.17.0 is listed as affected. PR 3308 was merged on 25 May and 1.17.0 shipped on 28 May, yet the advisory lists 1.17.0 as affected. The release was probably cut before the merge, but we have not confirmed the branch history. Follow the advisory.

What would have helped

There was no reported attack. The useful question is how to make a batch like this an easy job, and how to have taken the fix in September instead of late October.

Practices any team can use

  1. Keep a manifest for native dependencies. Record the name, version and source URL of every C++ library fetched by a script or vendored, and generate an SBOM from it at build time.
  2. Watch releases, not only CVE feeds. The 1.18.0 notes were full of hardening language five weeks before the CVEs. Follow the GitHub release feed or announce@apache.org and take minor releases on a schedule.
  3. Read the threat model of anything you embed. bRPC's says authentication is per connection, builtin services are on by default and client TLS verification is off by default.
  4. Separate administration from service traffic at the network layer. An internal port is only internal if a firewall makes it so.
  5. Turn off what you do not use. enabled_protocols, has_builtin_services and immutable_flags shrink the attack surface for free.
  6. Plan for forks. If you run a customised fork, keep a list of upstream security PRs you have and have not ported, and assign an owner.

Where Safeguard fits

Start with where bRPC actually lives. A lockfile or package manifest is where most dependency scanning looks first, and a bRPC tarball fetched by a CMake or shell script, or copied into a vendored directory, is not declared there. So feed the scan an input that does name it: the built binary or container image, or an SBOM your build produces.

  • Bring your own SBOM. If your build generates an SBOM that lists bRPC with its version, uploading that SBOM to Safeguard matches it against vulnerability databases, and the platform then shows which projects contain that component and version.
  • Track the services around it. safeguard scan --dir . and safeguard scan --image <name> cover the rest of what those services ship, written as JSON under ./output, so the rebuild for bRPC can also pick up other fixes.
  • Keep old versions out. Policies and gates evaluated in the platform can block promotion of a build whose SBOM still lists bRPC below 1.18.0.
  • Do the edit. The Safeguard CLI's assistant can change a vars.sh, a CMake FetchContent URL or a Bazel module version to 1.18.0, run your build and tests, and ask before each command under the default permission mode. safeguard exec runs the same work in CI. Autonomous remediation can open fix pull requests and ships switched off.

Where it does not help: Safeguard does not change ServerOptions in a running service, write your firewall rules, or tell you which bRPC features a closed source product enables. When bRPC is embedded in a vendor's product, the fix has to come from that vendor.

To try the CLI on your own repositories and images, download Safeguard and read the CLI docs.

The same release first, CVEs later pattern showed up the same day in Apache IoTDB 2.0.11; the link between the two is timing only. For the response process when a shared dependency turns out to be vulnerable, see our incident response playbook for a compromised dependency.

Common mistakes and troubleshooting

  • "We set internal_port, so builtin services are safe." Not before 1.18.0; see CVE-2026-84748 and CVE-2026-86249. Firewall the port and upgrade.
  • "We have authentication, so pre-auth parser bugs do not apply." The h2, Redis, RTMP and mcpack parsers run before the Authenticator.
  • "We scanned the repo and found nothing." Package based scanners cannot see a library pulled in by a script or vendored directory.
  • Upgrading the library but not the binaries. Static links keep the old code until rebuilt and redeployed.
  • Breaking monitoring. Dashboards that scraped /vars on the public port of an authenticated server will fail after the upgrade; move them to the internal port.
  • Cherry picks that conflict. Several patches touch the HPACK, HTTP/2 and stream code; apply them in PR number order and run tests between each.

FAQ

What is CVE-2026-48830 in Apache bRPC?

A high rated authentication bypass. With ServerOptions.auth enabled and builtin HTTP services on the public listener, a keep-alive connection could be treated as authenticated without credentials, so later requests to protected endpoints skipped the check. It affects bRPC through 1.17.0 and is fixed in 1.18.0 and PR 3308.

Which versions are affected and which version fixes them?

All 35 CVEs affect bRPC through 1.17.0; CVE-2026-79704 specifically affects 1.11.0 through 1.17.0. All are fixed in 1.18.0, released on GitHub on 17 September 2026. Each CVE also names a single pull request for teams that need to backport.

Is anyone exploiting these vulnerabilities?

No exploitation is reported. None are in the CISA KEV catalog as of version 2026.10.23, CISA's enrichment on three records says "Exploitation: none", and we found no public proof of concept.

What is the CVSS score?

Apache did not publish CVSS scores, only high and moderate ratings. CISA's enrichment scored CVE-2026-56386 and CVE-2026-82230 at 7.5 and CVE-2026-84727 at 5.4. NVD deferred CVE-2026-48830 without a score.

We set internal_port. Are we protected?

Partly, and not on 1.17.0 or earlier. CVE-2026-86249 and CVE-2026-84748 are both bypasses involving internal_port. Keep the internal port behind a firewall, restrict enabled protocols, and upgrade.

Do we need to upgrade services that only use bRPC as a client?

Yes. Redis, Thrift, MySQL, Discovery, multi stream RPC, TLS name checks and health checks all have client side CVEs in this batch.

Will 1.18.0 break anything?

Possibly. It enforces new parsing limits, rejects some old HTTP header forms, stops serving ordinary services on internal_port, requires credentials for builtin services on authenticated public ports, and moves to a C++14 baseline. See the limits table above and test before rollout.

Is Apache Doris or StarRocks affected?

Their master branch build scripts referenced older bRPC tarballs (1.4.0 and 1.9.0) on 24 October. Neither had published an assessment we could find, and they may patch or disable the affected features. Check with each project before drawing a conclusion.

bRPC is a good case for this section because every CVE comes with a small, named patch. If your service is pinned to a fork or an old line, backporting those pull requests into your own build is realistic today, and it is the same pattern the steps below describe.

Fix it without waiting for upstream

Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation categories include dependencies, licenses, security posture and findings, and each one is set separately. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds.

3. Gold Registry: start from components that are already fixed

Gold Registry provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs and a completed license check, with signed build provenance (signed with Safeguard's key and verifiable with cosign, SLSA Build Level 3 as the design target) and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. Ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingSafeguard policies and gates in CI
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

See how Safeguard would have helped

None of these demos shows bRPC; each shows a real flow that maps onto this upgrade.

The first is a real Safeguard CLI session. It installs the CLI, opens the interactive terminal and asks it to fix a lodash CVE: the assistant reads the finding and advisory, asks before any command that changes something, edits package.json to lodash 4.17.21, runs npm install and npm test with approval, and pushes nothing. For bRPC you would ask it to change the tarball URL in your third party script or the FetchContent line in CMake to 1.18.0, then approve the build and the test run one command at a time.

Click through it at your own pace, or open it full screen.

The second demo sets up the Safeguard runner on your own machine, approves it with a device code and then scans from the terminal. That is how you would scan the SBOMs and images your C++ builds produce and ask which still list bRPC below 1.18.0.

Click through it at your own pace, or open it full screen.

The third demo is a real desktop app session. The CLI session appears in the conversation list, you ask for work on your computer, pick the folder, and Approve or Deny each command and file edit; it ends with an upgrade done and tests passing. Here you would pick the repository of a service that links bRPC, let it propose the version bump plus has_builtin_services = false where the service does not need them, and approve each edit and build.

Click through it at your own pace, or open it full screen.

Quick check

Your bRPC 1.16 server uses an Authenticator and sets internal_port. Is it safe from the auth bypasses?

No. CVE-2026-86249 and CVE-2026-84748 are bypasses that involve internal_port, and the parser bugs run before authentication anyway. Firewall the internal port, restrict enabled protocols and upgrade to 1.18.0.

Your dependency scanner reports no bRPC in a C++ repository. Are you done?

Not yet. bRPC usually arrives through a build script, a CMake or Bazel rule or a vendored directory, which package based scanners cannot see. Search the build files and binaries, then generate an SBOM that lists it.

Sources

Last reviewed: 24 October 2026. This is a developing story; check the linked advisories for the latest status.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.