Skip to content

Boost: let admins test extra Concatenate JS/CSS excludes per-request via GET parameters#49555

Draft
kraftbj wants to merge 3 commits into
trunkfrom
claude/boost-audit-prioritize-09rf6a-concat-debug-excludes
Draft

Boost: let admins test extra Concatenate JS/CSS excludes per-request via GET parameters#49555
kraftbj wants to merge 3 commits into
trunkfrom
claude/boost-audit-prioritize-09rf6a-concat-debug-excludes

Conversation

@kraftbj

@kraftbj kraftbj commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Fixes #31682

Proposed changes

  • Adds two debug-only GET parameters for the Concatenate JS/CSS (minify) modules: jb-minify-js-excludes and jb-minify-css-excludes, each accepting comma-separated script/style handles.
  • For logged-in administrators (manage_options), the listed handles are appended to the respective saved exclude list for that request only, letting support/developers test "would excluding handle X fix this page?" without editing settings or needing a staging copy.
  • Handles are validated against a strict allowlist (alphanumerics, dash, underscore, dot); anything else is discarded. Case is preserved, since script/style handles are matched case-sensitively downstream. Oversized values are ignored, and nothing is ever persisted to the data-sync store.
  • The merge lives in jetpack_boost_page_optimize_merge_debug_excludes() in functions-helpers.php, called from the two exclude-list readers consumed by Concatenate_JS::do_items() / Concatenate_CSS::do_items() — which run during normal WordPress runtime (wp_head/wp_footer), so current_user_can() is reliably available (with a function_exists guard as belt-and-braces; the pre-WordPress _jb_static service path never reads exclude lists).
  • No Page Cache interaction: logged-in users always bypass Boost's page cache — Request::is_cacheable() returns false on both the serve and the write paths — and GET parameters are part of the cache key anyway, so these parameters can neither hit nor poison cached pages.
  • The parameter is intentionally nonce-free so it can be shared as a plain URL; it stays capability-gated rather than CSRF-gated. Rendering distinct exclude combinations generates the usual concat-path cache artifacts, reclaimed by the normal Cleanup_Stored_Paths schedule.
  • Adds unit tests covering merge, sanitization, case preservation, capability gating, dedup, the all-invalid / empty-string / oversized branches, non-string params, and non-persistence, plus a short "Debugging Concatenate JS/CSS exclusions" section in the development guide.

Related product discussion/links

Does this pull request change what data or activity we track or use?

No.

Testing instructions

  1. Enable Concatenate JS in Jetpack Boost and visit a front-end page as an administrator; confirm scripts are served via concatenated /_jb_static/??… URLs.
  2. Reload with ?jb-minify-js-excludes=jquery-core appended. Confirm jquery-core is now served as a standalone <script> tag (with WP_DEBUG on you'll see <!-- No Concat JS jquery-core => Excluded option -->), while other scripts remain concatenated. Repeat with ?jb-minify-css-excludes=<style-handle> for CSS.
  3. Reload without the parameter — the handle is concatenated again, and the saved exclude list in Boost's settings is unchanged (nothing persisted).
  4. Open the same URL with the parameter in a logged-out/incognito window — the parameter has no effect.
  5. Try ?jb-minify-js-excludes=<script>alert(1)</script> — the invalid handle is ignored and the page renders normally.
  6. Unit tests: run the Boost PHP unit suite (jp test php plugins/boost); the Debug_Excludes_Test cases exercise this feature.

When JS/CSS concatenation breaks a page, support staff and developers
previously had to edit the site's saved exclude lists to test whether
excluding a particular handle fixes it. This adds per-request debug
parameters instead:

- ?jb-minify-js-excludes=handle1,handle2 appends handles to the JS
  concatenate exclude list for that request only.
- ?jb-minify-css-excludes=... does the same for CSS.

The merge happens in jetpack_boost_page_optimize_js_exclude_list() /
..._css_exclude_list() (read from Concatenate_JS / Concatenate_CSS
during wp_head/wp_footer, i.e. within normal WordPress runtime), and:

- is only honored for logged-in users with manage_options;
- validates each handle against a sanitize_key-style allowlist
  (lowercase alphanumerics, dash, underscore, dot), ignoring the rest;
- never persists anything to the data sync store or options;
- has no Page Cache interaction, since logged-in users always bypass
  Boost's page cache (Request::is_cacheable() returns false).

Fixes #31682

https://claude.ai/code/session_01PgpTrtTCH4hpz6Krh3ssho
@jp-launch-control

jp-launch-control Bot commented Jun 11, 2026

Copy link
Copy Markdown

Code Coverage Summary

Coverage changed in 1 file.

File Coverage Δ% Δ Uncovered
projects/plugins/boost/app/lib/minify/functions-helpers.php 30/169 (17.75%) 14.99% -2 💚

Full summary · PHP report · JS report

@github-actions

Copy link
Copy Markdown
Contributor

Thank you for your PR!

When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:

  • ✅ Include a description of your PR changes.
  • ✅ Add a "[Status]" label (In Progress, Needs Review, ...).
  • ✅ Add testing instructions.
  • ✅ Specify whether this PR includes any changes to data or privacy.
  • ✅ Add changelog entries to affected projects

This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖


Follow this PR Review Process:

  1. Ensure all required checks appearing at the bottom of this PR are passing.
  2. Make sure to test your changes on all platforms that it applies to. You're responsible for the quality of the code you ship.
  3. You can use GitHub's Reviewers functionality to request a review.
  4. When it's reviewed and merged, you will be pinged in Slack to deploy the changes to WordPress.com simple once the build is done.

If you have questions about anything, reach out in #jetpack-developers for guidance!


Boost plugin:

No scheduled milestone found for this plugin.

If you have any questions about the release process, please ask in the #jetpack-releases channel on Slack.

claude and others added 2 commits June 11, 2026 12:21
…d lists

The defensive-null unit test passes null on purpose; the docblock now
says mixed so Phan's ProbablyReal check matches the implementation.

https://claude.ai/code/session_01PgpTrtTCH4hpz6Krh3ssho
Fixes from a code review + adversarial pass over the per-request
jb-minify-js-excludes / jb-minify-css-excludes debug parameters:

- Preserve handle case instead of lowercasing. Script/style handles are
  matched case-sensitively downstream, so lowercasing silently failed to
  exclude any handle registered with uppercase letters (e.g. MyPlugin-script).
  The allowlist now accepts A-Z and case is kept verbatim, matching how the
  saved exclude list already behaves.
- Ignore oversized parameter values (over 2000 chars) so the per-asset parse
  cannot be made to do unbounded work.
- Document that rendering distinct exclude combinations generates concat-path
  cache artifacts (reclaimed by the normal Cleanup_Stored_Paths schedule), and
  that the parameter is intentionally nonce-free so it stays shareable as a URL.
- Tighten the function_exists() rationale comment.
- Tests: assert case is preserved, cover the all-invalid-handles and
  empty-string branches, and the oversized-value guard. Drop the test that
  asserted the old lowercasing behavior.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enhancement: Debug Boost concatenate excludes via GET params

2 participants