GHSA-2MR3-M5Q5-WGP6

Vulnerability from github – Published: 2026-02-24 20:57 – Updated: 2026-02-24 20:57
VLAI?
Summary
Fiber is Vulnerable to Denial of Service via Flash Cookie Unbounded Allocation
Details

Summary

The use of the fiber_flash cookie can force an unbounded allocation on any server. A crafted 10-character cookie value triggers an attempt to allocate up to 85GB of memory via unvalidated msgpack deserialization. No authentication is required. Every GoFiber v3 endpoint is affected regardless of whether the application uses flash messages.

Details

Regardless of configuration, the flash cookie is checked:

func (app *App) requestHandler(rctx *fasthttp.RequestCtx) {
    // Acquire context from the pool
    ctx := app.AcquireCtx(rctx)
    defer app.ReleaseCtx(ctx)

        // Optional: Check flash messages
        rawHeaders := d.Request().Header.RawHeaders()
        if len(rawHeaders) > 0 && bytes.Contains(rawHeaders, flashCookieNameBytes) {
            d.Redirect().parseAndClearFlashMessages()
        }
        _, err = app.next(d)
    } else {
        // Check if the HTTP method is valid
        if ctx.getMethodInt() == -1 {
            _ = ctx.SendStatus(StatusNotImplemented) //nolint:errcheck // Always return nil
            return
        }

        // Optional: Check flash messages
        rawHeaders := ctx.Request().Header.RawHeaders()
        if len(rawHeaders) > 0 && bytes.Contains(rawHeaders, flashCookieNameBytes) {
            ctx.Redirect().parseAndClearFlashMessages()
        }
}

The cookie value is hex-decoded and passed directly to msgpack deserialization with no size or content validation:

https://github.com/gofiber/fiber/blob/f8f34f642fb3682c341ede7816e7cf861aa7df89/redirect.go#L371

// parseAndClearFlashMessages is a method to get flash messages before they are getting removed
func (r *Redirect) parseAndClearFlashMessages() {
    // parse flash messages
    cookieValue, err := hex.DecodeString(r.c.Cookies(FlashCookieName))
    if err != nil {
        return
    }

    _, err = r.c.flashMessages.UnmarshalMsg(cookieValue)
    if err != nil {
        return
    }

    r.c.Cookie(&Cookie{
        Name:   FlashCookieName,
        Value:  "",
        Path:   "/",
        MaxAge: -1,
    })
}

The auto-generated tinylib/msgp deserialization reads a uint32 array header from the attacker-controlled byte stream and passes it directly to make() with no bounds check:

https://github.com/gofiber/fiber/blob/f8f34f642fb3682c341ede7816e7cf861aa7df89/redirect_msgp.go#L242

// UnmarshalMsg implements msgp.Unmarshaler
func (z *redirectionMsgs) UnmarshalMsg(bts []byte) (o []byte, err error) {
    var zb0002 uint32
    zb0002, bts, err = msgp.ReadArrayHeaderBytes(bts)
    if err != nil {
        err = msgp.WrapError(err)
        return o, err
    }
    if cap((*z)) >= int(zb0002) {
        (*z) = (*z)[:zb0002]
    } else {
        (*z) = make(redirectionMsgs, zb0002)
    }
    for zb0001 := range *z {
        bts, err = (*z)[zb0001].UnmarshalMsg(bts)
        if err != nil {
            err = msgp.WrapError(err, zb0001)
            return o, err
        }
    }
    o = bts
    return o, err
}

where zb0002, bts, err = msgp.ReadArrayHeaderBytes(bts) translates the attacker-controlled value into the element count and make(redirectionMsgs, zb0002) performs the unbounded allocation

So we can craft a gofiber cookie that will force a huge allocation: curl -H "Cookie: fiber_flash=dd7fffffff" http://localhost:5000/hello

The cookie val is a hex-encoded msgpack array32 header: - dd = msgpack array32 marker - 7fffffff = 2 147 483 647 elements

Impact

Unauthenticated remote Denial of Service (CWE-789). Anyone running a gofiber v3.0.0 or v3 server is affected. The flash cookie parsing is hardcoded.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 3.0.0"
      },
      "package": {
        "ecosystem": "Go",
        "name": "github.com/gofiber/fiber/v3"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "3.1.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-25899"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-789"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-02-24T20:57:25Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "### Summary\nThe use of the `fiber_flash` cookie can force an unbounded allocation on any server. A crafted 10-character cookie value triggers an attempt to allocate up to 85GB of memory via unvalidated msgpack deserialization. No authentication is required. Every GoFiber v3 endpoint is affected regardless of whether the application uses flash messages.\n\n### Details\nRegardless of configuration, the flash cookie is checked:\n\n```go\nfunc (app *App) requestHandler(rctx *fasthttp.RequestCtx) {\n\t// Acquire context from the pool\n\tctx := app.AcquireCtx(rctx)\n\tdefer app.ReleaseCtx(ctx)\n\n\t\t// Optional: Check flash messages\n\t\trawHeaders := d.Request().Header.RawHeaders()\n\t\tif len(rawHeaders) \u003e 0 \u0026\u0026 bytes.Contains(rawHeaders, flashCookieNameBytes) {\n\t\t\td.Redirect().parseAndClearFlashMessages()\n\t\t}\n\t\t_, err = app.next(d)\n\t} else {\n\t\t// Check if the HTTP method is valid\n\t\tif ctx.getMethodInt() == -1 {\n\t\t\t_ = ctx.SendStatus(StatusNotImplemented) //nolint:errcheck // Always return nil\n\t\t\treturn\n\t\t}\n\n\t\t// Optional: Check flash messages\n\t\trawHeaders := ctx.Request().Header.RawHeaders()\n\t\tif len(rawHeaders) \u003e 0 \u0026\u0026 bytes.Contains(rawHeaders, flashCookieNameBytes) {\n\t\t\tctx.Redirect().parseAndClearFlashMessages()\n\t\t}\n}\n```\n\nThe cookie value is hex-decoded and passed directly to msgpack deserialization with no size or content validation:\n\nhttps://github.com/gofiber/fiber/blob/f8f34f642fb3682c341ede7816e7cf861aa7df89/redirect.go#L371\n\n```go\n// parseAndClearFlashMessages is a method to get flash messages before they are getting removed\nfunc (r *Redirect) parseAndClearFlashMessages() {\n\t// parse flash messages\n\tcookieValue, err := hex.DecodeString(r.c.Cookies(FlashCookieName))\n\tif err != nil {\n\t\treturn\n\t}\n\n\t_, err = r.c.flashMessages.UnmarshalMsg(cookieValue)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tr.c.Cookie(\u0026Cookie{\n\t\tName:   FlashCookieName,\n\t\tValue:  \"\",\n\t\tPath:   \"/\",\n\t\tMaxAge: -1,\n\t})\n}\n```\n\nThe auto-generated `tinylib/msgp` deserialization reads a `uint32` array header from the attacker-controlled byte stream and passes it directly to `make()` with no bounds check:\n\nhttps://github.com/gofiber/fiber/blob/f8f34f642fb3682c341ede7816e7cf861aa7df89/redirect_msgp.go#L242\n\n```go\n// UnmarshalMsg implements msgp.Unmarshaler\nfunc (z *redirectionMsgs) UnmarshalMsg(bts []byte) (o []byte, err error) {\n\tvar zb0002 uint32\n\tzb0002, bts, err = msgp.ReadArrayHeaderBytes(bts)\n\tif err != nil {\n\t\terr = msgp.WrapError(err)\n\t\treturn o, err\n\t}\n\tif cap((*z)) \u003e= int(zb0002) {\n\t\t(*z) = (*z)[:zb0002]\n\t} else {\n\t\t(*z) = make(redirectionMsgs, zb0002)\n\t}\n\tfor zb0001 := range *z {\n\t\tbts, err = (*z)[zb0001].UnmarshalMsg(bts)\n\t\tif err != nil {\n\t\t\terr = msgp.WrapError(err, zb0001)\n\t\t\treturn o, err\n\t\t}\n\t}\n\to = bts\n\treturn o, err\n}\n```\n\nwhere\n `zb0002, bts, err = msgp.ReadArrayHeaderBytes(bts)` translates the attacker-controlled value into the element count and `make(redirectionMsgs, zb0002)` performs the unbounded allocation\n\nSo we can craft a gofiber cookie that will force a huge allocation: \n`curl -H \"Cookie: fiber_flash=dd7fffffff\" http://localhost:5000/hello`\n\nThe cookie val is a hex-encoded msgpack array32 header:\n- `dd` = msgpack array32 marker\n- `7fffffff` = 2 147 483 647 elements\n\n### Impact\nUnauthenticated remote Denial of Service (CWE-789). Anyone running a gofiber v3.0.0 or v3 server is affected. The flash cookie parsing is hardcoded.",
  "id": "GHSA-2mr3-m5q5-wgp6",
  "modified": "2026-02-24T20:57:25Z",
  "published": "2026-02-24T20:57:25Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/gofiber/fiber/security/advisories/GHSA-2mr3-m5q5-wgp6"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/gofiber/fiber"
    },
    {
      "type": "WEB",
      "url": "https://github.com/gofiber/fiber/releases/tag/v3.1.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Fiber is Vulnerable to Denial of Service via Flash Cookie Unbounded Allocation"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Sightings

Author Source Type Date

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.


Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…