Add optional asset proxy mode for servers with incorrect MIME types#54
Open
erseco wants to merge 1 commit into
Open
Add optional asset proxy mode for servers with incorrect MIME types#54erseco wants to merge 1 commit into
erseco wants to merge 1 commit into
Conversation
Some servers return package JavaScript as text/plain while X-Content-Type-Options: nosniff is set, so browsers refuse to execute it and packages break. Add an optional, default-off "Content delivery" setting that routes all package assets through the existing content proxy, which sends explicit Content-Type headers. Direct uploads URLs remain the default for performance. - Content proxy: new exelearning_proxy_assets option and filter; widen is_proxied_path() to cover every package asset when enabled; map .mjs to application/javascript. - Settings: new "Content delivery" section with an AJAX-saved checkbox. - Docs: document the exelearning_proxy_assets filter. - Translations updated for all 10 shipped locales. - Tests for the proxy routing logic and the settings toggle. Closes #53
Contributor
Test in WordPress PlaygroundTest the plugin with the code from this branch:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #53
The problem
Some WordPress hosts serve files from the uploads directory with an incomplete or incorrect MIME map. When a package's JavaScript is returned as
text/plainwhileX-Content-Type-Options: nosniffis enabled, the browser refuses to execute the script, even though the file exists and the HTTP status is200:The package HTML itself loads fine (it already goes through the REST content proxy), but the directly-served sub-assets (CSS, JS, fonts, images, media) are rejected and the package breaks.
Root cause
The plugin routes script-capable documents (
html,htm,svg,xml) through the content proxy for hardened headers, but serves sub-assets directly fromwp-content/uploads/exelearning/{hash}/, trusting the web server to set the correct MIME type. On a misconfigured server that trust fails.The fix
A new optional, default-off setting routes all package assets through the existing content proxy, which sends explicit
Content-Typeheaders (application/javascript,text/css, valid font/image types…). Direct uploads URLs remain the default for performance.The change is intentionally small: the proxy already serves every extension with the right
Content-Typeand already rewrites HTML/CSS URLs with full path-traversal/realpathprotection. The only behavioral change is wideningExeLearning_Content_Proxy::is_proxied_path()so that, when the setting is on, ordinary assets are routed through the proxy too. External URLs (https://,//,data:,blob:,#,javascript:) are still never proxied, and CSSurl(...)references keep resolving relative to the CSS file.What's included
exelearning_proxy_assetsoption, a filterableis_asset_proxy_enabled()getter, widenedis_proxied_path(), and.mjsmapped toapplication/javascript.exelearning_proxy_assetsfilter to force the mode on/off per environment (documented indocs/HOOKS.md).ca,ca_valencia,de_DE,eo,es_ES,eu,gl_ES,it_IT,pt_PT,ro_RO);.po/.mo/.potregenerated.ContentProxyTestand toggle/permission tests inAdminSettingsTest.Acceptance criteria
application/javascript.text/css; fonts/images with valid MIME types.url(...)references resolved relative to the CSS file location.How to test
Automated
Manual (reproduce the off → on behavior)
make up, log in athttp://localhost:8888/wp-admin(admin/password)..elpxpackage to the Media Library and embed it on a page:[exelearning id="N"].…/wp-content/uploads/exelearning/{hash}/…js(served directly by the web server).…/wp-json/exelearning/v1/content/{hash}/…jswithContent-Type: application/javascript, and CSS astext/css. The package runs even under strictnosniffMIME checking.To simulate the broken host, configure the web server to return
text/plainfor.jsunder the uploads path: with the setting off the package fails with the “Refused to execute script” error; with it on the proxy sends the correctContent-Typeand the package works.