Repository navigation
[security] Fix ISEC-V2026-03/04/05 authorization findings and move to Python 3.11 only - #4384
Merged
Merged
Conversation
|
✅ Test files were modified. Ensure that the tests cover all relevant changes. ✅ |
Harshg999
force-pushed
the
fix/configuration-api-authorization
branch
from
October 26, 2026 17:10
319cd13 to
5af8587
Compare
|
Warning Your comment is too long (maximum is 65536 characters), so the coverage report was not added. See the job log for how to reduce it. |
Harshg999
force-pushed
the
fix/configuration-api-authorization
branch
2 times, most recently
from
October 28, 2026 08:08
9bde03b to
b810fc7
Compare
The DefaultConfiguration REST endpoints trusted a client-supplied user_id and configuration id without checking ownership or admin role. Any authenticated user could read or change another user's effective settings, modify cluster-wide default/group configuration, or delete arbitrary configuration rows. - Add configuration/authorization.py with helpers for the global admin check, per-user target resolution and delete authorization. - Require a Hue admin for GET/POST /desktop/api/configurations/. - Resolve and authorize user_id on GET/POST /desktop/api/configurations/user/. Non-admins can only use their own id; admins can use any valid id. - Authorize before deleting on /desktop/api/configurations/delete/: default and group rows need an admin, user rows need the owner or an admin. - Point CONFIG_SAVE_API at /desktop/api/configurations/user/. The previous /configurations/save/ route does not exist. - Add TestConfigurationAuthorization regression tests covering the cross-user, non-admin and admin cases.
GitHub-hosted ubuntu-latest now resolves to Ubuntu 26.04, where actions/setup-python no longer publishes prebuilt CPython 3.9. Python 3 CI failed at the setup-python step with "version 3.9 was not found for Ubuntu 26.04". Python 3.9 and 3.10 are also end of life. Align the supported, tested and documented Python version on 3.11 only, following the same direction as #4376 (drop EOL interpreters from the matrix). - commitflow-py3.yml: remove the 3.9/3.10/3.11 matrix and run a single job on Python 3.11. Always use build/env for pytest, ruff and artifacts. - Makefile.vars: PYTHON_VERSIONS is python3.11 only, require minor version >= 11 and simplify the pip/virtualenv version settings. - generate_requirements.py: drop the Python 3.9-specific pins on x86_64 and aarch64 (3.11 entries unchanged). - generate_requirements_test.py: update the tests for the 3.11 paths. - Docs: installation dependencies, developer guide, SDK and the ci-cd design note now state Python 3.11 as the required version. Follow-up (separate commit): tools/cloudera and the legacy container Dockerfiles still reference older Python versions.
CI runs `hue runruff check` with PYTHONWARNINGS=always. The configuration authorization changes introduced import order, unused exception bindings and style issues in api.py and tests.py. Apply the ruff fixes (I001, F401, F841, E303, E711, E712) so the Python 3 and ARM64 CI lint steps pass. No behavior change.
Follow-up to the CI/Makefile minimum of Python 3.11: remove the remaining multi-Python and EOL interpreter paths across the Cloudera builds, containers, scripts and requirement generation, so the supported, tested and documented versions line up. Cloudera packaging (tools/cloudera): - build_hue_cloudera.sh: single python3.11 build/release. All supported OS targets use PYTHON311_OSES and always build into build/env. - build_hue_common.sh: drop install_python39 and the Python 3.9 install hooks from every OS installer. install_sqlite_python only bootstraps 3.11.12. Runtime and developer tooling: - python_helper.sh and hue.sh: resolve build/env/bin only and reject other HUE_PYTHON_VERSION values. - Makefile.vars: always use build/env and inst/env (no build/venvs layout). - runruff.py: always use build/env/bin/ruff. - relocatable.sh: document and gate on Python 3.11. - pyproject.toml: ruff target-version is py311 and pytest norecursedirs drops the removed 3.8-3.10 directories. Requirements: - generate_requirements.py: one 3.11 arch-specific pin set. Fail on an unsupported Python minor version instead of falling back to legacy "default" pins. Refresh the stale version comments. Containers: - UBI compile/base/hue Dockerfiles: python3.11 packages and pip paths. Install psycopg2-binary with pip instead of a cp38 wheel. Tests: - generate_requirements_test.py updated. Not changed: historical gethue posts, vendored third-party CI configs and tools/docker/hue/Dockerfile.py2 (legacy Python 2 image).
GET /api/v1/check_config was available to any authenticated user. It returns the Hue configuration directory path and the configuration validation errors, which expose server paths and internal service topology. The legacy /desktop/debug/check_config view is already admin-only. - Gate check_config with deny_unless_hue_admin and return HTTP 403 with the shared "You must be a Hue admin" message for non-admins. The check uses the same is_admin helper as the legacy view. - Switch available_app_examples and install_app_examples to the same helper. Their behavior and message are unchanged. - Add TestCheckConfigPublicApi (anonymous, non-admin, admin), admin and non-admin unit tests for check_config, and unit tests for deny_unless_hue_admin. - Point the existing api2 admin tests at the shared is_admin patch target. Fix the unused imports and the undefined SkipTest in api_public_tests.py that ruff flagged once the file was touched.
POST /indexer/api/importer/save (save_pipeline) had its permission decorator commented out, and _save_pipeline loaded the target with a raw Document2.objects.get(id=...) and no write check. Any authenticated user could overwrite another user's saved document by id. - Add notebook/saved_document_auth.py with get_writable_document_for_update(). It resolves the existing document by parentSavedQueryUuid (write permission required) or by id (can_write_or_exception), and returns None when a new document should be created. A missing document and a denied write raise the same message so document ids cannot be probed. Admins keep write access to other users' documents, as before. - Re-enable @check_document_modify_permission() on save_pipeline. - Make check_document_modify_permission, _save_pipeline and _save_notebook use the helper, so authorization still holds if a view decorator is missing or incomplete. - check_document_modify_permission now also checks parentSavedQueryUuid when no id is sent, and a read-only share can no longer be saved over. - Add tests: TestSavedDocumentAuth, TestSavePipeline (model and HTTP, cross-user denied, owner allowed) and test_save_notebook_denies_cross_user_update. Housekeeping needed to pass ruff on the touched files: replace the fetch_handle lambda in indexer api3.py with a nested function, drop unused exception bindings in notebook/decorators.py and api.py, and remove test_save_notebook_with_connector_on, which was skipped unless connectors were enabled and referenced an undefined variable.
Harshg999
force-pushed
the
fix/configuration-api-authorization
branch
from
October 28, 2026 08:48
b810fc7 to
003aa8c
Compare
Harshg999
enabled auto-merge (rebase)
October 28, 2026 09:06
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes three authorization findings and drops support for Python versions
below 3.11 (including GitHub Actions fixes).
ISEC-V2026-03: Improper authorization (IDOR) in the configuration API (Medium)
/desktop/api/configurations/,/user/and/delete/did not check ownership or admin role.A client-supplied
user_idor configuration id was trusted, so any authenticated user couldread, overwrite or delete another user's editor configuration and change the cluster-wide
default.
desktop/configuration/authorization.py:GETandPOST /desktop/api/configurations/(global and group configuration) require aHue admin.
/desktop/api/configurations/user/: non-admins can only use their ownuser_id. Admins canuse any valid id.
/desktop/api/configurations/delete/: default and group rows require an admin. User rowsrequire the owner or an admin.
CONFIG_SAVE_APIin the frontend pointed at a route that does not exist(
/configurations/save/). It now uses/desktop/api/configurations/user/.ISEC-V2026-04: Server configuration disclosure via the configuration-check API (Low)
GET /api/v1/check_configwas available to any authenticated user. It returns the Hueconfiguration directory and the validation results, which include internal service endpoints.
is_admincheck as the legacy
/desktop/debug/check_configview.available_app_examplesandinstall_app_examplesuse the same shared helper(
deny_unless_hue_admin). Their behavior is unchanged.ISEC-V2026-05: Improper authorization (IDOR) in the indexer save API (Medium)
POST /indexer/api/importer/save(save_pipeline) had its permission decorator commented out,and
_save_pipelineloaded the target withDocument2.objects.get(id=...)and no write check.Any authenticated user could overwrite another user's saved document.
notebook/saved_document_auth.pywithget_writable_document_for_update(). It resolves thedocument by
parentSavedQueryUuid(write permission required) or byid(
can_write_or_exception), and returnsNonefor a new document.@check_document_modify_permission()is re-enabled onsave_pipeline. The decorator,_save_pipelineand_save_notebookall use the helper, so authorization still holds if aview decorator is ever missing.
Admins keep write access to other users' documents, as before.
Python 3.11 only
commitflow-py3.yml) runs a single Python 3.11 job, which also fixes the Ubuntu runnerfailure where
setup-pythoncould not find CPython 3.9.Makefile.vars,generate_requirements.py, thetools/clouderaandtools/containerbuild scripts, the Dockerfiles,python_helper.shandrunruff.generate_requirements.pynow fails clearly on an unsupported Python version.target-versionis nowpy311.Behavior changes
for
parentSavedQueryUuid.check_document_modify_permissionalso checksparentSavedQueryUuidwhen noidis sent./desktop/api/configurations/endpoint.Other changes in this PR
indexer/api3.py: thefetch_handlelambda is now a nested function (ruff E306).notebook/api.py,notebook/decorators.pyandapi_public_tests.py(unused imports and bindings, and an undefined
SkipTestreplaced withpytest.skip).test_save_notebook_with_connector_on. It only ran with connectors enabled and usedan undefined variable.
test_save_notebook_with_connector_offremains.Test plan
Automated:
TestConfigurationAuthorization,TestCheckConfigPublicApi,TestCheckConfigAPI(admin and non-admin),
TestSavedDocumentAuth(including admin access and the samemissing-vs-denied message),
TestSavePipeline(model and HTTP, cross-user denied, ownerallowed) and
test_save_notebook_denies_cross_user_update.hue runruff checkpasses.specific to this branch. The failures that remain also occur on
origin/master(HDFS and Hiveare not configured locally).
Manual (live server, real sessions for an admin and two normal users, 39 of 40 checks pass):
configuration. Own-user and admin flows work.
GET /api/v1/check_config: anonymous is rejected, a non-admin gets 403 with no server paths,and an admin gets 200.
idorparentSavedQueryUuid(database unchanged). Owner save and save-as work. A read-only sharecannot be saved over and a write share can. An admin can save another user's private query.