Ben Weidig created TAP5-2835:
--------------------------------
Summary: JavaScript source mapes (*.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
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)