diff --git a/jspwiki-main/src/main/java/org/apache/wiki/plugin/IfPlugin.java b/jspwiki-main/src/main/java/org/apache/wiki/plugin/IfPlugin.java index 5c33257449..d4a749a50e 100644 --- a/jspwiki-main/src/main/java/org/apache/wiki/plugin/IfPlugin.java +++ b/jspwiki-main/src/main/java/org/apache/wiki/plugin/IfPlugin.java @@ -27,10 +27,12 @@ Licensed to the Apache Software Foundation (ASF) under one import org.apache.oro.text.regex.Perl5Compiler; import org.apache.oro.text.regex.Perl5Matcher; import org.apache.wiki.api.core.Context; +import org.apache.wiki.api.core.Page; import org.apache.wiki.api.exceptions.PluginException; import org.apache.wiki.api.plugin.Plugin; import org.apache.wiki.api.providers.WikiProvider; import org.apache.wiki.auth.AuthorizationManager; +import org.apache.wiki.auth.permissions.PermissionFactory; import org.apache.wiki.pages.PageManager; import org.apache.wiki.render.RenderingManager; import org.apache.wiki.util.HttpUtil; @@ -190,7 +192,15 @@ public static boolean ifInclude( final Context context, final Map< String, Strin include |= checkIP(context, ip); if( page != null ) { - final String content = context.getEngine().getManager( PageManager.class ).getPureText(page, WikiProvider.LATEST_VERSION).trim(); + // Only read the target page's content if the requesting session is allowed to view it; + // otherwise behave exactly as if the content did not match, so ACL-protected content + // cannot be probed through the contains/is parameters. + String content = null; + final Page testedPage = context.getEngine().getManager( PageManager.class ).getPage( page ); + if( testedPage != null && context.getEngine().getManager( AuthorizationManager.class ) + .checkPermission( context.getWikiSession(), PermissionFactory.getPagePermission( testedPage, "view" ) ) ) { + content = context.getEngine().getManager( PageManager.class ).getPureText(page, WikiProvider.LATEST_VERSION).trim(); + } include |= checkContains(content,contains); include |= checkIs(content,is); include |= checkExists(context,page,exists); diff --git a/jspwiki-main/src/test/java/org/apache/wiki/plugin/IfPluginTest.java b/jspwiki-main/src/test/java/org/apache/wiki/plugin/IfPluginTest.java index 0f06c5a43b..8002e5ce95 100644 --- a/jspwiki-main/src/test/java/org/apache/wiki/plugin/IfPluginTest.java +++ b/jspwiki-main/src/test/java/org/apache/wiki/plugin/IfPluginTest.java @@ -44,6 +44,7 @@ class IfPluginTest { @AfterEach public void tearDown() throws Exception { testEngine.getManager( PageManager.class ).deletePage( "Test" ); + testEngine.getManager( PageManager.class ).deletePage( "SecretPage" ); } /** @@ -168,4 +169,25 @@ void testIfPluginIPNotAllowed() throws WikiException { Assertions.assertEquals( expected, res ); } + /** + * Checks that an ACL-protected page cannot be probed through the contains parameter: + * a denied page must behave exactly as if its content did not match. + * + * @throws WikiException test Assertions.failing. + */ + @Test + void testIfPluginContainsAclProtectedPageNotLeaked() throws WikiException { + testEngine.saveText( "SecretPage", "[{ALLOW view Alice}]\nxyzzy" ); + + final String src = "[{IfPlugin page='SecretPage' contains='xyzzy'\n\nSecret page contains xyzzy}]"; + final String expected = "\n"; + + testEngine.saveText( "Test", src ); + final Page page = testEngine.getManager( PageManager.class ).getPage( "Test", PageProvider.LATEST_VERSION ); + final Context context = getJanneBasedWikiContextFor( page ); + + final String res = testEngine.getManager( RenderingManager.class ).getHTML( context, page ); + Assertions.assertEquals( expected, res ); + } + }