Hello, I’m currently applying a Velocity allowlist based on the guide/article below.
In Jira version 10.3.4, it worked well after applying the Velocity Allowlist,
but in Jira version 10.5.0, it did not work properly (array.get(index) does not work).
Below is what I tested.
DTO
// com.test.dto.Address.java
@Getter
@AllArgsConstructor
public class Address {
private String zipcode;
private String city;
}
// com.test.dto.Certificate.java
@Getter
public class Certificate {
private String name;
private LocalDateTime dateIssued;
public Certificate(String name) {
this.name = name;
this.dateIssued = LocalDateTime.now();
}
}
// com.test.dto.User.java
@Getter
@AllArgsConstructor
public class User {
private String nickName;
private int age;
private List<String> hobbies;
private Address address;
private List<Certificate> certificates;
}
Servlet
// com.test.servlet.TestServlet.java
@RequiredArgsConstructor(onConstructor_ = {@Inject})
public class TestServlet extends HttpServlet {
@ComponentImport
private final TemplateRenderer tr;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Map<String, Object> map = new HashMap<>();
map.put("name", "john");
// List of hobbies
List<String> hobbies = List.of("Cooking", "Soccer");
map.put("hobbies", hobbies);
// Address object
Address address = new Address("12345", "USA");
map.put("address", address);
// List of certificates
List<Certificate> certificates = List.of(
new Certificate("Certificate 1"),
new Certificate("Certificate 2"),
new Certificate("Certificate 3")
);
map.put("certificates", certificates);
// User object
User user = new User("john", 30, hobbies, address, certificates);
map.put("user", user);
resp.setContentType("text/html; charset=UTF-8");
tr.render("/test.vm", map, resp.getWriter());
}
}
atlassian-plugin.xml
<velocity-allowlist key="budget-velocity-allowlist" name="Velocity Allowlist">
<method>com.test.dto.Address#getZipCode()</method>
<method>com.test.dto.Address#getCity()</method>
<method>com.test.dto.User#getNickName()</method>
<method>com.test.dto.User#getAge()</method>
<method>com.test.dto.User#getHobbies()</method>
<method>com.test.dto.User#getAddress()</method>
<method>com.test.dto.User#getCertificates()</method>
</velocity-allowlist>
test.vm
// test.vm
<div style="background-color: yellowgreen">
<h2>Velocity Test</h2>
<p>name: $name</p> // john
<br>
<p>hobbies : $hobbies</p> // [Cooking, Soccer]
<p>hobbies.get(1): $hobbies.get(1)</p> //Soccer
<br>
<p>address.getZipcode(): $address.getZipcode()</p> //12345
<p>address.getCity(): $address.getCity()</p> //USA
<br>
<p>certificates.get(0).getName(): $certificates.get(0).getName()</p> // Certificate 1
<p>certificates.get(0).getDateIssued(): $certificates.get(0).getDateIssued()</p> //2025-04-07T10:44:12.283031100
<br>
<p>user.getNickname(): $user.getNickname()</p> // john
<p>user.getAge(): $user.getAge()</p> // 30
<p>user.getHobbies(): $user.getHobbies()</p> // [Cooking, Soccer]
<p>user.getHobbies().get(0): $user.getHobbies().get(0)</p> // Cooking
<p>user.getAddress().getCity(): $user.getAddress().getCity()</p> //USA
<p>user.getCertificates().get(1).getName(): $user.getCertificates().get(1).getName()</p> // Certificate 2
</div>
With the code written as above, it works well in version 10.3.4.
// test.vm
<div style="background-color: yellowgreen">
<h2>Velocity Test</h2>
<p>name: $name</p> // john
<br>
<p>hobbies : $hobbies</p> // [Cooking, Soccer]
<p>hobbies.get(1): $hobbies.get(1)</p>
// just '$hobbies.get(1)'
// $hobbies.get(1) is being rendered as a plain string instead of being evaluated as a variable.
<br>
<p>address.getZipcode(): $address.getZipcode()</p> //12345
<p>address.getCity(): $address.getCity()</p> //USA
<br>
<p>certificates.get(0).getName(): $certificates.get(0).getName()</p> // It's the same issue.
<p>certificates.get(0).getDateIssued(): $certificates.get(0).getDateIssued()</p> //It's the same issue.
<br>
<p>user.getNickname(): $user.getNickname()</p> // john
<p>user.getAge(): $user.getAge()</p> // 30
<p>user.getHobbies(): $user.getHobbies()</p> // [Cooking, Soccer]
<p>user.getHobbies().get(0): $user.getHobbies().get(0)</p> // It's the same issue.
<p>user.getAddress().getCity(): $user.getAddress().getCity()</p> //USA
<p>user.getCertificates().get(1).getName(): $user.getCertificates().get(1).getName()</p> // It's the same issue.
</div>
However, it doesn’t work the same way in version 10.5.0.
How can I access the values of an object array in version 10.5.0?
Thanks.