Skip to content

[core] Fix the open Dependabot alerts: Django 5.2, Mako, protobuf, npm and more - #4391

Merged
Harshg999 merged 7 commits into
masterfrom
fix/dependabot-cve-upgrades
Oct 29, 2026
Merged

Harshg999 merged 7 commits into
masterfrom
fix/dependabot-cve-upgrades

Conversation

@Harshg999

@Harshg999 Harshg999 commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator

Closes the open Dependabot alerts on master (Python and npm) in six commits that can be reviewed one by one.

Commits

  1. npm alerts and Node 22.13: qs, sanitize-html, i18next-http-backend (1.4.4 to 4.0.6), webpack, @babel/core, prismjs override; removes the unused diff and jsdom. The vendored cuix tarball is patched (dompurify 3.4.17, moment-timezone 0.5.48, js-cookie 3.0.8; js-cookie 3 removed getJSON(), so useCookiePreference now parses the cookie itself). engines.node is now >=22.13.0 (sanitize-html and eslint 9 need it), the container images install Node 22, and the docs are updated.
  2. Python clean pins: python-ldap 3.4.5, requests 2.33.0, tablib 3.10.0 (+ explicit xlrd==2.0.2, which tablib no longer installs and the indexer needs), PyJWT 2.15.1, simplejwt 5.5.1, pyarrow 23.0.1, pytest 9.0.3. base_requirements.txt (only read by Dependabot) had drifted from generate_requirements.py; it is regenerated and a test now fails if they differ.
  3. protobuf 6.33.5: signer_protos_pb2.py regenerated with protoc 6.33.5 (the serialized descriptor is byte for byte identical to the old one) plus a round trip test.
  4. Mako 1.4.2: djangomako 1.3.2 hard pins Mako==1.2.3 and has no newer release, so it is vendored under ext-py3 with that requirement relaxed.
  5. Remove ASGI/WebSocket (channels, daphne): disabled by default, only used for streamed ksqlDB results, untested. Removes the config section, consumer, routing, frontend client code and the Helm daphne deployment, service and ingress route. A leftover [[websockets]] section in hue.ini is reported as an unknown section and otherwise ignored.
  6. Django 5.2.18 with the companion packages (DRF 3.18.3, django-axes 8.3.1 replacing the vendored 5.13 fork, webpack-loader 3, auth-ldap 5, djangosaml2 1.12, celery-beat 2.8, redis 6, ...). Code changes: STORAGES instead of the ignored STATICFILES_STORAGE, axes lockout options as AXES_LOCKOUT_PARAMETERS, behind_reverse_proxy mapped to AXES_IPWARE_META_PRECEDENCE_ORDER (the old axes settings no longer exist, which would have made every client behind a load balancer share one lockout), GET logout without LogoutView, get_storage_class replacement, render_bundle context in the Mako templates, pytest-django 4.12 migration test fixture. Removes the vendored django-axes and unused django-babel forks.

Alerts not fixed

  • deepmerge (dependabot findings number: 739): no patched release exists, dev only.

Testing

  • Full Python suite: identical set of failures before and after (26 failed / 152 errors, all environment dependent oozie, jobbrowser, hive and RAZ tests); 1177 passed vs 1171 before.
  • Full jest suite, tsc, and the main, login and worker webpack builds.
  • Live run against a Hive/HDFS cluster: login, editor query, CSV and XLSX download, metastore, file browser, user creation, REST schema and JWT token, static assets and locale files.
  • Lockout test on a live server: failed logins end in 429, per client IP behind X-Forwarded-For.
  • New tests: axes_lockout_test.py, signer_protos_test.py, the base requirements sync test.

Update the npm dependencies behind the open Dependabot alerts.

Direct dependencies:
- qs 6.16.0 -> 6.16.1.
- sanitize-html 2.17.7 -> 2.18.1. Requires Node >= 22.12.
- i18next-http-backend 1.4.4 -> 4.0.6. It no longer has runtime
  dependencies and uses fetch. Hue only sets loadPath, which is
  unchanged.
- webpack 5.104.1 and @babel/core 7.29.6 (dev).
- Remove diff and @types/diff, which nothing imports.
- Remove the jsdom 16.6.0 devDependency. Jest uses the jsdom that
  jest-environment-jsdom brings, and the unused copy pulled in the
  vulnerable @tootallnate/once 1.1.2.

Transitive dependencies:
- Add an override for prismjs 1.30.0, which refractor pins to 1.27.
- Patch the vendored cuix tarball: dompurify 3.4.17, moment-timezone
  0.5.48 and js-cookie 3.0.8. js-cookie 3 removed getJSON(), so
  useCookiePreference now parses the cookie itself.
- Refresh the lock file for fast-uri 3.1.9 and serialize-javascript
  7.1.4.

Node:
- Require Node >= 22.13 in package.json engines (eslint 9 and
  sanitize-html need it; CI already uses Node 22).
- Install Node 22 in the container compile and base images, which still
  used Node 14, and update the docs.

Verified with the full jest suite, tsc, and the main, login and worker
webpack builds.
Bump the packages whose upgrade needs no code change:

- python-ldap 3.4.3 -> 3.4.5
- requests 2.32.3 -> 2.33.0
- tablib 0.13.0 -> 3.10.0. It no longer installs xlrd, which the
  indexer needs for pandas.read_excel(engine="xlrd"), so pin
  xlrd==2.0.2 explicitly. Hue only uses tablib for CSV output.
- PyJWT 2.14.0 -> 2.15.1
- djangorestframework-simplejwt 5.3.1 -> 5.5.1
- pyarrow 17.0.0 -> 23.0.1
- pytest 8.1.1 -> 9.0.3 (tests only)

base_requirements.txt only exists so Dependabot can scan the pins, and it
had drifted from generate_requirements.py (missing boto3, certifi,
cryptography and pyOpenSSL). Rewrite it from the generator and add a
test that fails when the two differ.

The user, auth, filebrowser, indexer and desktop lib tests fail on the
same 24 tests before and after the upgrade.
protobuf 3.20.3 is affected by two denial of service advisories (a JSON
recursion depth bypass and a parsing issue) fixed in 5.29.x and 6.x.

The checked-in signer_protos_pb2.py was old style generated code that
does not import on protobuf 4 or newer. Regenerate it with protoc 6.33.5.
The serialized file descriptor is byte for byte identical to the old
one, so the wire format is unchanged. The generated module checks the
runtime version, so the requirement is pinned to the same release.

Add signer_protos_test.py, which round trips a SignRequestProto so a
runtime mismatch fails a test instead of the first RAZ request.
Mako 1.2.3 is affected by three TemplateLookup path traversal advisories
(double slash URI prefix, backslash URI and drive letter URI). The last
one is only fixed in 1.4.2.

djangomako 1.3.2, the Django template backend Hue uses for its Mako
templates, hard pins Mako==1.2.3, so pip refuses the upgrade. There is
no newer djangomako release. Vendor it under ext-py3 like the other
patched libraries, unchanged except for relaxing its Mako requirement to
>= 1.2.3, and install it as a local requirement.

desktop/tests.py renders the full pages through the backend and passes
on Mako 1.4.2.
The optional websocket results feature (the [[websockets]] configuration,
the notebook consumer, the daphne ASGI entry point and the Helm
deployment) is disabled by default, only streamed ksqlDB results through
it, and has no tests. It keeps three packages (channels, channels-redis,
daphne) on the dependency list that have to be kept compatible with every
Django upgrade.

Remove it instead, as the downstream branches already did:

- Delete desktop/asgi.py, desktop/routing.py, notebook/routing.py and
  notebook/consumer.py, the websockets config section and has_channels(),
  and the channels settings.
- Drop the WebSocket client code and the WEB_SOCKETS_ENABLED and
  WS_CHANNEL globals from the editor page and the frontend. Query results
  were already fetched over HTTP, which stays the only path.
- ksqlDB queries no longer take a channel name and always return their
  rows synchronously.
- Remove the daphne deployment, service and ingress route from the Helm
  chart.
- Drop channels, channels-redis and daphne from the requirements.

A [[websockets]] section left in an existing hue.ini is reported as an
unknown section by the configuration check and otherwise ignored.
Django 4.2 reached the end of its security support in April 2026, so the
Django advisories published since (GeoDjango/GDAL, DomainNameValidator
header injection, cache middleware, signed cookie salts and more) are
only fixed in 5.2 and later. djangorestframework 3.18, which fixes the
remaining DRF advisories, also requires Django 5.2.

Packages:
- Django 4.2.30 -> 5.2.18, djangorestframework 3.15.2 -> 3.18.3,
  drf-spectacular 0.27.2 -> 0.29.0.
- django-axes: replace the vendored 5.13.0 fork, which does not support
  Django 5, with 8.3.1 from PyPI. Remove the vendored fork and the
  unused django-babel fork.
- django-webpack-loader 1.0.0 -> 3.2.3, django-auth-ldap 4.3.0 -> 5.3.0,
  djangosaml2 1.9.3 -> 1.12.0, django-celery-beat 2.6.0 -> 2.8.1,
  django-celery-results 2.5.1 -> 2.6.0, django-cors-headers 4.4.0 ->
  4.9.0, django-extensions 3.2.3 -> 4.1, django-ipware 3.0.2 -> 7.0.1,
  django_prometheus 2.3.1 -> 2.4.1, django-redis 5.4.0 -> 6.0.0,
  lxml 4.9.1 -> 6.1.0, pytest-django 4.8.0 -> 4.12.0.

Code changes:
- settings.py: drop USE_L10N and the django_babel middleware and app.
  STATICFILES_STORAGE is ignored since Django 5.1, so configure the
  manifest static files storage through STORAGES to keep the hashed
  static file names.
- django-axes 8: express the lockout options as AXES_LOCKOUT_PARAMETERS
  instead of the deprecated AXES_USE_USER_AGENT and
  AXES_LOCK_OUT_BY_COMBINATION_USER_AND_IP. AXES_BEHIND_REVERSE_PROXY
  and AXES_REVERSE_PROXY_HEADER no longer exist, which would have made
  every client behind the load balancer share one lockout. Map them to
  AXES_IPWARE_META_PRECEDENCE_ORDER. Remove a stale commented out
  middleware.
- dt_logout: Django's LogoutView only accepts POST since Django 5.0, but
  Hue logs out through a link. Log the user out and redirect instead.
- notebook/tasks.py: get_storage_class was removed, use import_string.
- Pass the request context to render_bundle in the Mako templates, as
  django-webpack-loader 3 requires.
- Run the database migration tests with the django_db_blocker fixture,
  as pytest-django 4.12 no longer allows them to open extra databases
  under the django_db mark.

Add axes_lockout_test.py, which locks out a user after failed logins and
checks that the lockout follows the forwarded client IP behind a proxy.

The full test suite has the same failures before and after the upgrade
(environment dependent oozie, jobbrowser, hive and RAZ tests).
@Harshg999 Harshg999 self-assigned this Oct 29, 2026
@github-actions

Copy link
Copy Markdown

✅ Test files were modified. Ensure that the tests cover all relevant changes. ✅

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

UI Code Coverage Report

Lines Statements Branches Functions
Coverage: 33%
40.16% (31632/78763) 32.06% (14985/46738) 26.4% (2414/9142)

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Coverage

Backend Code Coverage Report •
FileStmtsMissBranchBrPartCoverMissing
conftest.py3016292%37->39, 39, 44->47
desktop/core
   generate_requirements.py41912377%159->160, 160, 168->169, 169, 182->183, 183–189
desktop/core/src/desktop/auth
   views.py20771852567%20–21, 58–62, 64, 66–71, 73, 88, 104->105, 105–106, 113->114, 114–115, 143–144, 146->147, 147, 151->152, 152, 156–157, 160–161, 186->187, 187, 190–191, 195->198, 198, 203->204, 204–205, 239->248, 243–246, 249->259, 251->252, 252–257, 259->260, 260, 273, 277, 290, 292–294, 299–300, 302, 304, 306, 311–313, 315–317, 319, 321–322, 324–325, 330–333
desktop/core/src/desktop/lib/raz
   signer_protos_pb2.py28162143%32->33, 33–48
desktop/libs/notebook/src/notebook
   tasks.py3281821218740%76–80, 82–83, 86–87, 90–91, 124->125, 125, 127->135, 144–145, 150, 152–155, 164->165, 165–166, 191->192, 192–193, 199–201, 203–206, 208, 210, 223–224, 228–231, 233, 238, 240, 252, 260->261, 261, 262->263, 263, 272->273, 273, 274->275, 275, 276->277, 277, 279->282, 282–284, 286–294, 298–299, 301–306, 308–309, 311–312, 314, 318–319, 321–326, 328–330, 332, 334, 338–343, 350–356, 358–362, 364–367, 369–379, 381, 383, 385, 389, 391–396, 398–401, 403, 407–409, 411–417, 419–420, 424–428, 430–435, 437–440, 442–443, 445, 457->458, 458, 459->460, 460, 461->462, 462, 464->469, 485->486, 486–489, 491, 495->496, 496, 514, 522–526, 528–530, 532
TOTAL5698028932219711299347% 

CI runs `hue runruff check` on every file a PR changes, so the files the
upgrade commits touched have to be lint clean as a whole.

- Exclude generated *_pb2.py files from ruff. signer_protos_pb2.py is
  produced by protoc and has to be regenerated instead of edited.
- auth/views.py: sort the imports, drop the unused OIDCBackend and Group
  imports and an unused exception binding.
- notebook/tasks.py: sort the imports, drop the unused transaction and
  FileResponse imports and three unused local variables.
- desktop/tests.py: sort the imports, drop the unused connection import
  and remove test_forbidden_libs, a Python 2 only test that always
  skipped. test_check_config_ajax now asserts on the decoded content it
  already computed, and test_cx_Oracle used the Python 2 only
  ex.message and an assert on a tuple, which can never fail. It now uses
  str(ex) and pytest.fail.

@JohanAhlen JohanAhlen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome!

@Harshg999
Harshg999 merged commit 4b5d859 into master Oct 29, 2026
7 checks passed
@Harshg999
Harshg999 deleted the fix/dependabot-cve-upgrades branch October 29, 2026 16:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants