Skip to content

chore(security): bump justhtml 1.18.0 to 3.11.1 - #17344

Merged
janriokrause merged 5 commits into
mainfrom
chore--bump-justhtml-safely
Aug 27, 2026
Merged

janriokrause merged 5 commits into
mainfrom
chore--bump-justhtml-safely

Conversation

@stevejalim

@stevejalim stevejalim commented Aug 24, 2026 •

Copy link
Copy Markdown
Contributor

This is a fresh swing at updating justhtml without shooting ourselves in the foot. It's a big bump, because justhtml is moving fast, so we need to be careful.

Changes of note around how we interact with it:

  • UrlRule now needs explicit handling="allow": since justhtml==1.19.0, rules without it inherit UrlPolicy.default_handling, which is "strip" in our config. Without this fix, href and src on allowlisted <a> and <img> tags get silently dropped. This was (allegedly) the root cause of the PR fix: correctly bump justhtml; add config update to handle breaking changes #17279 failure.

  • strip_all_tags loses the drop_content_tags parameter (removed in justhtml==2.0). To preserve the existing behavior of keeping text content from <script> and <style> elements, we pass an Unwrap("script, style") transform that converts those tags to bare text nodes before sanitization runs.

  • Both sanitization functions change safe=True to sanitize=True (renamed in version 2.0). Same rename in sync_greenhouse.py.

Seven <a> tags in the VPN download template had class specified twice. Because Dduplicate attributes are invalid HTML, so these have been merged into single class attributes to make things stable, but we should keep an eye open in case we get a change in behaviour - we shouldn't, but...

Testing

UrlRule now needs explicit handling="allow" — since justhtml 1.19.0,
rules without it inherit UrlPolicy.default_handling, which is "strip"
in our config. Without this fix, href and src on allowlisted <a> and
<img> tags get silently dropped. This was the root cause of the
PR #17279 failure.

strip_all_tags loses the drop_content_tags parameter (removed in
justhtml 2.0). To preserve the existing behavior of keeping text
content from <script> and <style> elements, we pass an
Unwrap("script, style") transform that converts those tags to bare
text nodes before sanitization runs.

Both sanitization functions change safe=True to sanitize=True
(renamed in justhtml 2.0). Same rename in sync_greenhouse.py.

Seven <a> tags in the VPN download template had class specified
twice. Duplicate attributes are invalid HTML; the new justhtml
parser may handle them differently. Merged into single class
attributes.
@stevejalim
stevejalim requested review from a team as code owners August 24, 2026 13:50
@codecov

codecov Bot commented Aug 24, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.90%. Comparing base (ae5f2d7) to head (710ba69).

Additional details and impacted files
@@           Coverage Diff           @@
##             main   #17344   +/-   ##
=======================================
  Coverage   82.90%   82.90%           
=======================================
  Files         180      180           
  Lines        9396     9396           
=======================================
  Hits         7790     7790           
  Misses       1606     1606           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI 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.

Pull request overview

This PR upgrades Bedrock’s HTML sanitization dependency (justhtml) from 1.18.0 to 3.11.1 and updates Bedrock’s sanitization wrappers/consumers to match breaking API and behavior changes, with a small template fix to avoid invalid duplicate attributes.

Changes:

  • Bump justhtml to 3.11.1 across prod/dev, and align lockfiles.
  • Update sanitization usage for justhtml>=2.0 (e.g., safe=True → sanitize=True, explicit UrlRule(..., handling="allow"), and a pre-sanitize Unwrap("script, style") transform for strip_all_tags).
  • Fix invalid HTML in the VPN download template by merging duplicate class attributes into a single attribute.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
requirements/prod.txt Updates the production lockfile for the justhtml major bump (and other resolver-driven version changes).
requirements/prod.in Updates the top-level justhtml pin to 3.11.1.
requirements/docs.txt Updates docs dependency lockfile (includes an updated “generated by” command comment).
requirements/dev.txt Updates the development lockfile to ensure local tests run against justhtml 3.11.1.
bedrock/products/templates/products/vpn/download.html Fixes invalid duplicate class attributes on multiple download CTA links.
bedrock/careers/management/commands/sync_greenhouse.py Updates JustHTML(..., safe=True) to sanitize=True for the new justhtml API.
bedrock/base/sanitization.py Updates Bedrock’s shared sanitization helpers for new justhtml policy/rule semantics.

(Review performed using the repository’s custom Copilot instructions.)

Suppressed comments (2)

requirements/prod.txt:1242

  • This lockfile update downgrades protobuf (7.36.0 → 7.35.1). Please confirm this is intentional and doesn’t conflict with any other pinned Google client libraries, since protobuf downgrades can introduce subtle runtime incompatibilities.
protobuf==7.35.1 \
    --hash=sha256:11d6b0ec246892d85215b0a13ca6e0233cf5284b68f0ac02646427f4ff88a799 \
    --hash=sha256:230a75ddfc2de4806e56696ce9640c1cdfdb6543b7cfce98d42a4c0a0e7bdb87 \
    --hash=sha256:24f857477359a85c0c235261b8ba905fd51b2562f4a64ca1df5473f29850cbf6 \
    --hash=sha256:353652e4efd0bca5b5fc2656abf8307ef351f0cf938c9eba09f0e09c20a25c30 \

requirements/dev.txt:958

  • requirements/dev.txt also downgrades runtime-adjacent deps (e.g., idna to 3.18 and protobuf to 7.35.1). Please confirm these are intentional side effects of the recompile for justhtml and not accidental drift.
idna==3.18 \
    --hash=sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2 \
    --hash=sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread requirements/prod.txt Outdated
Comment thread requirements/dev.txt Outdated
Base automatically changed from 2026-08-24--dep-updates to main August 24, 2026 14:31
stevejalim and others added 2 commits August 25, 2026 10:17
The class makes a round icon button and belongs only on the icon-only
links. Merging the duplicate `class` activated it and broke the labels
on the four secondary buttons. On the five primary ones it is inert,
verified across every platform state and width, so those are cleanup.
@janriokrause

Copy link
Copy Markdown
Contributor

Merging the duplicate class has a side effect: it activates platform-download-link, which was only inert because browsers were dropping it as a duplicate. That class forces a 45x45 round icon button with a hidden label, so the four secondary text buttons (185 64-bit, 220 Flathub, 224 APT, and 190 ARM once bedrock#17305 is uncommented) collapse with their labels overlapping the icon.

I pushed a fix that deletes platform-download-link instead of merging it, on the nine links that also carry mzp-c-button. Same rendering as before, still valid HTML. Five of the nine are in the primary card where the class is never styled, so those are just cleanup.

Here is one example (line 224):

Before

224-secondary-apt-BEFORE

After

224-secondary-apt-AFTER

@janriokrause
janriokrause merged commit 744ecb1 into main Aug 27, 2026
7 checks passed
@janriokrause
janriokrause deleted the chore--bump-justhtml-safely branch August 27, 2026 15:43
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.

3 participants