[
https://issues.apache.org/jira/browse/COLLECTIONS-580?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15003912#comment-15003912
]
Karsten Klein edited comment on COLLECTIONS-580 at 11/13/15 12:20 PM:
----------------------------------------------------------------------
We (not having seen the attached patch before) have come up with the following
solution:
{code}
/**
* Transforms the input to result by invoking a method on the input.
*
* @param input the input object to transform
* @return the transformed result, null if null input
*/
public Object transform(Object input) {
if (input == null) {
return null;
}
if (deserialized) {
throw new IllegalStateException("Transformation on deserialized
object not supported. "
+ "Using this function may indicate an attempted SECURITY
BREACH.");
}
try {
Class cls = input.getClass();
Method method = cls.getMethod(iMethodName, iParamTypes);
return method.invoke(input, iArgs);
} catch (NoSuchMethodException ex) {
throw new FunctorException("InvokerTransformer: The method '" +
iMethodName + "' on '" + input.getClass() + "' does not exist");
} catch (IllegalAccessException ex) {
throw new FunctorException("InvokerTransformer: The method '" +
iMethodName + "' on '" + input.getClass() + "' cannot be accessed");
} catch (InvocationTargetException ex) {
throw new FunctorException("InvokerTransformer: The method '" +
iMethodName + "' on '" + input.getClass() + "' threw an exception", ex);
}
}
private transient boolean deserialized = false;
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
in.defaultReadObject();
deserialized = true;
}
{code}
This approach is a little more 'compatible' and less invasive. It will only
fail if transform is invoked on a deserialized object. In particular it does
not fail at deserialization time. Only when the transform method is invoked.
This may reduce the effects of the change.
was (Author: [email protected]):
We (not having seen the attached patch before) have come up with the following
solution:
{code}
/**
* Transforms the input to result by invoking a method on the input.
*
* @param input the input object to transform
* @return the transformed result, null if null input
*/
public Object transform(Object input) {
if (input == null) {
return null;
}
if (deserialized) {
throw new IllegalStateException("Transformation on deserialized
object not supported. "
+ "Using this function may indicate an attempted SECURITY
BREACH.");
}
try {
Class cls = input.getClass();
Method method = cls.getMethod(iMethodName, iParamTypes);
return method.invoke(input, iArgs);
} catch (NoSuchMethodException ex) {
throw new FunctorException("InvokerTransformer: The method '" +
iMethodName + "' on '" + input.getClass() + "' does not exist");
} catch (IllegalAccessException ex) {
throw new FunctorException("InvokerTransformer: The method '" +
iMethodName + "' on '" + input.getClass() + "' cannot be accessed");
} catch (InvocationTargetException ex) {
throw new FunctorException("InvokerTransformer: The method '" +
iMethodName + "' on '" + input.getClass() + "' threw an exception", ex);
}
}
private transient boolean deserialized = false;
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
in.defaultReadObject();
deserialized = true;
}
{code}
This approach is the most non-invasive and 'compatible' approach. It will only
fail if transform is invoked on a deserialized object. In particular it does
not fail at deserialization time. Only when the transform method is invoked.
This may reduce the effects of the change.
> Arbitrary remote code execution with InvokerTransformer
> -------------------------------------------------------
>
> Key: COLLECTIONS-580
> URL: https://issues.apache.org/jira/browse/COLLECTIONS-580
> Project: Commons Collections
> Issue Type: Bug
> Affects Versions: 3.0, 4.0
> Reporter: Philippe Marschall
> Attachments: COLLECTIONS-580.patch
>
>
> With {{InvokerTransformer}} serializable collections can be build that
> execute arbitrary Java code.
> {{sun.reflect.annotation.AnnotationInvocationHandler#readObject}} invokes
> {{#entrySet}} and {{#get}} on a deserialized collection. If you have an
> endpoint that accepts serialized Java objects (JMX, RMI, remote EJB, ...) you
> can combine the two to create arbitrary remote code execution vulnerability.
> I don't know of a good fix short of removing {{InvokerTransformer}} or making
> it not Serializable. Both probably break existing applications.
> This is not my research, but has been discovered by other people.
> https://github.com/frohoff/ysoserial
> http://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)