You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by "Thiago Henrique De Paula Figueiredo (Jira)" <ji...@apache.org> on 2026/10/17 13:38:00 UTC
[jira] [Updated] (TAP5-2835) JavaScript source maps (*.map) shouldn't be served by default when running in production mode
[ https://issues.apache.org/jira/browse/TAP5-2835?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Thiago Henrique De Paula Figueiredo updated TAP5-2835:
------------------------------------------------------
Fix Version/s: 5.9.2
(was: 5.10.0)
> JavaScript source maps (*.map) shouldn't be served by default when running in production mode
> ---------------------------------------------------------------------------------------------
>
> Key: TAP5-2835
> URL: https://issues.apache.org/jira/browse/TAP5-2835
> Project: Tapestry 5
> Issue Type: Improvement
> Components: tapestry-core
> Affects Versions: 5.9.1
> Reporter: Ben Weidig
> Assignee: Ben Weidig
> Priority: Minor
> Fix For: 5.9.2
>
>
> h2. Problem
> Even though Tapestry doesn't generate sources maps, there are possible maps to be found in most projects:
> * build artifact copied into {{META-INF/assets}} or {{META-INF/modules}} alongside the application's compiled/bundled JS
> * vendored third-party bundle + map dropped into the webapp context and referenced via the {{context:}} prefix (e.g.{{{}@Path("context:js/vendor.min.js"){}}}).
> In production, these maps let anyone reconstruct original, unminified (and potentially unobfuscated/uncommented) source from the shipped bundle simply by requesting {{{}<bundle>.js.map{}}}.
> h2. Proposed Solution
> Introduce a new {{ContextAssetProtectionRule}} chain-of-responsibility service, mirroring the existing {{{}ClasspathAssetProtectionRule{}}}.
> Both are ordered-configuration chains where any contributed rule returning true for a path blocks the request (handler returns 404).
> * {{ContextAssetRequestHandler}} consults an injected {{ContextAssetProtectionRule}}
> * {{ClasspathAssetRequestHandler}} already had this mechanism, no change to the handler itself.
> * {{AssetsModule}} contributes a {{SourceMapFile}} rule to both chains, blocking any path ending in {{{}.map{}}}, gated on {{{}@Symbol(TapestryHttpSymbolConstants.PRODUCTION_MODE){}}}. The rule is only added when production mode is active, so development/QA environments are unaffected.
> Because both rules are ordinary IoC contributions, applications retain full control.
> *Note:* the {{asset:}} prefix resolves to a path under {{META-INF/assets/}} on the classpath and is served through {{{}ClasspathAssetRequestHandler{}}}.
> It is therefore already covered by the {{ClasspathAssetProtectionRule}} chain and needs no separate handling.
> h2. Caveat
> The new chain for {{ContextAssetRequestHandler}} won't change the existing behaviour and filter out {{{}WEB-INF{}}}, {{{}META-INF{}}}, and {{*.tml}} files.
> These rules are non-negotiable regardless of production mode.
> h2. Risks
> h3. Behavioral change for existing apps
> Any application currently relying on .map files being served in production will see those requests start returning 404 after upgrading.
> h5. Mitigation
> Documented as an intentional default.
> Recoverable via a one-line {{{}ContextAssetProtectionRule{}}}/{{{}ClasspathAssetProtectionRule{}}} contribution override, and behavior is unchanged in development mode.
> h3. Rule scope is extension-based, not content-based
> The block is a simple {{.toLowerCase().endsWith(".map")}} check.
> Any legitimate, non-source-map asset that happens to use a {{.map}} extension would also be blocked in production under the default rule.
> h5. Mitigation
> Same override path as above.
> h3. Two independent rule chains
> Because context and classpath assets now have separate protection mechanisms, an app overriding one (e.g., to re-enable maps under {{{}context:{}}}) must remember the other chain ({{{}classpath:{}}}) still blocks them by default, and vice versa.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)