Skip to content

Commit

Permalink
Prevent execution of remote code via mapping of parameters to arbitra…
Browse files Browse the repository at this point in the history
…ry beans.
  • Loading branch information
scottfrederick committed Jun 6, 2018
1 parent e1bedc1 commit 389874b
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,6 @@ public AsyncParameterizedServiceInstanceRequest(Map<String, Object> parameters,
}

public <T> T getParameters(Class<T> cls) {
try {
T bean = cls.newInstance();
BeanUtils.populate(bean, parameters);
return bean;
} catch (Exception e) {
throw new IllegalArgumentException("Error mapping parameters to class of type " + cls.getName(), e);
}
return ParameterBeanMapper.mapParametersToBean(parameters, cls);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,7 @@ public CreateServiceInstanceBindingRequest(String serviceDefinitionId, String pl
}

public <T> T getParameters(Class<T> cls) {
try {
T bean = cls.newInstance();
BeanUtils.populate(bean, parameters);
return bean;
} catch (Exception e) {
throw new IllegalArgumentException("Error mapping parameters to class of type " + cls.getName());
}
return ParameterBeanMapper.mapParametersToBean(parameters, cls);
}

public CreateServiceInstanceBindingRequest withServiceDefinition(final ServiceDefinition serviceDefinition) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.cloud.servicebroker.model;

import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.beanutils.SuppressPropertiesBeanIntrospector;

import java.lang.reflect.InvocationTargetException;
import java.util.Map;

/**
* Utilities for mapping parameter maps to Java beans.
*
* @author Scott Frederick
*/
public final class ParameterBeanMapper {
/**
* Instantiates an object of the specified type and populates properties of the object from the provided
* parameters.
*
* @param parameters a {@link Map} of values to populate the object from
* @param cls the {@link Class} representing the type of the object to instantiate and populate
* @param <T> the type of the object to instantiate and populate
* @return the instantiated and populated object
*/
public static <T> T mapParametersToBean(Map<String, Object> parameters, Class<T> cls) {
try {
T bean = cls.newInstance();

BeanUtilsBean beanUtils = new BeanUtilsBean();
beanUtils.getPropertyUtils().addBeanIntrospector(SuppressPropertiesBeanIntrospector.SUPPRESS_CLASS);
beanUtils.populate(bean, parameters);

return bean;
} catch (InstantiationException e) {
throw newIllegalArgumentException(cls, e);
} catch (IllegalAccessException e) {
throw newIllegalArgumentException(cls, e);
} catch (InvocationTargetException e) {
throw newIllegalArgumentException(cls, e);
}
}

private static <T> IllegalArgumentException newIllegalArgumentException(Class<T> cls, Exception e) {
return new IllegalArgumentException("Error mapping parameters to class of type " + cls.getName(), e);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.cloud.servicebroker.model;

import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;

public class ParameterBeanMapperTest {
@Test
@SuppressWarnings("serial")
public void mapParametersToBean() {
Map<String, Object> parameters = new HashMap<String, Object>() {{
put("stringProperty", "value1");
put("intProperty", 2);
put("extraProperty", "extra");
put("nestedBean.booleanProperty", true);
}};
TestBean testBean = ParameterBeanMapper.mapParametersToBean(parameters, TestBean.class);

assertThat(testBean.getStringProperty(), equalTo("value1"));
assertThat(testBean.getIntProperty(), equalTo(2));
assertThat(testBean.getUnusedProperty(), nullValue());
assertThat(testBean.getNestedBean().getBooleanProperty(), equalTo(true));
}

@SuppressWarnings("unused")
public static final class TestBean {
private String stringProperty;
private int intProperty;
private String unusedProperty;

private NestedBean nestedBean;

public TestBean() {
this.nestedBean = new NestedBean();
}

public String getStringProperty() {
return stringProperty;
}

public void setStringProperty(String stringProperty) {
this.stringProperty = stringProperty;
}

public int getIntProperty() {
return intProperty;
}

public void setIntProperty(int intProperty) {
this.intProperty = intProperty;
}

public String getUnusedProperty() {
return unusedProperty;
}

public void setUnusedProperty(String unusedProperty) {
this.unusedProperty = unusedProperty;
}

public NestedBean getNestedBean() {
return nestedBean;
}
}

@SuppressWarnings("unused")
public static final class NestedBean {
private boolean booleanProperty;

public boolean getBooleanProperty() {
return booleanProperty;
}

public void setBooleanProperty(boolean booleanProperty) {
this.booleanProperty = booleanProperty;
}
}
}

0 comments on commit 389874b

Please sign in to comment.