
Template Injection in Email Templates leads to code execution on Jira Service Management Server
Template Injection in Email Templates leads to code execution on Jira Service Management Server
I have provided a guide for deployment + debug here, you can refer to it.
The Description of this CVE already clearly states that the bug lies in the Email Template feature. With admin privileges, users can arbitrarily modify templates of notification emails. This bug requires admin privileges to execute, so even if it leads to RCE, it is not very critical, but I still decided to write this blog for fun :) those who are learning SSTI can refer to it.
atlassian-jira-servicedesk-4.17.0-m0006-standalone and tried to diff it with version 4.18.0 to see what's different:

When I saw this pile, ... of course I don't read each file one by one, I'm too lazy. Just kidding, actually besides the security fix, the versions also have upgrades and changes in features. If I diff everything and then sit down to read it, that's very time-consuming. Of course, in some cases I have to diff everything and read it, but for this case I didn't do that =)))
SendBulkMail feature to create a notification email. I will not mention the stack call of this endpoint to avoid being too lengthy, as it is similar to the stack call in CVE-2019-11581At the SimpleNote.render function, I can look at the context variable to see what I can take advantage of:
Based on my own experience, I pay attention to checking contexts/classes that have keywords like: Utils, Manager, service, ... . I noticed a context $jirautils (class com.atlassian.jira.util.JiraUtils) contains the method public static <T> T loadComponent(String className, Class<?> callingClass) :
I wandered around looking for docs to read about its functionality and how to use it, because the input is a String className and the output is a class, so it is very likely that this method can load classes arbitrarily:
I went to System -> Email templates and downloaded the current template file to my machine
There are many different templates, each used for a specific type of notification, so I looked for a file that can be shared across multiple notification types, such as email\html\includes\header.vm
After uploading the modified template file, and using SendBulkMail to send a notification email, I received the output in the email like this:
Basically, this class has no constructors or is not accepted. I tried using another class that has constructors (no-arg constructors) to see what happens:
And the result was as expected. I successfully obtained the class:
We see that 3 classes were added to the blacklist:
org.springframework.expression.spel.standard.SpelExpressionParser,\
com.atlassian.jira.component.ComponentAccessor,\
com.atlassian.jira.plugin.ComponentClassManager
When checking each class, I noticed that the SpelExpressionParser class has the method public SpelExpression parseRaw(String expressionString). After a quick Google search to find how to use it, basically it can be used like this:
#set($SpelExpressionParser = $jirautils.loadComponent('org.springframework.expression.spel.standard.SpelExpressionParser',$i18n.getClass()))
$SpelExpressionParser.parseRaw("T(java.lang.Runtime).getRuntime().exec('calc')")
As you can see, the parseRaw function returns an object of the class org.springframework.expression.spel.standard.SpelExpression, but it hasn't actually rendered the expression I provided. I looked into the SpelExpression class and found the method getValue:
@Nullable
public Object getValue() throws EvaluationException {
CompiledExpression compiledAst = this.compiledAst;
if (compiledAst != null) {
try {
EvaluationContext context = this.getEvaluationContext();
return compiledAst.getValue(context.getRootObject().getValue(), context);
} catch (Throwable var4) {
if (this.configuration.getCompilerMode() != SpelCompilerMode.MIXED) {
throw new SpelEvaluationException(var4, SpelMessage.EXCEPTION_RUNNING_COMPILED_EXPRESSION, new Object[0]);
}
}