v3.6.5
Highlights
This is a security patch release. It fixes three security advisories — a stored XSS in the Admin Dashboard, an unauthenticated denial-of-service affecting SQLite-backed instances, and a data-exposure issue in Shop API list queries — alongside a solid batch of dashboard and core fixes. If you're running 3.6.x, we recommend upgrading. Thanks to those who disclosed the security issues responsibly, and to everyone who reported bugs and sent in PRs.
Security
Three advisories are addressed in this release. Upgrading to 3.6.5 applies all three fixes.
- Stored XSS in the Admin Dashboard (GHSA-xhq9-whgq-49j5) -- certain stored entity content rendered in the dashboard could carry unsanitised HTML. Rendering has been hardened so stored content can no longer execute script.
- Denial-of-service on SQLite (GHSA-jgm3-qmp2-c4p7) -- a crafted list-query filter could trigger catastrophic backtracking and tie up the server. Input handling in the affected filter has been hardened. This only affects instances using the SQLite driver, which is intended for development and testing; production deployments on PostgreSQL or MySQL/MariaDB are unaffected.
- Data exposure in Shop API list queries (GHSA-xf65-r35x-wmmv) -- under certain filter combinations, Shop API list queries could return entities that should not be publicly visible. List-query scoping has been corrected so only intended results are returned.
Core fixes
Notable fixes to the core:
- Channel scoping enforced on entity updates (#4821) -- update operations now consistently respect channel scoping, tightening isolation between channels in multi-channel setups.
- Draft orders excluded from promotion usage limits (#4854) -- draft orders were being counted toward a promotion's usage limit, which could exhaust it prematurely. They're no longer counted.
- Reliable search index writes (#4809) --
DefaultSearchPlugincould hit duplicate-key errors while writing index entries under some conditions. Index writes are now handled without those collisions. - Bounded i18next preload (#4824) -- prevented unbounded growth in the i18next preload set, which could accumulate memory over time.
- StockLevel seeded on channel assignment (#4864) -- assigning a
ProductVariantto a channel now seeds itsStockLevelfor that channel, so stock is tracked from the start.
Dashboard improvements
- Draft orders (#4810, #4834) -- selecting a customer on a draft order now applies their default shipping and billing addresses.
- List pages and filters (#4843, #4845, #4839) -- enum fields are now supported in list filters and form defaults; the product multi-selector shows the full saved selection; and order-list state cells are guarded against an undefined state so the list renders cleanly.
- Robustness (#4859, #4851, #4874) -- the rich-text editor guards
getHTML()against a destroyed instance;useUiLanguageLoaderis stabilised to stop a render loop; and opening a detail entity that isn't in the active channel now redirects back to the list instead of erroring. - Assets (#4855, #4439) -- hard-loading
/dashboard/assetsnow serves the SPA route correctly, and the asset picker dialog isolates itsPageContextso it no longer interferes with the page behind it. - Layout and polish (#4829, #4712) --
PageBlockrenders full-width withcolumn="full", and the facet value chip's remove button stays visible on long values. - Internationalisation (#4838, #4870) -- added missing Russian translations for order actions, and fixed a nested
tmacro inside a plural for the job-cancel toasts.
What's Changed
- fix: Prevent facet value chip remove button from being hidden on long… by @Ryrahul in #4712
- fix(core): Stop silent telemetry data loss on Vercel/Netlify and under ESM by @dlhck in #4804
- fix(core): Prevent duplicate-key errors in DefaultSearchPlugin index writes by @IsroilovA in #4809
- fix(dashboard,i18n): improve Czech translations by @Misioka in #4806
- fix(core): Enforce channel scoping on entity update operations by @michaelbromley in #4821
- fix(core): Prevent unbounded i18next preload growth by @michaelbromley in #4824
- fix(dashboard): render full-width PageBlock with column="full" by @michaelbromley in #4829
- fix(dashboard): only send edited stock levels on variant update by @michaelbromley in #4834
- fix(dashboard): Guard order list state cells against undefined state by @grolmus in #4839
- fix(dashboard): Serve Assets SPA route when hard-loading /dashboard/assets by @grolmus in #4855
- fix(core): Exclude draft orders from promotion usage limit counts by @grolmus in #4854
- fix(dashboard): Stabilise useUiLanguageLoader callback to prevent render loop by @TheStreamCode in #4851
- fix(email-plugin): Add pooled SMTP options to SMTPTransportOptions by @grolmus in #4861
- fix(core): seed StockLevel on channel assignment (multi-channel) by @michael-attal in #4864
- docs: Expand dashboard extension docs by @dlhck in #4866
- fix(dashboard): Guard getHTML() against destroyed rich text editor by @xakmen in #4859
- fix(dashboard): Support enum fields in list filters and form defaults by @grolmus in #4843
- fix(dashboard,i18n): Add missing Russian translations for order actions by @IsroilovA in #4838
- fix(dashboard): Stop nesting t macro inside plural for job cancel toasts by @michaelbromley in #4870
- fix(dashboard): redirect to list when detail entity not found in active channel by @michaelbromley in #4874
- fix(dashboard): Show full saved selection in product multi-selector by @grolmus in #4845
- fix(dashboard): Isolate PageContext in asset picker dialog by @grolmus in #4439
- fix(create): Detect package manager for dependency install by @grolmus in #4877
- fix(dashboard): Set default addresses when selecting customer on draft order by @Lennix in #4810
- fix(dashboard): Gate draft-order address unset on streetLine1 + re-extract i18n by @michaelbromley in #4890
- fix(create): Allow pnpm to build native deps in generated project by @michaelbromley in #4893
- fix(core): Accept SVG uploads rejected by content-type validation by @michaelbromley in #4899
- fix(testing): Move contentTypeOverrides doc off inline type to fix docs build by @michaelbromley in #4900
- fix(create): install workspace deps from root in monorepo mode by @michaelbromley in #4907
New Contributors
- @Misioka made their first contribution in #4806
- @TheStreamCode made their first contribution in #4851
- @michael-attal made their first contribution in #4864
- @xakmen made their first contribution in #4859
- @Lennix made their first contribution in #4810
Full Changelog: v3.6.4...v3.6.5