This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch 5.9.x-javax
in repository https://gitbox.apache.org/repos/asf/tapestry-5.git

commit 4eb672944353cd9110dbd8f9c5c5f7211a2c7ee8
Author: Ben Weidig <[email protected]>
AuthorDate: Wed Oct 7 08:16:26 2026 +0200

    Improving classpath asset handling
---
 .../assets/ClasspathAssetRequestHandler.java       | 36 ++++++++++++++++------
 1 file changed, 27 insertions(+), 9 deletions(-)

diff --git 
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/ClasspathAssetRequestHandler.java
 
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/ClasspathAssetRequestHandler.java
index 1391bcee0..c93d4e5d1 100644
--- 
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/ClasspathAssetRequestHandler.java
+++ 
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/ClasspathAssetRequestHandler.java
@@ -59,24 +59,42 @@ public class ClasspathAssetRequestHandler implements 
AssetRequestHandler
     public boolean handleAssetRequest(Request request, Response response, 
String extraPath) throws IOException
     {
         ChecksumPath path = new ChecksumPath(streamer, baseFolder, extraPath);
-        
+
+        // Resolve the resource first, then check the protection rule against 
the
+        // fully-normalized path that will actually be loaded and streamed 
(Resource#getPath()).
+        final Resource resource;
+
+        try
+        {
+            resource = assetSource.resourceForPath(path.resourcePath);
+        }
+        catch (IllegalStateException ex)
+        {
+            // The path normalized to a location above the classpath root 
(e.g. a "../" escape).
+            // Fail closed: treat it as blocked rather than surfacing it as a 
server error.
+            if (LOGGER.isWarnEnabled())
+            {
+                LOGGER.warn("Blocked request for classpath asset '" + 
path.resourcePath +
+                        "': " + ex.getMessage());
+            }
+            return false;
+        }
+
+        final String resourcePath = resource.getPath();
+
         final boolean handled;
-        
-        final String resourcePath = path.resourcePath.replace("\\.", "");
-        
-        if (classpathAssetProtectionRule.block(resourcePath) && 
!path.resourcePath.equals(ChecksumPath.NON_EXISTING_RESOURCE)) 
+
+        if (classpathAssetProtectionRule.block(resourcePath) && 
!path.resourcePath.equals(ChecksumPath.NON_EXISTING_RESOURCE))
         {
-            if (LOGGER.isWarnEnabled()) 
+            if (LOGGER.isWarnEnabled())
             {
-                LOGGER.warn("Blocked request for classpath asset '" + 
path.resourcePath + 
+                LOGGER.warn("Blocked request for classpath asset '" + 
resourcePath +
                         "'. Contribute a new ClasspathAssetProtectionRule if 
you need this asset to be publicly accessible.");
             }
             handled = false;
         }
         else
         {
-            Resource resource = assetSource.resourceForPath(path.resourcePath);
-    
             handled = path.stream(resource);
         }
         return handled;

Reply via email to