Skip to content

Commit f5c4dd5

Browse files
committed
Explicitly ban evaluating ObjectMapper within jinjava for
defense-in-depth
1 parent 53fbb69 commit f5c4dd5

2 files changed

Lines changed: 68 additions & 2 deletions

File tree

src/main/java/com/hubspot/jinjava/el/ext/JinjavaBeanELResolver.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.hubspot.jinjava.el.ext;
22

3+
import com.fasterxml.jackson.databind.ObjectMapper;
34
import com.google.common.base.CaseFormat;
45
import com.google.common.collect.ImmutableSet;
56
import com.hubspot.jinjava.interpret.DeferredValueException;
@@ -36,6 +37,7 @@ public class JinjavaBeanELResolver extends BeanELResolver {
3637
.add("notify")
3738
.add("notifyAll")
3839
.add("wait")
40+
.add("readValueAs")
3941
.build();
4042

4143
private static final Set<String> DEFERRED_EXECUTION_RESTRICTED_METHODS = ImmutableSet
@@ -59,6 +61,10 @@ public class JinjavaBeanELResolver extends BeanELResolver {
5961
.add("set")
6062
.add("merge")
6163
.build();
64+
private static final String JAVA_LANG_REFLECT_PACKAGE =
65+
Method.class.getPackage().getName(); // java.lang.reflect
66+
private static final String JACKSON_DATABIND_PACKAGE =
67+
ObjectMapper.class.getPackage().getName(); // com.fasterxml.jackson.databind
6268

6369
/**
6470
* Creates a new read/write {@link JinjavaBeanELResolver}.
@@ -251,9 +257,11 @@ protected boolean isRestrictedClass(Object o) {
251257
return false;
252258
}
253259

260+
Package oPackage = o.getClass().getPackage();
254261
return (
255-
(o.getClass().getPackage() != null &&
256-
o.getClass().getPackage().getName().startsWith("java.lang.reflect")) ||
262+
(oPackage != null &&
263+
(oPackage.getName().startsWith(JAVA_LANG_REFLECT_PACKAGE) ||
264+
oPackage.getName().startsWith(JACKSON_DATABIND_PACKAGE))) ||
257265
o instanceof Class ||
258266
o instanceof ClassLoader ||
259267
o instanceof Thread ||

src/test/java/com/hubspot/jinjava/el/ext/JinjavaBeanELResolverTest.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
import static org.mockito.Mockito.mock;
66
import static org.mockito.Mockito.when;
77

8+
import com.fasterxml.jackson.databind.ObjectMapper;
89
import com.google.common.collect.ImmutableSet;
910
import com.hubspot.jinjava.JinjavaConfig;
1011
import com.hubspot.jinjava.el.JinjavaELContext;
1112
import com.hubspot.jinjava.interpret.AutoCloseableSupplier;
1213
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
14+
import java.util.List;
1315
import javax.el.ELContext;
1416
import javax.el.MethodNotFoundException;
1517
import javax.el.PropertyNotFoundException;
@@ -186,4 +188,60 @@ public void itDoesNotAllowAccessingPropertiesOfInterpreter() {
186188
.isNull();
187189
}
188190
}
191+
192+
@Test
193+
public void itDoesNotGettingFromObjectMapper() {
194+
try (
195+
AutoCloseableSupplier.AutoCloseableImpl<JinjavaInterpreter> c = JinjavaInterpreter
196+
.closeablePushCurrent(interpreter)
197+
.get()
198+
) {
199+
assertThat(
200+
jinjavaBeanELResolver.getValue(elContext, new ObjectMapper(), "dateFormat")
201+
)
202+
.isNull();
203+
}
204+
}
205+
206+
@Test
207+
public void itDoesNotAllowInvokingFromObjectMapper() throws NoSuchMethodException {
208+
try (
209+
AutoCloseableSupplier.AutoCloseableImpl<JinjavaInterpreter> c = JinjavaInterpreter
210+
.closeablePushCurrent(interpreter)
211+
.get()
212+
) {
213+
ObjectMapper objectMapper = new ObjectMapper();
214+
assertThatThrownBy(() ->
215+
jinjavaBeanELResolver.invoke(
216+
elContext,
217+
objectMapper,
218+
"getDateFormat",
219+
new Class[] {},
220+
new Object[] {}
221+
)
222+
)
223+
.isInstanceOf(MethodNotFoundException.class);
224+
}
225+
}
226+
227+
@Test
228+
public void itDoesNotAllowInvokingFromMethod() throws NoSuchMethodException {
229+
try (
230+
AutoCloseableSupplier.AutoCloseableImpl<JinjavaInterpreter> c = JinjavaInterpreter
231+
.closeablePushCurrent(interpreter)
232+
.get()
233+
) {
234+
List<String> list = List.of("foo");
235+
assertThatThrownBy(() ->
236+
jinjavaBeanELResolver.invoke(
237+
elContext,
238+
list.getClass().getMethod("get", int.class),
239+
"invoke",
240+
new Class[] { Object.class, Object[].class },
241+
new Object[] { list, 0 }
242+
)
243+
)
244+
.isInstanceOf(MethodNotFoundException.class);
245+
}
246+
}
189247
}

0 commit comments

Comments
 (0)