VYPR
Moderate severityNVD Advisory· Published Aug 26, 2022· Updated Aug 3, 2024

CVE-2021-3856

CVE-2021-3856

Description

ClassLoaderTheme and ClasspathThemeResourceProviderFactory allows reading any file available as a resource to the classloader. By sending requests for theme resources with a relative path from an external HTTP client, the client will receive the content of random files if available.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.keycloak:keycloak-coreMaven
< 15.1.015.1.0

Affected products

1

Patches

1
73f0474008e1

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

https://github.com/keycloak/keycloakDouglas PalmerOct 14, 2021via ghsa
3 files changed · +37 3
  • services/src/main/java/org/keycloak/theme/ClassLoaderTheme.java+13 2 modified
    @@ -105,8 +105,19 @@ public URL getTemplate(String name) {
         }
     
         @Override
    -    public InputStream getResourceAsStream(String path) {
    -        return classLoader.getResourceAsStream(resourceRoot + path);
    +    public InputStream getResourceAsStream(String path) throws IOException {
    +        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
    
  • services/src/main/java/org/keycloak/theme/ClasspathThemeResourceProviderFactory.java+12 1 modified
    @@ -39,7 +39,18 @@ public URL getTemplate(String name) throws IOException {
     
         @Override
         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
    
  • testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/theme/ThemeResourceProviderTest.java+12 0 modified
    @@ -73,6 +73,18 @@ public void getMessages() {
             });
         }
     
    +    @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
         public void gzipEncoding() throws IOException {
             final String resourcesVersion = testingClient.server().fetch(session -> Version.RESOURCES_VERSION, String.class);
    

Vulnerability mechanics

Synthesis attempt was rejected by the grounding validator. Re-run pending.

References

7

News mentions

0

No linked articles in our index yet.