My previous rule didn't work for JAR resources, here's an improved version of regex pattern rule:
import org.apache.tapestry5.SymbolConstants; import org.apache.tapestry5.ioc.annotations.Symbol; import org.apache.tapestry5.services.ClasspathAssetProtectionRule; import java.util.regex.Matcher; import java.util.regex.Pattern; public class DirectoryListingAssetProtectionRule implements ClasspathAssetProtectionRule { public static final Pattern LAST_SEGMENT_PATTERN = Pattern.compile("[^/\\\\]+$"); private final String modulePathPrefixGZ; public DirectoryListingAssetProtectionRule( @Symbol(SymbolConstants.MODULE_PATH_PREFIX) String modulePathPrefix) { this.modulePathPrefixGZ = modulePathPrefix.toLowerCase() + ".gz"; } @Override public boolean block(String path) { final Matcher matcher = LAST_SEGMENT_PATTERN.matcher(path); if (!matcher.find()) { // Empty last segment? return true; } final String match = matcher.group().toLowerCase(); return match.equals(modulePathPrefixGZ) || !match.contains("."); } } On Thu, Jan 16, 2020 at 1:35 PM Dmitry Gusev <dmitry.gu...@gmail.com> wrote: > Looking a bit further, it does make sense to me to block all directory > requests in ClasspathAssetRequestHandler by default, > as directory listing is not something you'd expect to receive via HTTP. > > That workaround won't work if you have folder with dot in the name though, > so something more type-safe may be required. > > At first glance I couldn't find any existing API that would expose > underlying File object from an instance of Resource, but for > ClasspathResource (and maybe some other resources, like FileResource, > ContextResource, etc.) this implementation could probably work better (not > tested): > > @Contribute(ClasspathAssetProtectionRule.class) > public static void contributeClasspathAssetProtectionRule( > OrderedConfiguration<ClasspathAssetProtectionRule> configuration, > AssetSource assetSource) > { > configuration.add("DirectoryListing", path -> > { > Resource resource = assetSource.resourceForPath(path); > > if (resource == null) > { > // Nothing to serve > return true; > } > > URL resourceUrl = resource.toURL(); > > if (resourceUrl != null) > { > try > { > return Path.of(resourceUrl.toURI()).toFile().isDirectory(); > } > catch (URISyntaxException e) > { > throw new RuntimeException(e); > } > } > > return false; > }); > } > > > On Thu, Jan 16, 2020 at 1:19 PM Nicolas Bouillon <nico...@bouillon.net> > wrote: > >> Hi, >> Thank you for the quick reply, I've added the following rule in my >> AppModule. >> >> @Contribute(ClasspathAssetProtectionRule.class) >> public static void contributeClasspathAssetProtectionRule( >> OrderedConfiguration<ClasspathAssetProtectionRule> configuration) >> { >> ClasspathAssetProtectionRule fileWithDot = (s) -> >> !s.toLowerCase().matches(".*\\.[^/]+"); >> configuration.add("DirectoryListing", fileWithDot); >> } >> >> Note that the directory listing is displayed even without any ending >> forwarding slash. Then I've forced the requested file name to end with >> a . followed by some chars (anything but a forward slash). >> >> I wonder if that configuration should be put by default, or activable >> using a configuration switch described in >> https://tapestry.apache.org/security.html >> >> Thank you again. >> Nicolas. >> >> Le jeu. 16 janv. 2020 à 10:43, Dmitry Gusev <dmitry.gu...@gmail.com> a >> écrit : >> > >> > Hi, >> > >> > I wasn't aware of it, thanks for bringing it up. >> > >> > From what I found in code, AssetsModule contributes three asset >> protection >> > rules: for .xml, .class, and .properties files: >> > >> > public static void contributeClasspathAssetProtectionRule( >> > OrderedConfiguration<ClasspathAssetProtectionRule> >> configuration) >> > { >> > ClasspathAssetProtectionRule classFileRule = (s) -> >> > s.toLowerCase().endsWith(".class"); >> > configuration.add("ClassFile", classFileRule); >> > ClasspathAssetProtectionRule propertiesFileRule = (s) -> >> > s.toLowerCase().endsWith(".properties"); >> > configuration.add("PropertiesFile", propertiesFileRule); >> > ClasspathAssetProtectionRule xmlFileRule = (s) -> >> > s.toLowerCase().endsWith(".xml"); >> > configuration.add("XMLFile", xmlFileRule); >> > } >> > >> > So as a possible workaround you could contribute another rule that >> vetoes >> > asset requests that have no file extension (or end with forward slash), >> > which should cover directory entries. >> > >> > On Thu, Jan 16, 2020 at 12:22 PM Nicolas Bouillon <nico...@bouillon.net >> > >> > wrote: >> > >> > > Hi all, >> > > >> > > Following a pen-test of our application, it has been raised that the >> > > list of assets if visible as a directory listing. >> > > >> > > For example, we have a javascript file available at this location >> > > /assets/meta/z58f7f3d4/javascript/library.js but when we access >> > > /assets/meta/z58f7f3d4/javascript/ the web server lists all files >> > > available in META-INF.assets.javascript directory of the project. >> > > >> > > Do you know how to prevent this listing? >> > > >> > > Looks like to me it's happening in >> > > >> > > >> org.apache.tapestry5.internal.services.assets.ClasspathAssetRequestHandler#handleAssetRequest >> > > and then in >> > > >> org.apache.tapestry5.internal.services.ResourceStreamerImpl#streamResource(org.apache.tapestry5.ioc.Resource, >> > > org.apache.tapestry5.services.assets.StreamableResource, >> > > java.lang.String, >> > > >> > > >> java.util.Set<org.apache.tapestry5.internal.services.ResourceStreamer.Options>) >> > > >> > > Thank you, >> > > Nicolas. >> > > >> > > --------------------------------------------------------------------- >> > > To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org >> > > For additional commands, e-mail: users-h...@tapestry.apache.org >> > > >> > > >> > >> > -- >> > Dmitry Gusev >> > >> > AnjLab Team >> > http://anjlab.com >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org >> For additional commands, e-mail: users-h...@tapestry.apache.org >> >> > > -- > Dmitry Gusev > > AnjLab Team > http://anjlab.com > -- Dmitry Gusev AnjLab Team http://anjlab.com