Pingora OSS展開におけるリクエスト・スマグリング脆弱性の修正
CloudflareはPingora OSSフレームワークのHTTP/1リクエストスモーシング脆弱性(CVE-2026-2833等)を公開し、Cloudflare CDNは影響を受けないが、スタンドアロン展開ユーザーへの早急なバージョン0.8.0へのアップグレードを推奨している。
キーポイント
脆弱性の概要と攻撃経路
HTTP/1スタックにおけるRFC非準拠のボディ長解釈が原因で、プロキシとバックエンド間の同期がずれる(デシンク)スモーシング攻撃が可能となり、セキュリティ制御の回避やセッション横取り、キャッシュポイズニングを招く。
Cloudflare CDNへの影響範囲
Cloudflareのネットワークアーキテクチャ上、Pingoraはインターネットに直接公開されるエッジプロキシとして運用されていないため、CloudflareのCDNおよび顧客トラフィックへの影響はゼロである。
スタンドアロン展開のリスクと対策
インターネットに公開されるスタンドアロンのPingoraデプロイメントは脆弱性の対象となるため、Cloudflareは修正と強化を施した「Pingora 0.8.0」をリリースし、該当フレームワークの利用者への早急なアップグレードを強く推奨している。
Transfer-Encodingの認識不足
PingoraはTransfer-Encodingヘッダーを単純にチェックするのみで、RFCが定める複数のエンコーディングや最終エンコーディングの処理に対応できていなかった。
HTTP/1.0とクローズ区切りの誤処理
Transfer-Encodingを認識できずHTTP/1.0だったため、Pingoraはリクエストボディを接続終了まで読み込む「クローズ区切り」として誤解釈した。RFCではリクエストボディのクローズ区切りは禁止されている。
パイプライン攻撃によるデシンク
攻撃者がHTTP/1.0リクエストの後に部分ヘッダーをパイプライン送信すると、Pingoraはそれを同一リクエストの本文とみなし、バックエンドとのフレームング不一致(CL.TE)によるデシンク攻撃を可能にした。
リクエストスモーシング対策の強化
不正なTransfer-EncodingとContent-Lengthの組み合わせを拒否し、リクエストボディをクローズデリミテッドとみなさないよう厳格化。また、プロキシロジックの制限からCONNECTリクエストをデフォルトで拒否するよう変更された。
影響分析・編集コメントを表示
影響分析
本件はオープンソースの境界プロキシフレームワークにおけるインフラセキュリティの重要な教訓を示している。Cloudflare CDNは影響を受けないものの、外部公開されるスタンドアロン環境ではセッション横取りやキャッシュポイズニングといった実害を伴う攻撃が可能となるため、運用環境の迅速なバージョンアップが必須である。この修正は、AIインフラや大規模Webサービスを支えるエッジコンピューティング基盤の信頼性維持に寄与する。
編集コメント
大規模AIサービスや生成AIプラットフォームのバックエンドに境界プロキシを採用するケースが増える中、フレームワーク固有のHTTP処理バグがインフラ全体のセキュリティを脅かす可能性を示唆している。運用担当者はCVE番号とバージョン情報を確認し、テスト環境での検証を経て本番展開へ反映させるべきだ。
研究者はまた、デフォルトのCacheKey(キャッシュキー)構築に関する別のキャッシュ汚染脆弱性を報告しました。単純なデフォルト実装ではURIパスのみを考慮し(ホストヘッダーやアップストリームサーバーのHTTPスキームなどの他の要素を含まない)、同じHTTPパスを使用する異なるホストが衝突して互いのキャッシュを汚染する可能性がありました。
この問題は、アルファ版のプロキシキャッシュ機能において、デフォルトのCacheKey実装を使用することを選択したユーザーに影響を与えていました。その後、私たちはこのデフォルト実装を削除しました。なぜなら、HTTPスキーム+ホスト+URIのような要素を使用することは多くのアプリケーションで理にかなっていますが、ユーザー自身がキャッシュキーを構築する際には注意深く行う必要があると考えたからです。例えば、プロキシロジックがアップストリームリクエストのURIやメソッドを条件付きで調整する場合、そのロジックもキャッシュキースキームに組み込む必要があり、汚染を避けるためです。
内部では、Cloudflareのデフォルトキャッシュキーはキャッシュキー汚染を防ぐために多数の要素を使用しており、以前提供されていたデフォルト実装を一切使用していませんでした。
Recommendation
Pingoraをプロキシとして使用している場合は、できるだけ早くPingora 0.8.0にアップグレードしてください。
この脆弱性がPingoraユーザーに与えた影響についてお詫び申し上げます。PingoraがCloudflareを超えた重要なインターネットインフラストラクチャとしての地位を確立するにつれ、フレームワークがデフォルトで厳格なRFC準拠の使用を促進することが重要であると信じており、この取り組みを継続します。フレームワークのユーザーの多くは、Cloudflareが扱うような同じ「実インターネット」トラフィックに対処する必要はないはずです。私たちの意図は、デフォルトでの最新RFC標準へのより厳格な準拠により、Pingoraユーザーのセキュリティを強化し、インターネット全体をベストプラクティスに向けて前進させることです。
Disclosure and response timeline
- 2025年12月2日: バグバウンティプログラムを通じて、アップグレードヘッダーを利用したスミグリング脆弱性が報告される。
- 2026年1月13日: Transfer-Encoding / HTTP/1.0のパース問題が報告される。
- 2026年1月18日: デフォルトキャッシュキー構築問題が報告される。
- 2026年1月29日から2026年2月13日: 修正が報告者と共に検証される。より多くのRFC準拠チェックの作業が継続。
- 2026年2月25日: キャッシュキーデフォルト削除と追加RFCチェックが研究者と共に検証される。
- 2026年3月2日: Pingora 0.8.0がリリースされる。
- 2026年3月4日: CVEアドバイザリが公開される。
Acknowledgements
バグバウンティプログラムを通じた報告、詳細な再現、修正の検証に対して、Rajat Raghav (xclow3n) に感謝します。詳細については、対応するブログをご覧ください。
また、Pingoraオープンソースコミュニティの積極的な関与、問題報告、フレームワークへの貢献に対して心からの感謝を申し上げます。あなた方は本当に私たちがより良いインターネットを構築するのを助けてくれています。
原文を表示
In December 2025, Cloudflare received reports of HTTP/1.x request smuggling vulnerabilities in the Pingora open source framework when Pingora is used to build an ingress proxy. Today we are discussing how these vulnerabilities work and how we patched them in Pingora 0.8.0.
The vulnerabilities are CVE-2026-2833, CVE-2026-2835, and CVE-2026-2836. These issues were responsibly reported to us by Rajat Raghav (xclow3n) through our Bug Bounty Program.
Cloudflare’s CDN and customer traffic were not affected, our investigation found. No action is needed for Cloudflare customers, and no impact was detected.
Due to the architecture of Cloudflare’s network, these vulnerabilities could not be exploited: Pingora is not used as an ingress proxy in Cloudflare’s CDN.
However, these issues impact standalone Pingora deployments exposed to the Internet, and may enable an attacker to:
Bypass Pingora proxy-layer security controls
Desync HTTP request/responses with backends for cross-user hijacking attacks (session or credential theft)
Poison Pingora proxy-layer caches retrieving content from shared backends
We have released Pingora 0.8.0 with fixes and hardening. While Cloudflare customers were not affected, we strongly recommend users of the Pingora framework to upgrade as soon as possible.
What was the vulnerability?
The reports described a few different HTTP/1 attack payloads that could cause desync attacks. Such requests could cause the proxy and backend to disagree about where the request body ends, allowing a second request to be “smuggled” past proxy‑layer checks. The researcher provided a proof-of-concept to validate how a basic Pingora reverse proxy misinterpreted request body lengths and forwarded those requests to server backends such as Node/Express or uvicorn.
Upon receiving the reports, our engineering team immediately investigated and validated that, as the reporter also confirmed, the Cloudflare CDN itself was not vulnerable. However, the team did also validate that vulnerabilities exist when Pingora acts as the ingress proxy to shared backends.
By design, the Pingora framework does allow edge case HTTP requests or responses that are not strictly RFC compliant, because we must accept this sort of traffic for customers with legacy HTTP stacks. But this leniency has limits to avoid exposing Cloudflare itself to vulnerabilities.
In this case, Pingora had non-RFC-compliant interpretations of request bodies within its HTTP/1 stack that allowed these desync attacks to exist. Pingora deployments within Cloudflare are not directly exposed to ingress traffic, and we found that production traffic that arrived at Pingora services were not subject to these misinterpretations. Thus, the attacks were not exploitable on Cloudflare traffic itself, unlike a previous Pingora smuggling vulnerability disclosed in May 2025.
We’ll explain, case-by-case, how these attack payloads worked.
- Premature upgrade without 101 handshake
The first report showed that a request with an Upgrade header value would cause Pingora to pass through subsequent bytes on the HTTP connection immediately, before the backend had accepted an upgrade (by returning 101 Switching Protocols). The attacker could thus pipeline a second HTTP request after the upgrade request on the same connection:
GET / HTTP/1.1
Host: example.com
Upgrade: foo
GET /admin HTTP/1.1
Host: example.com
Pingora would parse only the initial request, then treat the remaining buffered bytes as the “upgraded” stream and forward them directly to the backend in a “passthrough” mode due to the Upgrade header (until the response was received).
This is not at all how the HTTP/1.1 Upgrade process per RFC 9110 is intended to work. The subsequent bytes should only be interpreted as part of an upgraded stream if a 101 Switching Protocols header is received, and if a 200 OK response is received instead, the subsequent bytes should continue to be interpreted as HTTP.
image
An attacker that sends an Upgrade request, then pipelines a partial HTTP request may cause a desync attack. Pingora will incorrectly interpret both as the same upgraded request, even if the backend server declines the upgrade with a 200.
Via the improper pass-through, a Pingora deployment that received a non-101 response could still forward the second partial HTTP request to the upstream as-is, bypassing any Pingora user‑defined ACL-handling or WAF logic, and poison the connection to the upstream so that a subsequent request from a different user could improperly receive the /admin response.
image
After the attack payload, Pingora and the backend server are now “desynced.” The backend server will wait until it thinks the rest of the partial /attack request header that Pingora forwarded is complete. When Pingora forwards a different user’s request, the two headers are combined from the backend server’s perspective, and the attacker has now poisoned the other user’s response.
We’ve since patched Pingora to switch the interpretation of subsequent bytes only once the upstream responds with 101 Switching Protocols.
We verified Cloudflare was not affected for two reasons:
The ingress CDN proxies do not have this improper behavior.
The clients to our internal Pingora services do not attempt to pipeline HTTP/1 requests. Furthermore, the Pingora service these clients talk directly with disables keep-alive on these Upgrade requests by injecting a Connection: close header; this prevents additional requests that would be sent — and subsequently smuggled — over the same connection.
- HTTP/1.0, close-delimiting, and transfer-encoding
The reporter also demonstrated what appeared to be a more classic “CL.TE” desync-type attack, where the Pingora proxy would use Content-Length as framing while the backend would use Transfer-Encoding as framing:
GET / HTTP/1.0
Host: example.com
Connection: keep-alive
Transfer-Encoding: identity, chunked
Content-Length: 29
0
GET /admin HTTP/1.1
X:
In the reporter’s example, Pingora would treat all subsequent bytes after the first GET / request header as part of that request’s body, but the node.js backend server would interpret the body as chunked and ending at the zero-length chunk. There are actually a few things going on here:
Pingora’s chunked encoding recognition was quite barebones (only checking for whether Transfer-Encoding was “chunked”) and assumed that there could only be one encoding or Transfer-Encoding header. But the RFC only mandates that the final encoding must be chunked to apply chunked framing. So per RFC, this request should have a chunked message body (if it were not HTTP/1.0 — more on that below).
Pingora was also not actually using the Content-Length (because the Transfer-Encoding overrode the Content-Length per RFC). Because of the unrecognized Transfer-Encoding and the HTTP/1.0 version, the request body was instead treated as close-delimited (which means that the response body’s end is marked by closure of the underlying transport connection). An absence of framing headers would also trigger the same misinterpretation on HTTP/1.0. Although response bodies are allowed to be close-delimited, request bodies are never close-delimited. In fact, this clarification is now explicitly called out as a separate note in RFC 9112.
This is an HTTP/1.0 request that did not define Transfer-Encoding. The RFC mandates that HTTP/1.0 requests containing Transfer-Encoding must “treat the message as if the framing is faulty” and close the connection. Parsers such as the ones in nginx and hyper just reject these requests to avoid ambiguous framing.
image
When an attacker pipelines a partial HTTP request header after the HTTP/1.0 + Transfer-Encoding request, Pingora would incorrectly interpret that partial header as part of the same request, rather than as a distinct request. This enables the same kind of desync attack as described in the premature Upgrade example.
This spoke to a more fundamental misreading of the RFC particularly in terms of response vs. request message framing. We’ve since fixed the improper multiple Transfer-Encoding parsing, adhere strictly to the request length guidelines such that HTTP request bodies can never be considered close-delimited, and reject invalid Content-Length and HTTP/1.0 + Transfer-Encoding request messages. Further protections we’ve added include rejecting CONNECT requests by default because the HTTP proxy logic doesn’t currently treat CONNECT as special for the purposes of CONNECT upgrade proxying, and these requests have special message framing rules. (Note that incoming CONNECT requests are rejected by the Cloudflare CDN.)
When we investigated and instrumented our services internally, we found no requests arriving at our Pingora services that would have been misinterpreted. We found that downstream proxy layers in the CDN would forward as HTTP/1.1 only, reject ambiguous framing such as invalid Content-Length, and only forward a single Transfer-Encoding: chunked header for chunked requests.
- Cache key construction
The researcher also reported one other cache poisoning vulnerability regarding default CacheKey construction. The naive default implementation factored in only the URI path (without other factors such as host header or upstream server HTTP scheme), which meant different hosts using the same HTTP path could collide and poison each other’s cache.
This would affect users of the alpha proxy caching feature who chose to use the default CacheKey implementation. We have since removed that default, because while using something like HTTP scheme + host + URI makes sense for many applications, we want users to be careful when constructing their cache keys for themselves. If their proxy logic will conditionally adjust the URI or method on the upstream request, for example, that logic likely also must be factored into the cache key scheme to avoid poisoning.
Internally, Cloudflare’s default cache key uses a number of factors to prevent cache key poisoning, and never made use of the previously provided default.
Recommendation
If you use Pingora as a proxy, upgrade to Pingora 0.8.0 at your earliest convenience.
We apologize for the impact this vulnerability may have had on Pingora users. As Pingora earns its place as critical Internet infrastructure beyond Cloudflare, we believe it’s important for the framework to promote use of strict RFC compliance by default and will continue this effort. Very few users of the framework should have to deal with the same “wild Internet” that Cloudflare does. Our intention is that stricter adherence to the latest RFC standards by default will harden security for Pingora users and move the Internet as a whole toward best practices.
Disclosure and response timeline
- 2025‑12‑02: Upgrade‑based smuggling reported via bug bounty.
- 2026‑01‑13: Transfer‑Encoding / HTTP/1.0 parsing issues reported.
- 2026-01-18: Default cache key construction issue reported.
- 2026‑01‑29 to 2026‑02‑13: Fixes validated with the reporter. Work on more RFC-compliance checks continues.
- 2026-02-25: Cache key default removal and additional RFC checks validated with researcher.
- 2026‑03-02: Pingora 0.8.0 released.
- 2026-03-04: CVE advisories published.
Acknowledgements
We thank Rajat Raghav (xclow3n) for the report, detailed reproductions, and verification of the fixes through our bug bounty program. Please see their corresponding blog for more information.
We would also extend a heartfelt thank you to the Pingora open source community for their active engagement, issue reports, and contributions to the framework. You truly help us build a better Internet.
関連記事
今日のまとめ
AI日報で今日の重要ニュースをまとめ読み