Zimbra Sanitizer Flow

How Zimbra Sanitizes E-Mail Content

Nil Seri
3 min readJan 26, 2021
Photo by frank mckenna on Unsplash

When we search through Zimbra sanitizer code, there is a config key named “zimbra_use_owasp_html_sanitizer”.

Related dependencies that are in our Local Zimbra version (you can see my post about installing Zimbra as a local project here):

<dependency org="org.owasp.antisamy" name="antisamy" rev="1.5.3"/><dependency org="com.googlecode.owasp-java-html-sanitizer" name="owasp-java-html-sanitizer" rev="20190610.1"/>

https://github.com/Zimbra/zm-mailbox/blob/develop/store/src/java/com/zimbra/cs/html/owasp/OwaspDefang.java

From the class we see above, we come across the following class:

https://github.com/Zimbra/zm-mailbox/blob/develop/store/src/java/com/zimbra/cs/html/owasp/OwaspHtmlSanitizer.java

When we search for config key in Zimbra forums, we come across these links:

https://forums.zimbra.org/viewtopic.php?t=66613&start=10

https://forums.zimbra.org/viewtopic.php?t=66937

https://forums.zimbra.org/viewtopic.php?t=66409&start=60, there is a comment like this:

No, there aren’t any security implications after disabling the owasp sanitizer. When you disable it, the defanger is active and protects the system. Owasp sanitizer introduces performance enhancement over defanger but there are no such known security issues which are introduced after disabling the owasp sanitizer.

When we disable OWASP, the other existing HTML sanitizer is being used..

https://github.com/Zimbra/zm-mailbox/blob/develop/store/src/java/com/zimbra/cs/html/DefangFactory.java, here you can search for “isOwaspEnabled”.

https://github.com/Zimbra/zm-mailbox/blob/develop/build.xml has these config files:

<copy file=”${zm-mailbox.basedir}/store-conf/conf/antisamy.xml” todir=”${build.dir}/zimbra/conf/”/>
<copy file=”${zm-mailbox.basedir}/store-conf/conf/owasp_policy.xml” todir=”${build.dir}/zimbra/conf/”/>

For example, https://github.com/Zimbra/zm-mailbox/blob/develop/store/src/java/com/zimbra/cs/html/owasp/policies/StyleTagReceiver.java uses “antisamyXML” policy file inside.

Example file contents:

https://github.com/Zimbra/zm-mailbox/blob/develop/store-conf/conf/owasp_policy.xml

https://github.com/Zimbra/zm-mailbox/blob/develop/store-conf/conf/antisamy.xml

You can also search for these files if you installed Zimbra as a local project.

https://github.com/OWASP/java-html-sanitizer is being used. As well as its own policies, inside https://github.com/Zimbra/zm-mailbox/blob/develop/store/src/java/com/zimbra/cs/html/owasp/HtmlElementsBuilder.java Zimbra custom policies are also registered.

Zimbra’s custom policies for OWASP is under the folder:

https://github.com/Zimbra/zm-mailbox/tree/develop/store/src/java/com/zimbra/cs/html/owasp/policies

We cannot add our own configurations externally. What we can change are only the files owasp_policy.xml under the path /opt/zimbra/conf(https://github.com/Zimbra/zm-mailbox/blob/develop/store/src/java/com/zimbra/cs/html/owasp/OwaspPolicy.java da kullanılıyor) and antisamy.xml (https://github.com/Zimbra/zm-mailbox/blob/develop/store/src/java/com/zimbra/cs/html/owasp/policies/StyleTagReceiver.java da kullanılıyor); but the corrupt mail content problem does not come out of here. “writeCloseTag” method in “HtmlStreamRenderer” class in OWASP Java Html Sanitizer causes the problem.

The breakpoint is the exact place where the mail content gets all mixed up (the above code will add “td” at the end of the line and later will close all the other tags):

The problem here is that for OWASP, a tag has another a tag in it. When we set “zmlocalconfig -e zimbra_use_owasp_html_sanitizer=false”, the content appears just fine again:

Corrupt Content:

Back to Normal:

The place where button exists in Instagram mail:

Initial html output:

<tr><td style=""><a href="https://instagram.com/accounts/confirm_email/21S7pC3b/dWZ1a0B5cG9zdGEubmV0/?app_redirect=False" style="color:#3b5998;text-decoration:none;display:block;width:370px;"><table border="0" width="390" cellspacing="0" cellpadding="0" style="border-collapse:collapse;"><tr><td style="border-collapse:collapse;border-radius:3px;text-align:center;display:block;border:solid 1px #009fdf;padding:10px 16px 14px 16px;margin:0 2px 0 auto;min-width:80px;background-color:#47A2EA;"><a href="https://instagram.com/accounts/confirm_email/21S7pC3b/dWZ1a0B5cG9zdGEubmV0/?app_redirect=False" style="color:#3b5998;text-decoration:none;display:block;"><center><font size="3"><span style="font-family:Helvetica Neue,Helvetica,Roboto,Arial,sans-serif;white-space:nowrap;font-weight:bold;vertical-align:middle;color:#fdfdfd;font-size:16px;line-height:16px;">Confirm Email Address</span></font></center></a></td></tr></table></a></td></tr>

Final html output:

<tr><td><a href="https://instagram.com/accounts/confirm_email/21S7pC3b/dWZ1a0B5cG9zdGEubmV0/?app_redirect=False" style="color:#3b5998;text-decoration:none;display:block;width:370px" target="_blank" rel="nofollow noopener noreferrer"><table border="0" width="390" cellspacing="0" cellpadding="0" style="border-collapse:collapse"><tbody><tr><td style="border-collapse:collapse;border-radius:3px;text-align:center;display:block;border:solid 1px #009fdf;padding:10px 16px 14px 16px;margin:0 2px 0 auto;min-width:80px;background-color:#47a2ea"></td></tr></tbody></table></a><a href="https://instagram.com/accounts/confirm_email/21S7pC3b/dWZ1a0B5cG9zdGEubmV0/?app_redirect=False" style="color:#3b5998;text-decoration:none;display:block" target="_blank" rel="nofollow noopener noreferrer"><center><font size="3"><span style="font-family:'helvetica neue' , 'helvetica' , 'roboto' , 'arial' , sans-serif;white-space:nowrap;font-weight:bold;vertical-align:middle;color:#fdfdfd;font-size:16px;line-height:16px">Confirm Email Address</span></font></center></a></td></tr>

To check the existing config value, you can run this command:

sudo -u zimbra /opt/zimbra/bin/zmlocalconfig -s | grep zimbra_use_owasp_html_sanitizer

Happy Coding!

--

--

Nil Seri
Nil Seri

Written by Nil Seri

I would love to change the world, but they won’t give me the source code | coding 👩🏻‍💻 | coffee ☕️ | jazz 🎷 | anime 🐲 | books 📚 | drawing 🎨

No responses yet