Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,24 @@ public Pattern getPluginPattern() {
* @throws ClassNotFoundException if no such class exists.
*/
private Class< ? > findPluginClass( final String classname ) throws ClassNotFoundException {
return ClassUtil.findClass( m_searchPath, m_externalJars, classname );
final Class< ? > clazz = ClassUtil.findClass( m_searchPath, m_externalJars, classname );
if( !Plugin.class.isAssignableFrom( clazz ) || !isInSearchPath( clazz ) ) {
// Reject with the same error as an unknown class, so that page markup cannot be used to
// load or instantiate arbitrary classpath classes, nor to probe for their presence.
throw new ClassNotFoundException( "Class '" + classname + "' not found in search path!" );
}
return clazz;
}

/**
* Checks whether the package of the given class is one of the packages on the plugin search path.
*
* @param clazz The class to check.
* @return true, if the class' package is on the plugin search path.
*/
private boolean isInSearchPath( final Class< ? > clazz ) {
final Package pkg = clazz.getPackage();
return pkg != null && m_searchPath.contains( pkg.getName() );
}

/** Outputs an HTML-formatted version of a stack trace. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Licensed to the Apache Software Foundation (ASF) under one
import org.apache.wiki.TestEngine;
import org.apache.wiki.api.core.Context;
import org.apache.wiki.api.core.Engine;
import org.apache.wiki.api.exceptions.PluginException;
import org.apache.wiki.api.exceptions.ProviderException;
import org.apache.wiki.api.spi.Wiki;
import org.apache.wiki.pages.PageManager;
Expand Down Expand Up @@ -153,4 +154,16 @@ public void testParserPlugin() throws Exception {
Assertions.assertTrue( SamplePlugin.c_rendered );
}

/** Page markup must not load or instantiate arbitrary classpath classes; only plugins on the search path. */
@Test
public void testInsertArbitraryClass() {
final PluginException timer = Assertions.assertThrows( PluginException.class,
() -> manager.execute( context, "{INSERT java.util.Timer}" ) );
final PluginException missing = Assertions.assertThrows( PluginException.class,
() -> manager.execute( context, "{INSERT java.util.NoSuchClass}" ) );
// Rejected with the same "could not find" error as a nonexistent class, so markup
// cannot be used as a classpath-probing oracle either.
Assertions.assertEquals( missing.getMessage().replace( "NoSuchClass", "Timer" ), timer.getMessage() );
}

}
Loading