Common Weakness Enumeration

CWE-613

Allowed-with-Review

Insufficient Session Expiration

Abstraction: Base · Status: Incomplete

According to WASC, "Insufficient Session Expiration is when a web site permits an attacker to reuse old session credentials or session IDs for authorization."

876 vulnerabilities reference this CWE, most recent first.

GHSA-FPW6-HRG5-Q5X5

Vulnerability from github – Published: 2026-05-07 21:34 – Updated: 2026-05-07 21:34
VLAI
Summary
ech0's acess tokens with expiry=never cannot be revoked: logout panics, delete does not blacklist JTI
Details

Summary

Access tokens created with the "never expire" option have no exp JWT claim. Three independent revocation mechanisms fail for this token type. Logout at internal/handler/auth/auth.go:154 and :163 dereferences claims.ExpiresAt.Time, panicking on the nil field so the token never hits the blacklist. RevokeToken at internal/repository/auth/auth.go:45-50 skips when remainTTL <= 0. The admin's "Delete token" panel action at internal/service/setting/access_token_service.go:183-185 removes the database record but does not call RevokeToken to blacklist the JTI. Once a never-expire token leaks, the JWT stays cryptographically valid until the admin rotates the signing key across the entire instance.

Details

Creation path at internal/util/jwt/jwt.go:103-105:

// expiry = 0 表示永不过期
if expiry > 0 {
    claims.ExpiresAt = jwt.NewNumericDate(time.Now().UTC().Add(time.Duration(expiry) * time.Second))
}

For NEVER_EXPIRY, expiry = 0 and the conditional skips. The resulting JWT has no exp claim. The middleware at internal/middleware/auth.go accepts it; the jwt/v5 parser does not require exp by default.

Failure mode 1, logout panic at internal/handler/auth/auth.go:163:

// Refresh-token revocation at line 154 (safe in practice: refresh tokens always have exp).
// Access-token revocation, same pattern, at line 163 (the bug):
if claims, err := jwtUtil.ParseToken(authHeader[7:]); err == nil && claims.ID != "" {
    remaining := time.Until(claims.ExpiresAt.Time)  // nil deref when ExpiresAt is nil
    h.authService.RevokeToken(claims.ID, remaining)
}

For a never-expire access token, claims.ExpiresAt is nil. claims.ExpiresAt.Time panics. Gin's Recovery middleware catches it and returns HTTP 500; the JTI never reaches RevokeToken. Line 154 shares the same pattern against refresh tokens, but refresh tokens are always issued with an expiry so the nil dereference does not fire there in practice.

Failure mode 2, RevokeToken skip at internal/repository/auth/auth.go:45-50:

func (authRepository *AuthRepository) RevokeToken(jti string, remainTTL time.Duration) {
    if jti == "" || remainTTL <= 0 {
        return
    }
    authRepository.cache.SetWithTTL(fmt.Sprintf("%s%s", blacklistPrefix, jti), true, 1, remainTTL)
}

Even if the logout path were patched to handle nil ExpiresAt, a caller computing remainTTL = 0 would still skip the blacklist write.

Failure mode 3, admin delete at internal/service/setting/access_token_service.go:183-185:

return settingService.transactor.Run(ctx, func(txCtx context.Context) error {
    return settingService.settingRepository.DeleteAccessTokenByID(txCtx, id)
})

Deletion removes the token's metadata row from the database. No call to RevokeToken, no write to the JTI blacklist. The JWT continues to validate because the signature is still authentic and the middleware does not consult the metadata table.

The only way to invalidate a compromised never-expire token is to rotate JWT_SECRET, which invalidates every token for every user across the whole instance.

Proof of Concept

Default install. Admin creates a never-expire access token; its revocation pathways all fail:

import requests, base64, json
TARGET = "http://localhost:8300"

owner = requests.post(f"{TARGET}/api/login",
                      json={"username": "owner", "password": "owner-pw"}
                     ).json()["data"]["access_token"]

# 1) Create a never-expire access token.
r = requests.post(f"{TARGET}/api/access-tokens",
                  headers={"Authorization": f"Bearer {owner}",
                           "content-type": "application/json"},
                  json={"name": "poc-irrevocable",
                        "expiry": "never",
                        "scopes": ["profile:read"],
                        "audience": "cli"})
tok = r.json()["data"]
pad = lambda s: s + "=" * (-len(s) % 4)
payload = json.loads(base64.urlsafe_b64decode(pad(tok.split(".")[1])))
print(f"  exp claim: {payload.get('exp')}  (None = never expires)")
print(f"  jti: {payload['jti']}")

# 2) Confirm it works.
r = requests.get(f"{TARGET}/api/user", headers={"Authorization": f"Bearer {tok}"})
print(f"  token -> /api/user: HTTP {r.status_code}")

# 3) Failure mode #1 — logout panics on nil ExpiresAt.
r = requests.post(f"{TARGET}/api/auth/logout",
                  headers={"Authorization": f"Bearer {tok}"})
print(f"  logout: HTTP {r.status_code} (500 = Recovery middleware caught the panic)")

# 4) Failure mode #3 — admin delete does not blacklist the JTI.
listed = requests.get(f"{TARGET}/api/access-tokens",
                      headers={"Authorization": f"Bearer {owner}"}).json()["data"]
poc_row = next(t for t in listed if t["name"] == "poc-irrevocable")
r = requests.delete(f"{TARGET}/api/access-tokens/{poc_row['id']}",
                    headers={"Authorization": f"Bearer {owner}"})
print(f"  admin delete: HTTP {r.status_code} {r.text}")

# 5) Token should now be invalid if delete blacklisted. Test it.
r = requests.get(f"{TARGET}/api/user", headers={"Authorization": f"Bearer {tok}"})
print(f"  after delete, token -> /api/user: HTTP {r.status_code}")
print(f"  response body: {r.text[:150]}")

Observed on v4.5.6 in the test container:

exp claim: None  (None = never expires)
jti: 019daf86-6354-7c2d-9ff1-180de87667b3
token -> /api/user: HTTP 200
logout: HTTP 500 (500 = Recovery middleware caught the panic)
admin delete: HTTP 200 {"code":1,"msg":"删除访问令牌成功","data":null}
after delete, token -> /api/user: HTTP 200
response body: {"code":1,"msg":"获取用户信息成功","data":{"id":"019daf76-b5d2-7778-a90a-e943872b2946","username":"owner","email":"owner@test.local","is_admin":true,"is_owner":true,...}}

After the admin "deleted" the token, the same JWT string still returns the owner's profile data. The token stays valid with no path to invalidate it short of rotating JWT_SECRET.

Impact

The "never expire" option is intended for CLI and integration use cases where rotating tokens is expensive. When one of those tokens leaks (configuration file committed to a public repo, developer laptop compromised, log file uploaded by mistake), the admin has no remediation that does not nuke every other user's session.

A compromised token gives the attacker:

  • Perpetual authenticated access at whatever scopes the token holds until the JWT secret is rotated.
  • Admin's "revoke" UI button lies. The token row disappears from the panel but the bearer keeps working. The admin believes they mitigated the incident.
  • Instance-wide blast radius on proper revocation. The only working fix (rotate JWT_SECRET) forces every user to log in again and invalidates every other access token. Security incidents force operators into an all-or-nothing choice.

Precondition: token theft. A stolen token is the standard threat model for any long-lived credential; the point of revocation is that stolen credentials can be invalidated. Ech0 currently has no working path to do that for the "never expire" class.

Recommended Fix

Three coordinated changes, matching the three failure modes:

  1. Replace "never expire" with a very long expiry (for example 10 years) so every token has a finite exp claim. This removes the conditional at jwt.go:103 entirely:
if expiry == model.NEVER_EXPIRY {
    expiry = int64((10 * 365 * 24 * time.Hour).Seconds())
}
claims.ExpiresAt = jwt.NewNumericDate(time.Now().UTC().Add(time.Duration(expiry) * time.Second))
  1. If the "never expire" semantics must be preserved, make logout handle nil ExpiresAt explicitly:
if claims, err := jwtUtil.ParseToken(authHeader[7:]); err == nil && claims.ID != "" {
    var remaining time.Duration
    if claims.ExpiresAt != nil {
        remaining = time.Until(claims.ExpiresAt.Time)
    } else {
        remaining = 365 * 24 * time.Hour
    }
    h.authService.RevokeToken(claims.ID, remaining)
}

And accept non-positive TTLs in RevokeToken by substituting a long default.

  1. Blacklist the JTI when admin deletes an access token:
tok, err := settingService.settingRepository.GetAccessTokenByID(ctx, id)
if err != nil {
    return err
}
if tok.JTI != "" {
    settingService.authRepo.RevokeToken(tok.JTI, 365*24*time.Hour)
}
return settingService.transactor.Run(ctx, func(txCtx context.Context) error {
    return settingService.settingRepository.DeleteAccessTokenByID(txCtx, id)
})

Any two of the three changes close the gap; all three together make the revocation semantics match the admin's mental model.


Found by aisafe.io

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/lin-snow/Ech0"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.4.8-0.20260503041146-eab62379c795"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-613",
      "CWE-755"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-05-07T21:34:01Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "## Summary\n\nAccess tokens created with the \"never expire\" option have no `exp` JWT claim. Three independent revocation mechanisms fail for this token type. Logout at `internal/handler/auth/auth.go:154` and `:163` dereferences `claims.ExpiresAt.Time`, panicking on the nil field so the token never hits the blacklist. `RevokeToken` at `internal/repository/auth/auth.go:45-50` skips when `remainTTL \u003c= 0`. The admin\u0027s \"Delete token\" panel action at `internal/service/setting/access_token_service.go:183-185` removes the database record but does not call `RevokeToken` to blacklist the JTI. Once a never-expire token leaks, the JWT stays cryptographically valid until the admin rotates the signing key across the entire instance.\n\n## Details\n\nCreation path at `internal/util/jwt/jwt.go:103-105`:\n\n```go\n// expiry = 0 \u8868\u793a\u6c38\u4e0d\u8fc7\u671f\nif expiry \u003e 0 {\n    claims.ExpiresAt = jwt.NewNumericDate(time.Now().UTC().Add(time.Duration(expiry) * time.Second))\n}\n```\n\nFor `NEVER_EXPIRY`, `expiry = 0` and the conditional skips. The resulting JWT has no `exp` claim. The middleware at `internal/middleware/auth.go` accepts it; the `jwt/v5` parser does not require `exp` by default.\n\nFailure mode 1, logout panic at `internal/handler/auth/auth.go:163`:\n\n```go\n// Refresh-token revocation at line 154 (safe in practice: refresh tokens always have exp).\n// Access-token revocation, same pattern, at line 163 (the bug):\nif claims, err := jwtUtil.ParseToken(authHeader[7:]); err == nil \u0026\u0026 claims.ID != \"\" {\n    remaining := time.Until(claims.ExpiresAt.Time)  // nil deref when ExpiresAt is nil\n    h.authService.RevokeToken(claims.ID, remaining)\n}\n```\n\nFor a never-expire access token, `claims.ExpiresAt` is nil. `claims.ExpiresAt.Time` panics. Gin\u0027s Recovery middleware catches it and returns HTTP 500; the JTI never reaches `RevokeToken`. Line 154 shares the same pattern against refresh tokens, but refresh tokens are always issued with an expiry so the nil dereference does not fire there in practice.\n\nFailure mode 2, `RevokeToken` skip at `internal/repository/auth/auth.go:45-50`:\n\n```go\nfunc (authRepository *AuthRepository) RevokeToken(jti string, remainTTL time.Duration) {\n    if jti == \"\" || remainTTL \u003c= 0 {\n        return\n    }\n    authRepository.cache.SetWithTTL(fmt.Sprintf(\"%s%s\", blacklistPrefix, jti), true, 1, remainTTL)\n}\n```\n\nEven if the logout path were patched to handle nil `ExpiresAt`, a caller computing `remainTTL = 0` would still skip the blacklist write.\n\nFailure mode 3, admin delete at `internal/service/setting/access_token_service.go:183-185`:\n\n```go\nreturn settingService.transactor.Run(ctx, func(txCtx context.Context) error {\n    return settingService.settingRepository.DeleteAccessTokenByID(txCtx, id)\n})\n```\n\nDeletion removes the token\u0027s metadata row from the database. No call to `RevokeToken`, no write to the JTI blacklist. The JWT continues to validate because the signature is still authentic and the middleware does not consult the metadata table.\n\nThe only way to invalidate a compromised never-expire token is to rotate `JWT_SECRET`, which invalidates every token for every user across the whole instance.\n\n## Proof of Concept\n\nDefault install. Admin creates a never-expire access token; its revocation pathways all fail:\n\n```python\nimport requests, base64, json\nTARGET = \"http://localhost:8300\"\n\nowner = requests.post(f\"{TARGET}/api/login\",\n                      json={\"username\": \"owner\", \"password\": \"owner-pw\"}\n                     ).json()[\"data\"][\"access_token\"]\n\n# 1) Create a never-expire access token.\nr = requests.post(f\"{TARGET}/api/access-tokens\",\n                  headers={\"Authorization\": f\"Bearer {owner}\",\n                           \"content-type\": \"application/json\"},\n                  json={\"name\": \"poc-irrevocable\",\n                        \"expiry\": \"never\",\n                        \"scopes\": [\"profile:read\"],\n                        \"audience\": \"cli\"})\ntok = r.json()[\"data\"]\npad = lambda s: s + \"=\" * (-len(s) % 4)\npayload = json.loads(base64.urlsafe_b64decode(pad(tok.split(\".\")[1])))\nprint(f\"  exp claim: {payload.get(\u0027exp\u0027)}  (None = never expires)\")\nprint(f\"  jti: {payload[\u0027jti\u0027]}\")\n\n# 2) Confirm it works.\nr = requests.get(f\"{TARGET}/api/user\", headers={\"Authorization\": f\"Bearer {tok}\"})\nprint(f\"  token -\u003e /api/user: HTTP {r.status_code}\")\n\n# 3) Failure mode #1 \u2014 logout panics on nil ExpiresAt.\nr = requests.post(f\"{TARGET}/api/auth/logout\",\n                  headers={\"Authorization\": f\"Bearer {tok}\"})\nprint(f\"  logout: HTTP {r.status_code} (500 = Recovery middleware caught the panic)\")\n\n# 4) Failure mode #3 \u2014 admin delete does not blacklist the JTI.\nlisted = requests.get(f\"{TARGET}/api/access-tokens\",\n                      headers={\"Authorization\": f\"Bearer {owner}\"}).json()[\"data\"]\npoc_row = next(t for t in listed if t[\"name\"] == \"poc-irrevocable\")\nr = requests.delete(f\"{TARGET}/api/access-tokens/{poc_row[\u0027id\u0027]}\",\n                    headers={\"Authorization\": f\"Bearer {owner}\"})\nprint(f\"  admin delete: HTTP {r.status_code} {r.text}\")\n\n# 5) Token should now be invalid if delete blacklisted. Test it.\nr = requests.get(f\"{TARGET}/api/user\", headers={\"Authorization\": f\"Bearer {tok}\"})\nprint(f\"  after delete, token -\u003e /api/user: HTTP {r.status_code}\")\nprint(f\"  response body: {r.text[:150]}\")\n```\n\nObserved on v4.5.6 in the test container:\n\n```\nexp claim: None  (None = never expires)\njti: 019daf86-6354-7c2d-9ff1-180de87667b3\ntoken -\u003e /api/user: HTTP 200\nlogout: HTTP 500 (500 = Recovery middleware caught the panic)\nadmin delete: HTTP 200 {\"code\":1,\"msg\":\"\u5220\u9664\u8bbf\u95ee\u4ee4\u724c\u6210\u529f\",\"data\":null}\nafter delete, token -\u003e /api/user: HTTP 200\nresponse body: {\"code\":1,\"msg\":\"\u83b7\u53d6\u7528\u6237\u4fe1\u606f\u6210\u529f\",\"data\":{\"id\":\"019daf76-b5d2-7778-a90a-e943872b2946\",\"username\":\"owner\",\"email\":\"owner@test.local\",\"is_admin\":true,\"is_owner\":true,...}}\n```\n\nAfter the admin \"deleted\" the token, the same JWT string still returns the owner\u0027s profile data. The token stays valid with no path to invalidate it short of rotating `JWT_SECRET`.\n\n## Impact\n\nThe \"never expire\" option is intended for CLI and integration use cases where rotating tokens is expensive. When one of those tokens leaks (configuration file committed to a public repo, developer laptop compromised, log file uploaded by mistake), the admin has no remediation that does not nuke every other user\u0027s session.\n\nA compromised token gives the attacker:\n\n- **Perpetual authenticated access** at whatever scopes the token holds until the JWT secret is rotated.\n- **Admin\u0027s \"revoke\" UI button lies.** The token row disappears from the panel but the bearer keeps working. The admin believes they mitigated the incident.\n- **Instance-wide blast radius on proper revocation.** The only working fix (rotate JWT_SECRET) forces every user to log in again and invalidates every other access token. Security incidents force operators into an all-or-nothing choice.\n\nPrecondition: token theft. A stolen token is the standard threat model for any long-lived credential; the point of revocation is that stolen credentials can be invalidated. Ech0 currently has no working path to do that for the \"never expire\" class.\n\n## Recommended Fix\n\nThree coordinated changes, matching the three failure modes:\n\n1. Replace \"never expire\" with a very long expiry (for example 10 years) so every token has a finite `exp` claim. This removes the conditional at `jwt.go:103` entirely:\n\n```go\nif expiry == model.NEVER_EXPIRY {\n    expiry = int64((10 * 365 * 24 * time.Hour).Seconds())\n}\nclaims.ExpiresAt = jwt.NewNumericDate(time.Now().UTC().Add(time.Duration(expiry) * time.Second))\n```\n\n2. If the \"never expire\" semantics must be preserved, make logout handle nil `ExpiresAt` explicitly:\n\n```go\nif claims, err := jwtUtil.ParseToken(authHeader[7:]); err == nil \u0026\u0026 claims.ID != \"\" {\n    var remaining time.Duration\n    if claims.ExpiresAt != nil {\n        remaining = time.Until(claims.ExpiresAt.Time)\n    } else {\n        remaining = 365 * 24 * time.Hour\n    }\n    h.authService.RevokeToken(claims.ID, remaining)\n}\n```\n\nAnd accept non-positive TTLs in `RevokeToken` by substituting a long default.\n\n3. Blacklist the JTI when admin deletes an access token:\n\n```go\ntok, err := settingService.settingRepository.GetAccessTokenByID(ctx, id)\nif err != nil {\n    return err\n}\nif tok.JTI != \"\" {\n    settingService.authRepo.RevokeToken(tok.JTI, 365*24*time.Hour)\n}\nreturn settingService.transactor.Run(ctx, func(txCtx context.Context) error {\n    return settingService.settingRepository.DeleteAccessTokenByID(txCtx, id)\n})\n```\n\nAny two of the three changes close the gap; all three together make the revocation semantics match the admin\u0027s mental model.\n\n---\n*Found by [aisafe.io](https://aisafe.io)*",
  "id": "GHSA-fpw6-hrg5-q5x5",
  "modified": "2026-05-07T21:34:01Z",
  "published": "2026-05-07T21:34:01Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/lin-snow/Ech0/security/advisories/GHSA-fpw6-hrg5-q5x5"
    },
    {
      "type": "WEB",
      "url": "https://github.com/lin-snow/Ech0/commit/eab62379c795c3f4850a9ca938ae3f27d7171541"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/lin-snow/Ech0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "ech0\u0027s acess tokens with expiry=never cannot be revoked: logout panics, delete does not blacklist JTI"
}

GHSA-FQFW-5JC9-HW27

Vulnerability from github – Published: 2025-04-14 09:30 – Updated: 2025-06-04 00:30
VLAI
Details

A session management vulnerability exists in Apache Roller before version 6.1.5 where active user sessions are not properly invalidated after password changes. When a user's password is changed, either by the user themselves or by an administrator, existing sessions remain active and usable. This allows continued access to the application through old sessions even after password changes, potentially enabling unauthorized access if credentials were compromised.

This issue affects Apache Roller versions up to and including 6.1.4.

The vulnerability is fixed in Apache Roller 6.1.5 by implementing centralized session management that properly invalidates all active sessions when passwords are changed or users are disabled.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-24859"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-613"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-04-14T09:15:14Z",
    "severity": "CRITICAL"
  },
  "details": "A session management vulnerability exists in Apache Roller before version 6.1.5 where active user sessions are not properly invalidated after password changes. When a user\u0027s password is changed, either by the user themselves or by an administrator, existing sessions remain active and usable. This allows continued access to the application through old sessions even after password changes, potentially enabling unauthorized access if credentials were compromised.\n\nThis issue affects Apache Roller versions up to and including 6.1.4.\n\nThe vulnerability is fixed in Apache Roller 6.1.5 by implementing centralized session management that properly invalidates all active sessions when passwords are changed or users are disabled.",
  "id": "GHSA-fqfw-5jc9-hw27",
  "modified": "2025-06-04T00:30:25Z",
  "published": "2025-04-14T09:30:24Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-24859"
    },
    {
      "type": "WEB",
      "url": "https://lists.apache.org/thread/4j906k16v21kdx8hk87gl7663sw7lg7f"
    },
    {
      "type": "WEB",
      "url": "https://lists.apache.org/thread/vxv52vdr8nhtjlj6v02w43fdvo0cxw23"
    },
    {
      "type": "WEB",
      "url": "http://www.openwall.com/lists/oss-security/2025/04/11/1"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/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:H/SI:H/SA:H/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-FWHC-9G43-HMCM

Vulnerability from github – Published: 2024-04-17 00:30 – Updated: 2024-11-07 18:31
VLAI
Details

cskefu v7 suffers from Insufficient Session Expiration, which allows attackers to exploit the old session for malicious activity.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-29402"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-613"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-04-16T23:15:08Z",
    "severity": "MODERATE"
  },
  "details": "cskefu v7 suffers from Insufficient Session Expiration, which allows attackers to exploit the old session for malicious activity.",
  "id": "GHSA-fwhc-9g43-hmcm",
  "modified": "2024-11-07T18:31:20Z",
  "published": "2024-04-17T00:30:57Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-29402"
    },
    {
      "type": "WEB",
      "url": "https://github.com/cskefu/cskefu/issues/781"
    },
    {
      "type": "WEB",
      "url": "https://github.com/cskefu/cskefu/pull/803"
    },
    {
      "type": "WEB",
      "url": "https://gist.github.com/menghaining/8d424faebfe869c80eadaea12bbdd158"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-FWQ2-5P9G-FM29

Vulnerability from github – Published: 2026-04-22 12:30 – Updated: 2026-04-22 12:30
VLAI
Details

A flaw was found in Red Hat Quay. When Red Hat Quay requests password re-verification for sensitive operations, such as token generation or robot account creation, the re-authentication prompt can be bypassed. This allows a user with a timed-out session, or an attacker with access to an idle authenticated browser session, to perform privileged actions without providing valid credentials. The vulnerability enables unauthorized execution of sensitive operations despite the user interface displaying an error for invalid credentials.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-6848"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-613"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-04-22T10:16:52Z",
    "severity": "MODERATE"
  },
  "details": "A flaw was found in Red Hat Quay. When Red Hat Quay requests password re-verification for sensitive operations, such as token generation or robot account creation, the re-authentication prompt can be bypassed. This allows a user with a timed-out session, or an attacker with access to an idle authenticated browser session, to perform privileged actions without providing valid credentials. The vulnerability enables unauthorized execution of sensitive operations despite the user interface displaying an error for invalid credentials.",
  "id": "GHSA-fwq2-5p9g-fm29",
  "modified": "2026-04-22T12:30:30Z",
  "published": "2026-04-22T12:30:30Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-6848"
    },
    {
      "type": "WEB",
      "url": "https://access.redhat.com/security/cve/CVE-2026-6848"
    },
    {
      "type": "WEB",
      "url": "https://bugzilla.redhat.com/show_bug.cgi?id=2460119"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-G24C-FX4V-XG9W

Vulnerability from github – Published: 2022-05-24 17:21 – Updated: 2026-01-12 20:18
VLAI
Summary
Mattermost Server has Insufficient Session Expiration when used as an OAuth 2.0 service provider
Details

An issue was discovered in Mattermost Server before 4.0.0, 3.10.2, and 3.9.2, when used as an OAuth 2.0 service provider, Session invalidation was mishandled.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/mattermost/mattermost-server"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "3.9.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/mattermost/mattermost-server"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "3.10.0"
            },
            {
              "fixed": "3.10.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2017-18905"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-613"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-01-12T20:18:44Z",
    "nvd_published_at": "2020-06-19T20:15:00Z",
    "severity": "MODERATE"
  },
  "details": "An issue was discovered in Mattermost Server before 4.0.0, 3.10.2, and 3.9.2, when used as an OAuth 2.0 service provider, Session invalidation was mishandled.",
  "id": "GHSA-g24c-fx4v-xg9w",
  "modified": "2026-01-12T20:18:44Z",
  "published": "2022-05-24T17:21:06Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2017-18905"
    },
    {
      "type": "WEB",
      "url": "https://github.com/mattermost/mattermost/commit/15ad24d160cb4604d0605ebbfa53d11a57820706"
    },
    {
      "type": "WEB",
      "url": "https://github.com/mattermost/mattermost/commit/b17fca0d5ee7557e3df1cf1d1da8bd749859e35f"
    },
    {
      "type": "WEB",
      "url": "https://github.com/mattermost/mattermost/commit/fbc170733e86f09b46ba754dd03304733d2f482f"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/mattermost/mattermost"
    },
    {
      "type": "WEB",
      "url": "https://mattermost.com/security-updates"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Mattermost Server has Insufficient Session Expiration when used as an OAuth 2.0 service provider"
}

GHSA-G28X-633F-R8QF

Vulnerability from github – Published: 2022-01-19 00:01 – Updated: 2022-01-25 00:02
VLAI
Details

Mattermost Boards plugin v0.10.0 and earlier fails to invalidate a session on the server-side when a user logged out of Boards, which allows an attacker to reuse old session token for authorization.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2021-37866"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-613"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2022-01-18T17:15:00Z",
    "severity": "HIGH"
  },
  "details": "Mattermost Boards plugin v0.10.0 and earlier fails to invalidate a session on the server-side when a user logged out of Boards, which allows an attacker to reuse old session token for authorization.",
  "id": "GHSA-g28x-633f-r8qf",
  "modified": "2022-01-25T00:02:23Z",
  "published": "2022-01-19T00:01:09Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-37866"
    },
    {
      "type": "WEB",
      "url": "https://mattermost.com/security-updates"
    },
    {
      "type": "WEB",
      "url": "https://www.whitesourcesoftware.com/vulnerability-database/CVE-2021-37866"
    }
  ],
  "schema_version": "1.4.0",
  "severity": []
}

GHSA-G39J-8M48-QWGJ

Vulnerability from github – Published: 2022-05-24 17:49 – Updated: 2022-10-22 12:00
VLAI
Details

A vulnerability in the SIP inspection engine of Cisco Adaptive Security Appliance (ASA) Software and Cisco Firepower Threat Defense (FTD) Software could allow an unauthenticated, remote attacker to cause a crash and reload of an affected device, resulting in a denial of service (DoS) condition.The vulnerability is due to a crash that occurs during a hash lookup for a SIP pinhole connection. An attacker could exploit this vulnerability by sending crafted SIP traffic through an affected device. A successful exploit could allow the attacker to cause a crash and reload of the affected device.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2021-1501"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-613"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2021-04-29T18:15:00Z",
    "severity": "HIGH"
  },
  "details": "A vulnerability in the SIP inspection engine of Cisco Adaptive Security Appliance (ASA) Software and Cisco Firepower Threat Defense (FTD) Software could allow an unauthenticated, remote attacker to cause a crash and reload of an affected device, resulting in a denial of service (DoS) condition.The vulnerability is due to a crash that occurs during a hash lookup for a SIP pinhole connection. An attacker could exploit this vulnerability by sending crafted SIP traffic through an affected device. A successful exploit could allow the attacker to cause a crash and reload of the affected device.",
  "id": "GHSA-g39j-8m48-qwgj",
  "modified": "2022-10-22T12:00:30Z",
  "published": "2022-05-24T17:49:08Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-1501"
    },
    {
      "type": "WEB",
      "url": "https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-asa-ftd-sipdos-GGwmMerC"
    }
  ],
  "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"
    }
  ]
}

GHSA-G4R8-MP7G-85FQ

Vulnerability from github – Published: 2025-05-06 16:51 – Updated: 2025-05-06 19:57
VLAI
Summary
ZITADEL Allows IdP Intent Token Reuse
Details

Impact

ZITADEL offers developers the ability to manage user sessions using the Session API. This API enables the use of IdPs for authentication, known as idp intents.

Following a successful idp intent, the client receives an id and token on a predefined URI. These id and token can then be used to authenticate the user or their session.

However, it was possible to exploit this feature by repeatedly using intents. This allowed an attacker with access to the application’s URI to retrieve the id and token, enabling them to authenticate on behalf of the user.

It’s important to note that the use of additional factors (MFA) prevents a complete authentication process and, consequently, access to the ZITADEL API.

Patches

3.x versions are fixed on >=3.0.0 2.71.x versions are fixed on >=2.71.9 2.x versions are fixed on >=2.70.10

Workarounds

The recommended solution is to update ZITADEL to a patched version.

Questions

If you have any questions or comments about this advisory, please email us at security@zitadel.com

Credits

Thanks to Józef Chraplewski from Nedap for reporting this vulnerability.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 3.0.0-rc.3"
      },
      "package": {
        "ecosystem": "Go",
        "name": "github.com/zitadel/zitadel"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "3.0.0-rc.1"
            },
            {
              "fixed": "3.0.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/zitadel/zitadel"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2.70.10"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 2.71.8"
      },
      "package": {
        "ecosystem": "Go",
        "name": "github.com/zitadel/zitadel"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.71.0"
            },
            {
              "fixed": "2.71.9"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2025-46815"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-294",
      "CWE-384",
      "CWE-613"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2025-05-06T16:51:16Z",
    "nvd_published_at": "2025-05-06T18:15:38Z",
    "severity": "HIGH"
  },
  "details": "### Impact\n\nZITADEL offers developers the ability to manage user sessions using the [Session API](https://zitadel.com/docs/category/apis/resources/session_service_v2/session-service). This API enables the use of IdPs for authentication, known as idp intents.\n\nFollowing a successful idp intent, the client receives an id and token on a predefined URI. These id and token can then be used to authenticate the user or their session.\n\nHowever, it was possible to exploit this feature by repeatedly using intents. This allowed an attacker with access to the application\u2019s URI to retrieve the id and token, enabling them to authenticate on behalf of the user.\n\nIt\u2019s important to note that the use of additional factors (MFA) prevents a complete authentication process and, consequently, access to the ZITADEL API.\n\n### Patches\n\n3.x versions are fixed on \u003e=[3.0.0](https://github.com/zitadel/zitadel/releases/tag/v3.0.0)\n2.71.x versions are fixed on \u003e=[2.71.9](https://github.com/zitadel/zitadel/releases/tag/v2.71.9)\n2.x versions are fixed on \u003e=[2.70.10](https://github.com/zitadel/zitadel/releases/tag/v2.70.10)\n\n### Workarounds\n\nThe recommended solution is to update ZITADEL to a patched version.\n\n### Questions\n\nIf you have any questions or comments about this advisory, please email us at [security@zitadel.com](mailto:security@zitadel.com)\n\n### Credits\n\nThanks to J\u00f3zef Chraplewski from Nedap for reporting this vulnerability.",
  "id": "GHSA-g4r8-mp7g-85fq",
  "modified": "2025-05-06T19:57:17Z",
  "published": "2025-05-06T16:51:16Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/zitadel/zitadel/security/advisories/GHSA-g4r8-mp7g-85fq"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-46815"
    },
    {
      "type": "WEB",
      "url": "https://github.com/zitadel/zitadel/commit/b1e60e7398d677f08b06fd7715227f70b7ca1162"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/zitadel/zitadel"
    },
    {
      "type": "WEB",
      "url": "https://github.com/zitadel/zitadel/releases/tag/v2.70.10"
    },
    {
      "type": "WEB",
      "url": "https://github.com/zitadel/zitadel/releases/tag/v2.71.9"
    },
    {
      "type": "WEB",
      "url": "https://github.com/zitadel/zitadel/releases/tag/v3.0.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "ZITADEL Allows IdP Intent Token Reuse"
}

GHSA-G4X6-JCVR-9M3G

Vulnerability from github – Published: 2026-07-14 20:26 – Updated: 2026-07-14 20:26
VLAI
Summary
nebula-mesh: Web UI host creation ignores configured enrollment token TTL and mints 24-hour bearer enrollment tokens
Details

Summary

The nebula-mgmt Web UI host-creation path ignores both the server-wide enrollment_token_ttl security setting and per-network network_config.enrollment_token_ttl overrides. API host creation and token-regeneration paths use the configured TTL resolver, but POST /ui/hosts hardcodes now.Add(24 * time.Hour) for newly minted agent enrollment tokens. In deployments that intentionally reduce enrollment-token lifetime, any authenticated operator who can create a host through the Web UI can still mint a bearer enrollment token valid for about 24 hours.

Details

Enrollment tokens are bearer credentials for the public POST /api/v1/enroll endpoint: possession of a valid token allows enrolling the pending host and receiving a signed Nebula certificate/config for that host. The server configuration documents a security knob for their default lifetime and per-network overrides:

  • internal/config/server.go:82 defines EnrollmentTokenTTL as the default lifetime for freshly minted enrollment tokens.
  • internal/config/server.go:83 documents per-network overrides in network_config under enrollment_token_ttl.

The API server implements and consistently uses this resolver:

  • internal/api/server.go:77 defines tokenTTLFor, with precedence of per-network enrollment_token_ttl, then server default, then 24h fallback.
  • internal/api/server.go:82 reads network_config.enrollment_token_ttl.
  • internal/api/server.go:89 falls back to the configured server default.
  • internal/api/hosts.go:190 through internal/api/hosts.go:196 use now.Add(s.tokenTTLFor(r.Context(), host.NetworkID)) for API host creation.

The Web UI sibling path does not call the resolver and instead always sets a 24-hour expiry:

  • internal/web/handlers.go:874 mints the raw token for POST /ui/hosts.
  • internal/web/handlers.go:879 sets ExpiresAt: now.Add(24 * time.Hour).

This creates inconsistent behavior between API and Web UI host creation and bypasses an operator-configured token lifetime policy. The issue is reachable by an authenticated Web UI operator who can create hosts. Admins can create hosts in any network; non-admin operators can create hosts in networks whose CA they own.

Affected version evidence: the configurable enrollment-token TTL feature was introduced by commit 6c344a6 (feat(api): configurable enrollment-token TTL + regenerate endpoint (#75) (#79)), and git tag --contains 6c344a6 --sort=version:refname returns v0.3.0 through v0.3.8. Pattern checks across all release tags showed the TTL config/API resolver and the Web UI 24-hour hardcode are present in every v0.3.x release from v0.3.0 to v0.3.8, and are not meaningfully applicable to v0.1.x/v0.2.0 because the TTL policy knob was not present there. The current checkout at commit d92dd9a60de291e2bc1caf73b4e9a99567b31ec0 (git describe: v0.3.8-1-gd92dd9a) remains affected.

PoC

Safe local PoC run from a clean checkout at commit d92dd9a60de291e2bc1caf73b4e9a99567b31ec0 on 2026-06-12. The PoC is a temporary Go test that uses only in-memory SQLite and httptest; it does not start a real server and does not contact external services.

  1. Create a temporary test file internal/web/security_audit_poc_test.go in package web.
  2. In the test, create an in-memory Web UI with newTestWeb(t), create a network audit-poc-net with CIDR 10.77.0.0/24, and set network_config.enrollment_token_ttl to 30m.
  3. Log in as the seeded test admin through the normal Web UI helper and obtain a CSRF token from GET /ui/hosts/new.
  4. Submit POST /ui/hosts with network_id=audit-poc-net, name=audit-poc-host, nebula_ips=10.77.0.10, role=host, and kind=agent.
  5. Parse the one-shot enrollment token from the returned host-detail page and read the token row with GetEnrollmentToken.
  6. Compare the observed expiry to the configured 30-minute network override.

Command run:

go test ./internal/web -run 'TestSecurityAuditPOC' -count=1 -v

Observed vulnerable output from this environment:

=== RUN   TestSecurityAuditPOC_UIHostCreateIgnoresNetworkEnrollmentTokenTTL
POC_UI_TTL_BYPASS observed_token_ttl=24h0m0s configured_network_ttl=30m expires_at=2026-06-13T14:51:45Z
--- PASS: TestSecurityAuditPOC_UIHostCreateIgnoresNetworkEnrollmentTokenTTL (0.05s)

The meaningful control is the API sibling: internal/api/hosts.go:190 through internal/api/hosts.go:196 uses s.tokenTTLFor(...), and existing tests in internal/api/hosts_token_ttl_test.go verify API-created/regenerated enrollment tokens honor server-default and per-network TTLs. Variant review also found API regenerate-token, API re-enroll, and signed-poll rekey token minting use the resolver rather than a hardcoded 24h value. After recording the output, the temporary test file was removed and git status --short returned clean. The PoC was re-run after drafting this report and produced the output shown above.

Impact

An authenticated Web UI operator can bypass a configured enrollment-token lifetime policy and obtain a token valid for approximately 24 hours even when the deployment or network is configured for a much shorter lifetime such as 30 minutes. Because enrollment tokens are bearer credentials for the public enrollment endpoint, longer-than-intended validity increases the window in which a copied, logged, shared, or otherwise exposed token can be used to enroll the pending host and obtain its Nebula certificate/config. This weakens confidentiality and integrity for deployments relying on short token lifetimes to reduce enrollment-token exposure.

Suggested remediation: refactor the Web UI host-creation path to use the same TTL resolution as the API path, or move the resolver into a shared package/service used by both API and Web UI. Add a regression test under internal/web that sets network_config.enrollment_token_ttl = "30m", creates an agent host through POST /ui/hosts, and asserts the persisted enrollment token expires within the configured 30-minute window rather than 24 hours.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/forgekeep/nebula-mesh"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0.3.0"
            },
            {
              "fixed": "0.5.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-55513"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-613"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-07-14T20:26:21Z",
    "nvd_published_at": null,
    "severity": "MODERATE"
  },
  "details": "### Summary\nThe `nebula-mgmt` Web UI host-creation path ignores both the server-wide `enrollment_token_ttl` security setting and per-network `network_config.enrollment_token_ttl` overrides. API host creation and token-regeneration paths use the configured TTL resolver, but `POST /ui/hosts` hardcodes `now.Add(24 * time.Hour)` for newly minted agent enrollment tokens. In deployments that intentionally reduce enrollment-token lifetime, any authenticated operator who can create a host through the Web UI can still mint a bearer enrollment token valid for about 24 hours.\n\n### Details\nEnrollment tokens are bearer credentials for the public `POST /api/v1/enroll` endpoint: possession of a valid token allows enrolling the pending host and receiving a signed Nebula certificate/config for that host. The server configuration documents a security knob for their default lifetime and per-network overrides:\n\n- `internal/config/server.go:82` defines `EnrollmentTokenTTL` as the default lifetime for freshly minted enrollment tokens.\n- `internal/config/server.go:83` documents per-network overrides in `network_config` under `enrollment_token_ttl`.\n\nThe API server implements and consistently uses this resolver:\n\n- `internal/api/server.go:77` defines `tokenTTLFor`, with precedence of per-network `enrollment_token_ttl`, then server default, then 24h fallback.\n- `internal/api/server.go:82` reads `network_config.enrollment_token_ttl`.\n- `internal/api/server.go:89` falls back to the configured server default.\n- `internal/api/hosts.go:190` through `internal/api/hosts.go:196` use `now.Add(s.tokenTTLFor(r.Context(), host.NetworkID))` for API host creation.\n\nThe Web UI sibling path does not call the resolver and instead always sets a 24-hour expiry:\n\n- `internal/web/handlers.go:874` mints the raw token for `POST /ui/hosts`.\n- `internal/web/handlers.go:879` sets `ExpiresAt: now.Add(24 * time.Hour)`.\n\nThis creates inconsistent behavior between API and Web UI host creation and bypasses an operator-configured token lifetime policy. The issue is reachable by an authenticated Web UI operator who can create hosts. Admins can create hosts in any network; non-admin operators can create hosts in networks whose CA they own.\n\nAffected version evidence: the configurable enrollment-token TTL feature was introduced by commit `6c344a6` (`feat(api): configurable enrollment-token TTL + regenerate endpoint (#75) (#79)`), and `git tag --contains 6c344a6 --sort=version:refname` returns `v0.3.0` through `v0.3.8`. Pattern checks across all release tags showed the TTL config/API resolver and the Web UI 24-hour hardcode are present in every `v0.3.x` release from `v0.3.0` to `v0.3.8`, and are not meaningfully applicable to `v0.1.x`/`v0.2.0` because the TTL policy knob was not present there. The current checkout at commit `d92dd9a60de291e2bc1caf73b4e9a99567b31ec0` (`git describe`: `v0.3.8-1-gd92dd9a`) remains affected.\n\n### PoC\nSafe local PoC run from a clean checkout at commit `d92dd9a60de291e2bc1caf73b4e9a99567b31ec0` on 2026-06-12. The PoC is a temporary Go test that uses only in-memory SQLite and `httptest`; it does not start a real server and does not contact external services.\n\n1. Create a temporary test file `internal/web/security_audit_poc_test.go` in package `web`.\n2. In the test, create an in-memory Web UI with `newTestWeb(t)`, create a network `audit-poc-net` with CIDR `10.77.0.0/24`, and set `network_config.enrollment_token_ttl` to `30m`.\n3. Log in as the seeded test admin through the normal Web UI helper and obtain a CSRF token from `GET /ui/hosts/new`.\n4. Submit `POST /ui/hosts` with `network_id=audit-poc-net`, `name=audit-poc-host`, `nebula_ips=10.77.0.10`, `role=host`, and `kind=agent`.\n5. Parse the one-shot enrollment token from the returned host-detail page and read the token row with `GetEnrollmentToken`.\n6. Compare the observed expiry to the configured 30-minute network override.\n\nCommand run:\n\n```bash\ngo test ./internal/web -run \u0027TestSecurityAuditPOC\u0027 -count=1 -v\n```\n\nObserved vulnerable output from this environment:\n\n```text\n=== RUN   TestSecurityAuditPOC_UIHostCreateIgnoresNetworkEnrollmentTokenTTL\nPOC_UI_TTL_BYPASS observed_token_ttl=24h0m0s configured_network_ttl=30m expires_at=2026-06-13T14:51:45Z\n--- PASS: TestSecurityAuditPOC_UIHostCreateIgnoresNetworkEnrollmentTokenTTL (0.05s)\n```\n\nThe meaningful control is the API sibling: `internal/api/hosts.go:190` through `internal/api/hosts.go:196` uses `s.tokenTTLFor(...)`, and existing tests in `internal/api/hosts_token_ttl_test.go` verify API-created/regenerated enrollment tokens honor server-default and per-network TTLs. Variant review also found API regenerate-token, API re-enroll, and signed-poll rekey token minting use the resolver rather than a hardcoded 24h value. After recording the output, the temporary test file was removed and `git status --short` returned clean. The PoC was re-run after drafting this report and produced the output shown above.\n\n### Impact\nAn authenticated Web UI operator can bypass a configured enrollment-token lifetime policy and obtain a token valid for approximately 24 hours even when the deployment or network is configured for a much shorter lifetime such as 30 minutes. Because enrollment tokens are bearer credentials for the public enrollment endpoint, longer-than-intended validity increases the window in which a copied, logged, shared, or otherwise exposed token can be used to enroll the pending host and obtain its Nebula certificate/config. This weakens confidentiality and integrity for deployments relying on short token lifetimes to reduce enrollment-token exposure.\n\nSuggested remediation: refactor the Web UI host-creation path to use the same TTL resolution as the API path, or move the resolver into a shared package/service used by both API and Web UI. Add a regression test under `internal/web` that sets `network_config.enrollment_token_ttl = \"30m\"`, creates an agent host through `POST /ui/hosts`, and asserts the persisted enrollment token expires within the configured 30-minute window rather than 24 hours.",
  "id": "GHSA-g4x6-jcvr-9m3g",
  "modified": "2026-07-14T20:26:21Z",
  "published": "2026-07-14T20:26:21Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/forgekeep/nebula-mesh/security/advisories/GHSA-g4x6-jcvr-9m3g"
    },
    {
      "type": "WEB",
      "url": "https://github.com/forgekeep/nebula-mesh/commit/514006029e09f1991122b86a80e7b25970bcfa98"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/forgekeep/nebula-mesh"
    },
    {
      "type": "WEB",
      "url": "https://github.com/forgekeep/nebula-mesh/releases/tag/v0.5.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "nebula-mesh: Web UI host creation ignores configured enrollment token TTL and mints 24-hour bearer enrollment tokens"
}

GHSA-G5RH-53CQ-PX9W

Vulnerability from github – Published: 2026-05-21 15:34 – Updated: 2026-05-21 15:34
VLAI
Details

Insufficient session expiration vulnerability in Turkiye Electricity Transmission Corporation (TEİAŞ) Mobile Application allows Session Hijacking.

This issue affects Mobile Application: from 1.6.2 before 1.13.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-1815"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-613"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-05-21T15:16:22Z",
    "severity": "MODERATE"
  },
  "details": "Insufficient session expiration vulnerability in Turkiye Electricity Transmission Corporation (TE\u0130A\u015e) Mobile Application allows Session Hijacking.\n\nThis issue affects Mobile Application: from 1.6.2 before 1.13.",
  "id": "GHSA-g5rh-53cq-px9w",
  "modified": "2026-05-21T15:34:09Z",
  "published": "2026-05-21T15:34:09Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-1815"
    },
    {
      "type": "WEB",
      "url": "https://siberguvenlik.gov.tr/guvenlik-bildirimleri/detay/tr-26-0286"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

Mitigation
Implementation

Set sessions/credentials expiration date.

No CAPEC attack patterns related to this CWE.