You can implement a function and then call it via %{} expression like this:
<s:property value="%{sanitize(actionError)}"/>
The only way I can get this to work is to use jstl <c:out >
#####
safeEscapeHTML(s){return Jsoup.clean(s, "", Safelist.simpleText().addTags("br"),new
Document.OutputSettings().prettyPrint(false));}
####
<s:property value="%{safeEscapeHTML(#actionError)}" escapeHtml="true" />
No entries were found using the term <b>test</b>. Please try again.
####
This works
<%
pageContext.setAttribute ("utils", new my.Utilities());
%>
<c:out value="${utils.safeEscapeHTML(requestScope.actionError)}"
escapeXml="false"/>
No entries were found using the term *test*. Please try again.
####
>Yes, exactly that's what WW-5639 proposes. The four flags become
>mutually exclusive and exactly one escaper is applied, by first-match
>precedence:
>escapeHtml -> escapeJavaScript -> escapeXml -> escapeCsv
Not setting escapeHtml -> escapeJavaScript -> escapeXml ->
escapeCsv may generate lots of warnings, and would probably break stuff
if set, especially if showing js code eg for a blog post.
Alas, there does not seem to be a way I can find to safely use html
with <s:property > tag.
On 29/06/2026 20:27, Lukasz Lenart wrote:
sob., 27 cze 2026 o 10:58 Greg Huber<[email protected]> napisał(a):
If we can fix this then good.
If I understand it correctly, escapehtml=false, then apply either
escapeJavaScript or escapeXml or escapeCsv ?
Yes, exactly that's what WW-5639 proposes. The four flags become
mutually exclusive and exactly one escaper is applied, by first-match
precedence:
escapeHtml -> escapeJavaScript -> escapeXml -> escapeCsv
Since escapeHtml defaults to true, the default (HTML-escape only)
doesn't change. The only outputs that change are the broken combos
that were already producing corrupt double-/cross-escaped results,
like the <b><\/b> you hit.
I did try this, (escapeHtml -> escapeJavaScript) but was left with the
unterminated html
the quick fix I used for the layout problem, was to drop
escapeJavaScript add an additional escape on any field that returned
into the response (with escapehtml=false)
s = Strings.CS.replace(s, "\"", """);
s = Strings.CS.replace(s, "<", "<");
s = Strings.CS.replace(s, ">", ">");
Probably not the correct way comparing with commons.text
escapeEcmaScript (the experts), but escaping js correctly and make it
play nicely seems a minefield.
I want to flag two things, because I don't think this ticket gives you
what you're actually after:
escapeJavaScript is not XSS protection. It escapes only ' " \ / and
control chars, it does NOT touch <, > or &. So escapeHtml=false +
escapeJavaScript=true still emits a live <script> into the page. The
real exposure is escapeHtml=false itself, which outputs raw HTML and
is unsafe unless the value is fully trusted. So the "warning" we
discussed shouldn't say "set escapeJavaScript=true", that's a false
sense of safety.
"Allow <b>/<strong>, block <script>" can't be done with these flags.
Escaping HTML and allowing HTML markup are opposite output contexts -
that's why escapeHtml=false + escapeJavaScript=true mangles the
closing tags. What you want is an allowlist HTML sanitizer (e.g. OWASP
Java HTML Sanitizer), applied to the value before output, with
escapeHtml=false on a value you've already sanitized. That keeps
<b>/<strong>/<em> and strips/encodes <script>. The property tag's
escape flags aren't the right tool for it.
Your manual workaround (escaping " < >) is safe, but note it's
effectively just escapeHtml=true again, so <b> will render literally
rather than bold. Fine if you don't actually need the formatting on
those fields.
So WW-5639 makes the tag's behavior predictable and stops the
corruption, plus updates the docs/JavaDoc and adds a devMode warning
when more than one flag is set. It just won't, by itself, give you
"formatting yes, scripts no" that needs the sanitizer.
You can implement a function and then call it via %{} expression like this:
<s:property value="%{sanitize(actionError)}"/>
Cheers
Łukasz
---------------------------------------------------------------------
To unsubscribe, e-mail:[email protected]
For additional commands, e-mail:[email protected]