Skip to content

Enforce path containment in FolderTheme.getTemplate()#50098

Open
MdTanwer wants to merge 10 commits into
keycloak:mainfrom
MdTanwer:fix/folder-theme-path-containment-49961
Open

Enforce path containment in FolderTheme.getTemplate()#50098
MdTanwer wants to merge 10 commits into
keycloak:mainfrom
MdTanwer:fix/folder-theme-path-containment-49961

Conversation

@MdTanwer

Copy link
Copy Markdown

Summary

  • Route FolderTheme.getTemplate() through ResourceLoader.getFile() for parity with getResourceAsStream()
  • Reject template names containing ../ or encoded traversal sequences that escape themeDir
  • Add testGetTemplatePathContainment covering valid and traversal paths

Test plan

Route template resolution through ResourceLoader.getFile() so getTemplate()
applies the same normalization and root-path guard as getResourceAsStream().

Closes keycloak#49961

Co-authored-by: Cursor <cursoragent@cursor.com>
@MdTanwer MdTanwer marked this pull request as ready for review June 18, 2026 05:26
@MdTanwer MdTanwer requested a review from a team as a code owner June 18, 2026 05:26
Copilot AI review requested due to automatic review settings June 18, 2026 05:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens theme template resolution by ensuring FolderTheme.getTemplate() enforces path containment (consistent with getResourceAsStream()), preventing ../-style traversal from escaping the theme directory. It also adds a regression test to validate both valid and traversal-like template names.

Changes:

  • Route FolderTheme.getTemplate() through ResourceLoader.getFile(...) to apply the existing containment check.
  • Add a new FolderThemeTest.testGetTemplatePathContainment covering a normal template and traversal/encoded traversal-like names.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
services/src/main/java/org/keycloak/theme/FolderTheme.java Uses ResourceLoader.getFile(themeDir, name) to enforce path containment when resolving templates.
services/src/test/java/org/keycloak/theme/FolderThemeTest.java Adds a regression test for template path containment behavior.

Comment thread services/src/test/java/org/keycloak/theme/FolderThemeTest.java
MdTanwer and others added 2 commits June 18, 2026 06:33
Initialize FreeMarker with the bundled VERSION_2_3_32 to avoid legacy 2.3.0 defaults and opt into current security and correctness improvements.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: MdTanwer <122739350+MdTanwer@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 18, 2026 11:41
@MdTanwer MdTanwer requested a review from michalvavrik June 18, 2026 11:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comment thread services/src/test/java/org/keycloak/theme/FolderThemeTest.java Outdated
assertNotNull(theme.getTemplate("login.ftl"));
assertNull(theme.getTemplate(NONE + "forbidden.ftl"));
assertNull(theme.getTemplate(SINGLE + "forbidden.ftl"));
assertNull(theme.getTemplate(DOUBLE + "forbidden.ftl"));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not testing changes as it is passing without your fix.


assertNotNull(theme.getTemplate("login.ftl"));
assertNull(theme.getTemplate(NONE + "forbidden.ftl"));
assertNull(theme.getTemplate(SINGLE + "forbidden.ftl"));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here - This is not testing changes as it is passing without your fix.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the test to follow ResourceLoaderTest — using assertGetTemplate(..., false, true) for ../forbidden.ftl so we prove the file exists outside themeDir but is rejected, and removed the encoded literal path checks that passed without the fix.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: MdTanwer <122739350+MdTanwer@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 19, 2026 02:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comment thread services/src/test/java/org/keycloak/theme/FolderThemeTest.java Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: MdTanwer <122739350+MdTanwer@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 19, 2026 03:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comment thread services/src/test/java/org/keycloak/theme/FolderThemeTest.java Outdated
public void testGetTemplatePathContainment() throws Exception {
Path tempDirectory = Files.createTempDirectory("folder-theme-test");
File themeDir = new File(tempDirectory.toFile(), "login");
org.junit.Assert.assertTrue("Failed to create theme directory: " + themeDir, themeDir.mkdirs());
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: MdTanwer <122739350+MdTanwer@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 19, 2026 03:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comment thread services/src/test/java/org/keycloak/theme/FolderThemeTest.java Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: MdTanwer <122739350+MdTanwer@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 19, 2026 03:09

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Use assertGetTemplate with expectFileToExist so the regression test
proves the target file exists outside themeDir but is rejected. Remove
encoded literal path assertions that passed without the fix.

Closes keycloak#49961
@MdTanwer MdTanwer force-pushed the fix/folder-theme-path-containment-49961 branch from d407cbc to 795204d Compare June 19, 2026 03:52
@MdTanwer MdTanwer requested a review from michalvavrik June 19, 2026 03:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Themes: FolderTheme.getTemplate() missing path-containment check

3 participants