[KEYCLOAK-19422] ClassLoaderTheme and ClasspathThemeResourceProviderFactory allows reading any file available as a resource to the classloader

This commit is contained in:
Douglas Palmer 2021-10-14 15:47:57 -07:00 committed by Stian Thorgersen
parent 7d0af8519b
commit 73f0474008
3 changed files with 37 additions and 3 deletions

View file

@ -105,8 +105,19 @@ public class ClassLoaderTheme implements Theme {
} }
@Override @Override
public InputStream getResourceAsStream(String path) { public InputStream getResourceAsStream(String path) throws IOException {
return classLoader.getResourceAsStream(resourceRoot + path); final URL rootResourceURL = classLoader.getResource(resourceRoot);
if (rootResourceURL == null) {
return null;
}
final String rootPath = rootResourceURL.getPath();
final URL resourceURL = classLoader.getResource(resourceRoot + path);
if(resourceURL == null || !resourceURL.getPath().startsWith(rootPath)) {
return null;
}
else {
return resourceURL.openConnection().getInputStream();
}
} }
@Override @Override

View file

@ -39,7 +39,18 @@ public class ClasspathThemeResourceProviderFactory implements ThemeResourceProvi
@Override @Override
public InputStream getResourceAsStream(String path) throws IOException { public InputStream getResourceAsStream(String path) throws IOException {
return classLoader.getResourceAsStream(THEME_RESOURCES_RESOURCES + path); final URL rootResourceURL = classLoader.getResource(THEME_RESOURCES_RESOURCES);
if (rootResourceURL == null) {
return null;
}
final String rootPath = rootResourceURL.getPath();
final URL resourceURL = classLoader.getResource(THEME_RESOURCES_RESOURCES + path);
if(resourceURL == null || !resourceURL.getPath().startsWith(rootPath)) {
return null;
}
else {
return resourceURL.openConnection().getInputStream();
}
} }
@Override @Override

View file

@ -73,6 +73,18 @@ public class ThemeResourceProviderTest extends AbstractTestRealmKeycloakTest {
}); });
} }
@Test
public void getResourceIllegalTraversal() {
testingClient.server().run(session -> {
try {
Theme theme = session.theme().getTheme("base", Theme.Type.LOGIN);
Assert.assertNull(theme.getResourceAsStream("../templates/test.ftl"));
} catch (IOException e) {
Assert.fail(e.getMessage());
}
});
}
@Test @Test
public void gzipEncoding() throws IOException { public void gzipEncoding() throws IOException {
final String resourcesVersion = testingClient.server().fetch(session -> Version.RESOURCES_VERSION, String.class); final String resourcesVersion = testingClient.server().fetch(session -> Version.RESOURCES_VERSION, String.class);