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 <[email protected]> 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 <[email protected]>
> 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 <[email protected]> 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 <[email protected]
>> >
>> > 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: [email protected]
>> > > For additional commands, e-mail: [email protected]
>> > >
>> > >
>> >
>> > --
>> > Dmitry Gusev
>> >
>> > AnjLab Team
>> > http://anjlab.com
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: [email protected]
>> For additional commands, e-mail: [email protected]
>>
>>
>
> --
> Dmitry Gusev
>
> AnjLab Team
> http://anjlab.com
>
--
Dmitry Gusev
AnjLab Team
http://anjlab.com