GCVE Workshop - 22 September 2026 (14:00-18:00), Luxembourg Before The Vulnopticon Conference - Registration
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."

970 vulnerabilities reference this CWE, most recent first.

GHSA-FP6Q-GCCW-7QQM

Vulnerability from github – Published: 2024-10-22 17:55 – Updated: 2024-10-22 19:22
VLAI
Summary
Umbraco CMS logout page displayed before session expiration
Details

Impact

The Backoffice displays the logout page with a session timeout message before the server session has fully expired, causing users to believe they have been logged out approximately 30 seconds before they actually are.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Umbraco.CMS"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "13.0.0"
            },
            {
              "fixed": "13.5.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Umbraco.CMS"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "10.0.0"
            },
            {
              "fixed": "10.8.7"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "UmbracoCMS"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "8.0.0"
            },
            {
              "fixed": "8.18.15"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2024-48926"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-613"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2024-10-22T17:55:01Z",
    "nvd_published_at": "2024-10-22T16:15:08Z",
    "severity": "MODERATE"
  },
  "details": "### Impact\nThe Backoffice displays the logout page with a session timeout message before the server session has fully expired, causing users to believe they have been logged out approximately 30 seconds before they actually are.\n",
  "id": "GHSA-fp6q-gccw-7qqm",
  "modified": "2024-10-22T19:22:29Z",
  "published": "2024-10-22T17:55:01Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/umbraco/Umbraco-CMS/security/advisories/GHSA-fp6q-gccw-7qqm"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-48926"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/umbraco/Umbraco-CMS"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Umbraco CMS logout page displayed before session expiration"
}

GHSA-FPCR-4RR5-HPCP

Vulnerability from github – Published: 2022-05-24 17:21 – Updated: 2026-02-10 14:16
VLAI
Summary
Mattermost Server vulnerable to user account takeover when Single Sign-On OAuth2 is used
Details

An issue was discovered in Mattermost Server before 4.0.0, 3.10.2, and 3.9.2, when Single Sign-On OAuth2 is used. An attacker could claim somebody else's account.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/mattermost/mattermost-server"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "3.9.2-0.20170714134023-b17fca0d5ee7"
            }
          ],
          "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-18906"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-613"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-02-06T22:42:23Z",
    "nvd_published_at": "2020-06-19T20:15:00Z",
    "severity": "HIGH"
  },
  "details": "An issue was discovered in Mattermost Server before 4.0.0, 3.10.2, and 3.9.2, when Single Sign-On OAuth2 is used. An attacker could claim somebody else\u0027s account.",
  "id": "GHSA-fpcr-4rr5-hpcp",
  "modified": "2026-02-10T14:16:10Z",
  "published": "2022-05-24T17:21:06Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2017-18906"
    },
    {
      "type": "WEB",
      "url": "https://github.com/mattermost/mattermost/commit/259ad46f30d0fac2f7c5c14f3b76b2170f7e90c7"
    },
    {
      "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:L/UI:N/S:U/C:H/I:H/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Mattermost Server vulnerable to user account takeover when Single Sign-On OAuth2 is used"
}

GHSA-FPG4-3688-Q56C

Vulnerability from github – Published: 2024-02-27 03:31 – Updated: 2024-08-16 18:30
VLAI
Details

An issue was discovered in Linksys Router E1700 1.0.04 (build 3), allows authenticated attackers to escalate privileges via a crafted GET request to the /goform/* URI or via the ExportSettings function.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-22543"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-613"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-02-27T01:15:06Z",
    "severity": "MODERATE"
  },
  "details": "An issue was discovered in Linksys Router E1700 1.0.04 (build 3), allows authenticated attackers to escalate privileges via a crafted GET request to the /goform/* URI or via the ExportSettings function.",
  "id": "GHSA-fpg4-3688-q56c",
  "modified": "2024-08-16T18:30:55Z",
  "published": "2024-02-27T03:31:01Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-22543"
    },
    {
      "type": "WEB",
      "url": "https://mat4mee.notion.site/Leaked-SessionID-can-lead-to-authentication-bypass-on-the-Linksys-Router-E1700-f56f9c4b15e7443fa237bd1b101a18d2"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:U/C:H/I:H/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-FPRX-3CV4-96VC

Vulnerability from github – Published: 2024-07-23 09:30 – Updated: 2025-07-10 18:31
VLAI
Details

On versions before 2.1.4, session is not invalidated after logout. When the user logged in successfully, the Backend service returns "Authorization" as the front-end authentication credential. "Authorization" can still initiate requests and access data even after logout.

Mitigation:

all users should upgrade to 2.1.4

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-29070"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-613"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-07-23T09:15:02Z",
    "severity": "CRITICAL"
  },
  "details": "On versions before 2.1.4,\u00a0session is not invalidated after logout. When the user logged in successfully, the Backend service returns \"Authorization\" as the front-end authentication credential. \"Authorization\" can still initiate requests and access data even after logout.\n\nMitigation:\n\nall users should upgrade to 2.1.4",
  "id": "GHSA-fprx-3cv4-96vc",
  "modified": "2025-07-10T18:31:13Z",
  "published": "2024-07-23T09:30:39Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-29070"
    },
    {
      "type": "WEB",
      "url": "https://lists.apache.org/thread/zslblrz1l0n9t67mqdv42yv75ncfn9zl"
    },
    {
      "type": "WEB",
      "url": "http://www.openwall.com/lists/oss-security/2024/07/22/4"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-FPW6-HRG5-Q5X5

Vulnerability from github – Published: 2026-05-07 21:34 – Updated: 2026-07-21 14:37
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-07-21T14:37:24Z",
  "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": []
}

Mitigation
Implementation

Set sessions/credentials expiration date.

No CAPEC attack patterns related to this CWE.