Skip to main content

Threats Tagged 'ghsa-4q9j-6299-gxmr'

View all threats tagged with 'ghsa-4q9j-6299-gxmr'. Filter and sort to focus on specific types of threats.

Pro Console Lifetime

Stop chasing alerts. Route them.

Start free, then upgrade once to turn Radar into an automated delivery engine for your security stack.

Custom feeds / Automations: email, Slack, webhooks, SIEM/MISP / API access (baseline limits)

View Plans & Pricing

API access activates after upgrading in Console -> Billing.

Breach by OffSeqOFFSEQFRIENDS — 25% OFF

Check if your credentials are on the dark web

Instant breach scanning across billions of leaked records. Free tier available.

Scan now

Filter Threats

Narrow down the results by type, severity, or affected countries

Search threats by title, CVE ID, or description. Maximum 100 characters.
Active filters (1):Tag: ghsa-4q9j-6299-gxmr

Threats Tagged 'ghsa-4q9j-6299-gxmr'

Click on any threat for detailed analysis and mitigation recommendations

### Summary The Dragonfly Manager exposes `GET /api/v1/oauth` and `GET /api/v1/oauth/:id` to unauthenticated clients. The response body deserializes the entire `manager/models.Oauth` struct, which includes the `client_secret` field. Any network-reachable attacker can read the OAuth client secrets configured for `github` or `google` providers, defeating the confidentiality guarantee of those secrets and enabling subsequent abuse against the connected identity providers. ### Affected versions `github.com/dragonflyoss/dragonfly` `<= v2.4.3` (and current `main` at commit `46a8f1e`). The vulnerable wiring is present back to the introduction of OAuth GET handlers and was not addressed by GHSA-j8hf-cp34-g4j7 / CVE-2026-24124, whose remediation only added `jwt + rbac` middleware to the `/jobs` group. ### Privilege required Unauthenticated. The only precondition is that an administrator has registered at least one OAuth provider via `POST /api/v1/oauth` (a one-time setup for tenants that enable GitHub / Google sign-in). ### Vulnerable code [`manager/router/router.go:134-140`](https://github.com/dragonflyoss/dragonfly/blob/e1491bf6134fe307b09e82e11fa94b0587dcd323/manager/router/router.go#L134-L140) (v2.4.3) — the `/oauth` group registration: ```go // Oauth. oa := apiv1.Group("/oauth") oa.POST("", jwt.MiddlewareFunc(), rbac, h.CreateOauth) oa.DELETE(":id", jwt.MiddlewareFunc(), rbac, h.DestroyOauth) oa.PATCH(":id", jwt.MiddlewareFunc(), rbac, h.UpdateOauth) oa.GET(":id", h.GetOauth) oa.GET("", h.GetOauths) ``` Note the asymmetry inside the same `oa` route group: `POST`, `PATCH`, and `DELETE` explicitly attach `jwt.MiddlewareFunc(), rbac` as per-route middleware, but the two `GET` handlers omit both. Compare with the sibling group three lines below at [`manager/router/router.go:143-148`](https://github.com/dragonflyoss/dragonfly/blob/e1491bf6134fe307b09e82e11fa94b0587dcd323/manager/router/router.go#L143-L148), the `/clusters` group: ```go c := apiv1.Group("/clusters", jwt.MiddlewareFunc(), rbac) c.POST("", h.CreateCluster) c.DELETE(":id", h.DestroyCluster) c.PATCH(":id", h.UpdateCluster) c.GET(":id", h.GetCluster) c.GET("", h.GetClusters) ``` Here the middleware pair is attached once at the group level, so every verb on `/clusters` is guarded. The OAuth GETs are an unguarded sibling of the same primitive that GHSA-j8hf-cp34-g4j7 (Jan 2026) patched on the `/jobs` group. This is `sibling-method-dispatch-target` of the AP-012 sub-shape lens: same module, same router file, same anchor primitive ("group lacking JWT + RBAC"), parallel GET methods missed. The handler at [`manager/handlers/oauth.go:127-141`](https://github.com/dragonflyoss/dragonfly/blob/e1491bf6134fe307b09e82e11fa94b0587dcd323/manager/handlers/oauth.go#L127-L141) returns the model directly: ```go func (h *Handlers) GetOauth(ctx *gin.Context) { var params types.OauthParams if err := ctx.ShouldBindUri(&params); err != nil { ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()}) return } oauth, err := h.service.GetOauth(ctx.Request.Context(), params.ID) if err != nil { ctx.Error(err) // nolint: errcheck return } ctx.JSON(http.StatusOK, oauth) } ``` [`manager/handlers/oauth.go:155-171`](https://github.com/dragonflyoss/dragonfly/blob/e1491bf6134fe307b09e82e11fa94b0587dcd323/manager/handlers/oauth.go#L155-L171) has the parallel list handler: ```go func (h *Handlers) GetOauths(ctx *gin.Context) { var query types.GetOauthsQuery if err := ctx.ShouldBindQuery(&query); err != nil { ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()}) return } h.setPaginationDefault(&query.Page, &query.PerPage) oauth, count, err := h.service.GetOauths(ctx.Request.Context(), query) if err != nil { ctx.Error(err) // nolint: errcheck return } h.setPaginationLinkHeader(ctx, query.Page, query.PerPage, int(count)) ctx.JSON(http.StatusOK, oauth) } ``` [`manager/models/oauth.go:19-26`](https://github.com/dragonflyoss/dragonfly/blob/e1491bf6134fe307b09e82e11fa94b0587dcd323/manager/models/oauth.go#L19-L26) declares `ClientSecret` with no `json:"-"` tag, so it is serialized into every response: ```go type Oauth struct { BaseModel Name string `gorm:"column:name;type:varchar(256);index:uk_oauth2_name,unique;not null;comment:oauth2 name" json:"name"` BIO string `gorm:"column:bio;type:varchar(1024);comment:biography" json:"bio"` ClientID string `gorm:"column:client_id;type:varchar(256);index:uk_oauth2_client_id,unique;not null;comment:client id for oauth2" json:"client_id"` ClientSecret string `gorm:"column:client_secret;type:varchar(1024);not null;comment:client secret for oauth2" json:"client_secret"` RedirectURL string `gorm:"column:redirect_url;type:varchar(1024);comment:authorization callback url" json:"redirect_url"` } ``` ### How an unauthenticated request reaches the OAuth client_secret 1. `gin.Engine` routes `GET /api/v1/oauth/:id` to the `oa` group registered at [`manager/route

Join the discussion

Showing 1 to 1 of 1 result

Filters:Tag: ghsa-4q9j-6299-gxmr
Page 1 of 1
OffSeq TrainingCredly Certified

Lead Pen Test Professional

Technical5-day eLearningPECB Accredited
View courses