OS: Pop!_OS 22.04
Java Version: 25
Tomcat Version: 11
Lucee Version: 7.0.5.41 RELEASE
ESAPI Version: 2.6.0.1
Every attempt to load any extension details page results in error:
OSGi Bundle with the name [esapi.extension] and the version [3.0.0.14] was no class with name [org.lucee.extension.guard.functions.SanitizeHTML] found.
The similarity to LDEV-6101 is most likely a red herring.
The error is thrown by line 116 in Lucee/core/src/main/cfml/context/admin/ext.applications.detail.cfm at 7.0.5.4 · lucee/Lucee · GitHub
#sanitizehtml(replace(trim(app.description),chr(10),"<br />","all"),'FORMATTING')#
The root cause appears to be that the ESAPI version is hardcoded to 3.0.0.14 in the Java bytecode of /opt/lucee/tomcat/lucee-server/context/context/lucee-admin.lar.
Probably that was pulled from the manifest during build?
ESAPI v3 is a major roadblock for me and I would expect for many other Lucee devs due to missing support for common html tags such as <img> via HtmlPolicyBuilder.
I’m able to edit extension properties by editing .CFConfig.json, but obviously the Lucee Admin UI interface is quite often useful and even preferred.
Can this issue can be resolved somehow?
I decided to try again at getting my apps working with 3.0.0.14, and this time found success.
I had been doing this:
Application.objHtmlPolicyBuilder = CreateObject("java", "org.owasp.html.HtmlPolicyBuilder");
Application.SafeHtmlPolicy = Application.objHtmlPolicyBuilder.init()
.allowElements(["img"])
.allowAttributes(["alt", "src"]).onElements(["img"])
// various other allowances
.toFactory();
[...]
html = '<img src="https://example.com/foo.jpg">';
cleanHtml = html.SanitizeHTML(Application.SafeHtmlPolicy);
The solution was to use the Java object’s sanitize method instead of Lucee’s SanitizeHtml:
cleanHtml = Application.SafeHtmlPolicy.sanitize(html);
When I tried create an instance like this it just didn’t work. The Bundle was never recognized.
var oPolicyBuilder = CreateObject( “java”, “org.owasp.html.HtmlPolicyBuilder”)
When I did it this way it worked and downloaded the jar on its own.
var oPolicyBuilder = CreateObject( “java”, “org.owasp.html.HtmlPolicyBuilder”, { maven: [ “com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20260313.1”] } )
Yes I had to do that in the past and was surprised when I didn’t need to specify the Maven version after installing 7.0.5.41. I wonder if it’s because I installed with a fresh .jar into lib folder instead of a patch.
@kenricashe I don’t think the jar install vs. patch is the reason. When you call createObject("java", "org.owasp.html.HtmlPolicyBuilder") without coordinates, Lucee uses whatever copy of that library it happens to find on that server. Which copy that is depends on which extensions are installed, and in which versions. The ESAPI 3.0.0.14 extension doesn’t ship the OWASP sanitizer itself, so when the plain name worked, it was picking up a copy from somewhere else on that install. That’s why it can work on one server and not on the next.
The reliable way is to ask for it explicitly with Maven coordinates, like @apenhorwood showed, or once for the whole app in Application.cfc:
this.javaSettings = {
maven: [ "com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20260313.1" ]
};
Then Lucee loads that exact version, and it behaves the same on every install, whatever else is installed. More on this: Loading Java Libraries with Maven :: Lucee Documentation
When I put the bundle in manually I had to make sure the file was named:
com.googlecode.owasp-java-html-sanitizer-20260313.1.0.jar
even though it was named owasp-java-html-sanitizer-20260313.1.0.jar from the download.
The system ignored the bundle until I renamed it. Before this moment I thought the name of the file didn’t really matter.
normally the name should not matter, it always checks the bundle name and version in the manifest.
@GianTschingt can you check that?
I checked this in the source (7.0 and 7.1) and tried it on 7.0.5.41 and 7.1.0.204. The file name doesn’t matter. Lucee reads the manifest of every jar in the bundles folder, so owasp-java-html-sanitizer-20260313.1.0.jar and com.googlecode.owasp-java-html-sanitizer-20260313.1.0.jar were found and loaded the same way. When Lucee finds a bundle by name and version, it renames the file itself to com.googlecode.owasp-java-html-sanitizer-20260313.1.0.jar, which may be why that name turned up.
What does matter with this library: the 20260313.1 jar from Maven Central needs two packages that aren’t inside it, javax.annotation (jsr305) and org.owasp.shim. The shim jars aren’t OSGi bundles, so with only the sanitizer jar in the bundles folder it can’t resolve, and the plain createObject just says no definition for the class could be found. Once that has failed, it keeps failing until a restart, even if the missing jars are added later, so a restart around the same time as the rename would explain what you saw.
I’ve filed that as LDEV-6526: the plain path should show the real resolve error, and it should retry loading the dependencies after a failed resolve instead of failing until a restart.
For this library the Maven route (this.javaSettings = { maven: [...] }, or the struct argument @apenhorwood showed) is the easiest. It pulls in the shims as plain jars and doesn’t need OSGi to resolve anything.