nebari-dev / nebari-dev/data-science-pack
Security(M-03): missing role-filter state falls back to mounting every group in the token
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 5
- Forks
- 7
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 13
Description
Summary
When role-based mount filtering is unavailable, the shared-storage resolver falls back to the user's full groups claim. The static allowlist is empty by default, so every group the user holds becomes a writable shared mount. This turns ordinary realm group membership into shared-storage authorization on any deployment where the RBAC bootstrap is off or partially configured.
Severity: Medium · CWE-863 (Incorrect Authorization)
Validation: Confirmed against HEAD f932d80 on 2026-07-14 (assessed at 69c84f7; unchanged since).
Evidence
config/jupyterhub/01-spawner.py:794-806: usesgroups_with_permission_to_mountwhen the key is present, otherwiseraw_groups = auth_state.get("groups", [])(the full claim).config/jupyterhub/01-spawner.py:810-812: the allowlist only filters when it is non-empty; an empty list is falsy and skips filtering entirely.- Default allowlist is empty:
01-spawner.py:147readscustom.shared-storage-groupsdefaulting to[], andvalues.yaml:471setsshared-storage-groups: []. - Documented as legacy:
values.yaml:491-495states that with RBAC off the spawner "falls back to mounting every group the user is in (legacy behaviour)." - Corroboration:
00-gateway-auth.py:434returns early without settinggroups_with_permission_to_mountwhenrealm_api_urlis unset, so the key is genuinely absent when RBAC is off.
Impact
In nonstandard, disabled-bootstrap, or partially configured deployments, any realm group a user belongs to becomes a writable shared mount, with no explicit approval step.
Remediation
- Make the authorization mode explicit.
- In production, treat missing role-filter state as zero mounts.
- Require a non-empty approved mapping.
- Put the legacy full-
groupsbehavior behind an explicit unsafe-dev flag.
Acceptance criteria
- Absent, malformed, or unavailable role-filter data yields no shared mounts and a visible readiness/status error.
Source: data-science-pack 0.1.0 security assessment (pinned commit 69c84f72df259ec755ed40bfc83f20158c550d55), finding M-03.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read config/jupyterhub/01-spawner.py:794-812 and config/jupyterhub/01-spawner.py:147, then inspect config/jupyterhub/00-gateway-auth.py:434 and values.yaml:471,491-495. Trace how absent or empty role-filter data reaches shared-mount resolution. Done means unavailable or malformed role-filter data produces no shared mounts and a visible readiness or status error, with legacy full-groups behavior requiring an explicit unsafe-dev setting.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- jupyter, python
- Domain
- authorization, backend, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100