Skip to content

Commit 59d9f2d

Browse files
committed
Explicitly ban evaluating ObjectMapper within jinjava for
defense-in-depth
1 parent e6465cb commit 59d9f2d

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,10 +5,12 @@
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.JinjavaInterpreter;
13+
import java.util.List;
1214
import javax.el.ELContext;
1315
import javax.el.MethodNotFoundException;
1416
import javax.el.PropertyNotFoundException;
@@ -184,4 +186,60 @@ public void itDoesNotAllowAccessingPropertiesOfInterpreter() {
184186
JinjavaInterpreter.popCurrent();
185187
}
186188
}
189+
190+
@Test
191+
public void itDoesNotGettingFromObjectMapper() {
192+
try (
193+
AutoCloseableSupplier.AutoCloseableImpl<JinjavaInterpreter> c = JinjavaInterpreter
194+
.closeablePushCurrent(interpreter)
195+
.get()
196+
) {
197+
assertThat(
198+
jinjavaBeanELResolver.getValue(elContext, new ObjectMapper(), "dateFormat")
199+
)
200+
.isNull();
201+
}
202+
}
203+
204+
@Test
205+
public void itDoesNotAllowInvokingFromObjectMapper() throws NoSuchMethodException {
206+
try (
207+
AutoCloseableSupplier.AutoCloseableImpl<JinjavaInterpreter> c = JinjavaInterpreter
208+
.closeablePushCurrent(interpreter)
209+
.get()
210+
) {
211+
ObjectMapper objectMapper = new ObjectMapper();
212+
assertThatThrownBy(() ->
213+
jinjavaBeanELResolver.invoke(
214+
elContext,
215+
objectMapper,
216+
"getDateFormat",
217+
new Class[] {},
218+
new Object[] {}
219+
)
220+
)
221+
.isInstanceOf(MethodNotFoundException.class);
222+
}
223+
}
224+
225+
@Test
226+
public void itDoesNotAllowInvokingFromMethod() throws NoSuchMethodException {
227+
try (
228+
AutoCloseableSupplier.AutoCloseableImpl<JinjavaInterpreter> c = JinjavaInterpreter
229+
.closeablePushCurrent(interpreter)
230+
.get()
231+
) {
232+
List<String> list = List.of("foo");
233+
assertThatThrownBy(() ->
234+
jinjavaBeanELResolver.invoke(
235+
elContext,
236+
list.getClass().getMethod("get", int.class),
237+
"invoke",
238+
new Class[] { Object.class, Object[].class },
239+
new Object[] { list, 0 }
240+
)
241+
)
242+
.isInstanceOf(MethodNotFoundException.class);
243+
}
244+
}
187245
}

0 commit comments

Comments
 (0)