diff --git a/api/src/org/labkey/api/query/QueryChangeListener.java b/api/src/org/labkey/api/query/QueryChangeListener.java index 59d96dc79ee..776c57392ff 100644 --- a/api/src/org/labkey/api/query/QueryChangeListener.java +++ b/api/src/org/labkey/api/query/QueryChangeListener.java @@ -144,7 +144,7 @@ public static void handleQueryNameChange(@NotNull String oldValue, String newVal if (oldValue.equals(newValue)) return; - QueryChangeListener.QueryPropertyChange change = new QueryChangeListener.QueryPropertyChange<>( + QueryChangeListener.QueryPropertyChange change = new QueryChangeListener.QueryPropertyChange<>( QueryService.get().getUserSchema(user, container, schemaPath).getQueryDefForTable(newValue), QueryChangeListener.QueryProperty.Name, oldValue, @@ -160,7 +160,7 @@ public static void handleSchemaNameChange(@NotNull String oldValue, String newVa if (oldValue.equals(newValue)) return; - QueryChangeListener.QueryPropertyChange change = new QueryChangeListener.QueryPropertyChange<>( + QueryChangeListener.QueryPropertyChange change = new QueryChangeListener.QueryPropertyChange<>( null, QueryChangeListener.QueryProperty.SchemaName, oldValue, diff --git a/core/src/org/labkey/core/security/BlockListFilter.java b/core/src/org/labkey/core/security/BlockListFilter.java index 55e7f31ac3a..bee41f69984 100644 --- a/core/src/org/labkey/core/security/BlockListFilter.java +++ b/core/src/org/labkey/core/security/BlockListFilter.java @@ -180,7 +180,7 @@ public static boolean isSuspicious(String request_path, String query, String use return true; for (String part : path) { - if (part.startsWith(".") || part.startsWith("\">") || part.startsWith("wp-") || (part.startsWith("admin")&&!isActionURL)) + if ((part.startsWith(".") && !part.equals(".well-known")) || part.startsWith("\">") || part.startsWith("wp-") || (part.startsWith("admin")&&!isActionURL)) return true; if (part.endsWith("-inf")) return true; diff --git a/core/src/org/labkey/core/webdav/ModuleStaticResolverImpl.java b/core/src/org/labkey/core/webdav/ModuleStaticResolverImpl.java index cfd06de1c21..737e2d121f2 100644 --- a/core/src/org/labkey/core/webdav/ModuleStaticResolverImpl.java +++ b/core/src/org/labkey/core/webdav/ModuleStaticResolverImpl.java @@ -24,6 +24,7 @@ import org.labkey.api.cache.Cache; import org.labkey.api.cache.CacheListener; import org.labkey.api.cache.CacheManager; +import org.labkey.api.collections.CaseInsensitiveHashSet; import org.labkey.api.collections.CaseInsensitiveTreeMap; import org.labkey.api.files.FileSystemDirectoryListener; import org.labkey.api.files.FileSystemWatcher; @@ -57,12 +58,14 @@ import java.io.InputStream; import java.nio.file.WatchEvent; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; @@ -181,16 +184,15 @@ private LookupResult resolve(Path path) for (int i=0 ; i> map = shortcuts.get(rParent.getPath()); - if (null == map) - { - map = new HashMap<>(); - shortcuts.put(rParent.getPath(), map); - } + Map> map = shortcuts.computeIfAbsent(rParent.getPath(), k -> new HashMap<>()); map.put(from.getName(), new Pair<>(target,indexPage)); } @@ -387,6 +384,15 @@ public boolean shouldIndex() } } + private static final Set ALLOWED_DOT_NAMES = Collections.unmodifiableSet(new CaseInsensitiveHashSet(Arrays.asList(".well-known"))); + + private boolean isAllowableName(String name) + { + return !"WEB-INF".equalsIgnoreCase(name) && + !"META-INF".equalsIgnoreCase(name) && + (!name.startsWith(".") || ALLOWED_DOT_NAMES.contains(name)); + } + private static final Cache> CHILDREN_CACHE = CacheManager.getCache(1000, CacheManager.DAY, "Static resources"); private class StaticResource extends _PublicResource implements SupportsFileSystemWatcher @@ -419,18 +425,6 @@ public String getExecuteHref(ViewContext context) return PageFlowUtil.staticResourceUrl(getPath().encode()); } - @Override - public WebdavResolver getResolver() - { - return ModuleStaticResolverImpl.this; - } - - @Override - public boolean canList(User user, boolean forRead) - { - return true; - } - Map getChildren() { synchronized (_lock) @@ -447,7 +441,7 @@ Map getChildren() for (FileLike fo : files) { String name = fo.getName(); - if (name.startsWith(".") || name.equals("WEB-INF") || name.equals("META-INF")) + if (!isAllowableName(name)) continue; if (!map.containsKey(name)) map.put(name, new ArrayList<>()); @@ -459,7 +453,7 @@ Map getChildren() { Path path = getPath().append(e.getKey()); List alternates = e.getValue(); - if (alternates.get(0).isFile()) + if (alternates.getFirst().isFile()) children.put(e.getKey(), new StaticResource(this, path, alternates.subList(0,1), null)); else children.put(e.getKey(), new StaticResource(this, path, e.getValue(), null)); @@ -518,7 +512,7 @@ public File getFile() { if (!exists()) return null; - return _files.get(0).toNioPathForRead().toFile(); + return _files.getFirst().toNioPathForRead().toFile(); } @Override @@ -537,7 +531,7 @@ public boolean exists() @Override public boolean isCollection() { - return exists() && _files.get(0).isDirectory(); + return exists() && _files.getFirst().isDirectory(); } @Override @@ -549,7 +543,7 @@ public WebdavResource find(Path.Part name) @Override public boolean isFile() { - return exists() && _files.get(0).isFile(); + return exists() && _files.getFirst().isFile(); } @Override @@ -572,7 +566,7 @@ public long getLastModified() public InputStream getInputStream(User user) throws IOException { if (isFile()) - return _files.get(0).openInputStream(); + return _files.getFirst().openInputStream(); return null; } @@ -586,7 +580,7 @@ public long copyFrom(User user, FileStream in) public long getContentLength() { if (isFile()) - return _files.get(0).getSize(); + return _files.getFirst().getSize(); return 0; } diff --git a/core/webapp/.well-known/security.txt b/core/webapp/.well-known/security.txt new file mode 100644 index 00000000000..2b332e13de9 --- /dev/null +++ b/core/webapp/.well-known/security.txt @@ -0,0 +1,5 @@ +Contact: https://www.labkey.com/about/contact-us/ +Expires: 2030-01-01T00:00:00.000Z +Preferred-Languages: en +Policy: https://www.labkey.org/Documentation/wiki-page.view?name=securityFixEvaluation +Acknowledgements: https://www.labkey.org/Documentation/wiki-page.view?name=securityFixEvaluation