Repository navigation
chore(security): bump justhtml 1.18.0 to 3.11.1 - #17344
Conversation
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.
Codecov Report✅ All modified and coverable lines are covered by tests. 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. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
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
justhtmlto 3.11.1 across prod/dev, and align lockfiles. - Update sanitization usage for
justhtml>=2.0(e.g.,safe=True→sanitize=True, explicitUrlRule(..., handling="allow"), and a pre-sanitizeUnwrap("script, style")transform forstrip_all_tags). - Fix invalid HTML in the VPN download template by merging duplicate
classattributes 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.txtalso downgrades runtime-adjacent deps (e.g.,idnato 3.18 andprotobufto 7.35.1). Please confirm these are intentional side effects of the recompile forjusthtmland 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.
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.


This is a fresh swing at updating
justhtmlwithout 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:
UrlRulenow needs explicithandling="allow": sincejusthtml==1.19.0, rules without it inheritUrlPolicy.default_handling, which is"strip"in our config. Without this fix,hrefandsrcon 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_tagsloses thedrop_content_tagsparameter (removed injusthtml==2.0). To preserve the existing behavior of keeping text content from<script>and<style>elements, we pass anUnwrap("script, style")transform that converts those tags to bare text nodes before sanitization runs.Both sanitization functions change
safe=Truetosanitize=True(renamed in version2.0). Same rename insync_greenhouse.py.Seven
<a>tags in the VPN download template hadclassspecified 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
./manage.py update_legal_docs --forceand check the legal pages have links and decent markup./manage.py sync_greenhouse --forceand check the careers pages have links and decent markup