VYPR
High severity8.1NVD Advisory· Published Apr 7, 2016· Updated May 6, 2026

CVE-2016-2510

CVE-2016-2510

Description

BeanShell (bsh) before 2.0b6, when included on the classpath by an application that uses Java serialization or XStream, allows remote attackers to execute arbitrary code via crafted serialized data, related to XThis.Handler.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.apache-extras.beanshell:bshMaven
< 2.0b62.0b6

Patches

2
7c68fde2d6fc

Prevent deserialization of Handler

https://github.com/beanshell/beanshellStian Soiland-ReyesFeb 3, 2016via ghsa
1 file changed · +4 0
  • src/bsh/XThis.java+4 0 modified
    @@ -118,6 +118,10 @@ interface from JDK1.2 VM...
     	*/
     	class Handler implements InvocationHandler
     	{
    +		private Object readResolve() throws ObjectStreamException {
    +			throw new NotSerializableException();
    +		}
    +
     		public Object invoke( Object proxy, Method method, Object[] args )
     			throws Throwable
     		{
    
1ccc66bb693d

Avoid (de)serialization of XThis.Handler

https://github.com/beanshell/beanshellStian Soiland-ReyesFeb 1, 2016via ghsa
2 files changed · +48 35
  • src/bsh/XThis.java+32 35 modified
    @@ -34,9 +34,9 @@
     import java.util.Hashtable;
     
     /**
    -	XThis is a dynamically loaded extension which extends This.java and adds 
    -	support for the generalized interface proxy mechanism introduced in 
    -	JDK1.3.  XThis allows bsh scripted objects to implement arbitrary 
    +	XThis is a dynamically loaded extension which extends This.java and adds
    +	support for the generalized interface proxy mechanism introduced in
    +	JDK1.3.  XThis allows bsh scripted objects to implement arbitrary
     	interfaces (be arbitrary event listener types).
     
     	Note: This module relies on new features of JDK1.3 and will not compile
    @@ -47,22 +47,22 @@ support for the generalized interface proxy mechanism introduced in
     	we will maintain This without requiring support for the proxy mechanism.
     
     	XThis stands for "eXtended This" (I had to call it something).
    -	
    +
     	@see JThis	 See also JThis with explicit JFC support for compatibility.
    -	@see This	
    +	@see This
     */
    -public class XThis extends This 
    +public class XThis extends This
     	{
     	/**
     		A cache of proxy interface handlers.
     		Currently just one per interface.
     	*/
     	Hashtable interfaces;
     
    -	InvocationHandler invocationHandler = new Handler();
    +	transient InvocationHandler invocationHandler = new Handler();
     
    -	public XThis( NameSpace namespace, Interpreter declaringInterp ) { 
    -		super( namespace, declaringInterp ); 
    +	public XThis( NameSpace namespace, Interpreter declaringInterp ) {
    +		super( namespace, declaringInterp );
     	}
     
     	public String toString() {
    @@ -72,15 +72,15 @@ public String toString() {
     	/**
     		Get dynamic proxy for interface, caching those it creates.
     	*/
    -	public Object getInterface( Class clas ) 
    +	public Object getInterface( Class clas )
     	{
     		return getInterface( new Class[] { clas } );
     	}
     
     	/**
     		Get dynamic proxy for interface, caching those it creates.
     	*/
    -	public Object getInterface( Class [] ca ) 
    +	public Object getInterface( Class [] ca )
     	{
     		if ( interfaces == null )
     			interfaces = new Hashtable();
    @@ -93,10 +93,10 @@ public Object getInterface( Class [] ca )
     
     		Object interf = interfaces.get( hashKey );
     
    -		if ( interf == null ) 
    +		if ( interf == null )
     		{
     			ClassLoader classLoader = ca[0].getClassLoader(); // ?
    -			interf = Proxy.newProxyInstance( 
    +			interf = Proxy.newProxyInstance(
     				classLoader, ca, invocationHandler );
     			interfaces.put( hashKey, interf );
     		}
    @@ -110,51 +110,51 @@ public Object getInterface( Class [] ca )
     
     		Notes:
     		Inner class for the invocation handler seems to shield this unavailable
    -		interface from JDK1.2 VM...  
    -		
    +		interface from JDK1.2 VM...
    +
     		I don't understand this.  JThis works just fine even if those
     		classes aren't there (doesn't it?)  This class shouldn't be loaded
     		if an XThis isn't instantiated in NameSpace.java, should it?
     	*/
    -	class Handler implements InvocationHandler, java.io.Serializable 
    +	class Handler implements InvocationHandler
     	{
    -		public Object invoke( Object proxy, Method method, Object[] args ) 
    +		public Object invoke( Object proxy, Method method, Object[] args )
     			throws Throwable
     		{
    -			try { 
    +			try {
     				return invokeImpl( proxy, method, args );
     			} catch ( TargetError te ) {
    -				// Unwrap target exception.  If the interface declares that 
    -				// it throws the ex it will be delivered.  If not it will be 
    +				// Unwrap target exception.  If the interface declares that
    +				// it throws the ex it will be delivered.  If not it will be
     				// wrapped in an UndeclaredThrowable
     				throw te.getTarget();
     			} catch ( EvalError ee ) {
     				// Ease debugging...
     				// XThis.this refers to the enclosing class instance
    -				if ( Interpreter.DEBUG ) 
    +				if ( Interpreter.DEBUG )
     					Interpreter.debug( "EvalError in scripted interface: "
     					+ XThis.this.toString() + ": "+ ee );
     				throw ee;
     			}
     		}
     
    -		public Object invokeImpl( Object proxy, Method method, Object[] args ) 
    -			throws EvalError 
    +		public Object invokeImpl( Object proxy, Method method, Object[] args )
    +			throws EvalError
     		{
     			String methodName = method.getName();
     			CallStack callstack = new CallStack( namespace );
     
     			/*
    -				If equals() is not explicitly defined we must override the 
    +				If equals() is not explicitly defined we must override the
     				default implemented by the This object protocol for scripted
    -				object.  To support XThis equals() must test for equality with 
    +				object.  To support XThis equals() must test for equality with
     				the generated proxy object, not the scripted bsh This object;
    -				otherwise callers from outside in Java will not see a the 
    +				otherwise callers from outside in Java will not see a the
     				proxy object as equal to itself.
     			*/
     			BshMethod equalsMethod = null;
     			try {
    -				equalsMethod = namespace.getMethod( 
    +				equalsMethod = namespace.getMethod(
     					"equals", new Class [] { Object.class } );
     			} catch ( UtilEvalError e ) {/*leave null*/ }
     			if ( methodName.equals("equals" ) && equalsMethod == null ) {
    @@ -163,33 +163,30 @@ object.  To support XThis equals() must test for equality with
     			}
     
     			/*
    -				If toString() is not explicitly defined override the default 
    +				If toString() is not explicitly defined override the default
     				to show the proxy interfaces.
     			*/
     			BshMethod toStringMethod = null;
     			try {
    -				toStringMethod = 
    +				toStringMethod =
     					namespace.getMethod( "toString", new Class [] { } );
     			} catch ( UtilEvalError e ) {/*leave null*/ }
     
     			if ( methodName.equals("toString" ) && toStringMethod == null)
     			{
     				Class [] ints = proxy.getClass().getInterfaces();
     				// XThis.this refers to the enclosing class instance
    -				StringBuffer sb = new StringBuffer( 
    +				StringBuffer sb = new StringBuffer(
     					XThis.this.toString() + "\nimplements:" );
     				for(int i=0; i<ints.length; i++)
    -					sb.append( " "+ ints[i].getName() 
    +					sb.append( " "+ ints[i].getName()
     						+ ((ints.length > 1)?",":"") );
     				return sb.toString();
     			}
     
     			Class [] paramTypes = method.getParameterTypes();
    -			return Primitive.unwrap( 
    +			return Primitive.unwrap(
     				invokeMethod( methodName, Primitive.wrap(args, paramTypes) ) );
     		}
     	};
     }
    -
    -
    -
    
  • tests/junitTests/src/bsh/BshSerializationTest.java+16 0 modified
    @@ -58,4 +58,20 @@ public void testSpecialNullSerialization() throws Exception {
             final Interpreter deserInterpreter = TestUtil.serDeser(originalInterpreter);
    
             Assert.assertTrue((Boolean) deserInterpreter.eval("myNull == null"));
    
         }
    
    +
    
    +
    
    +    /**
    
    +     * Tests that a declared method can be serialized (but not exploited)
    
    +     *
    
    +     * @throws Exception in case of failure
    
    +     */
    
    +    @Test
    
    +    public void testMethodSerialization() throws Exception {
    
    +        final Interpreter origInterpreter = new Interpreter();
    
    +        origInterpreter.eval("int method() { return 1337; }");
    
    +        Assert.assertEquals(1337, origInterpreter.eval("method()"));
    
    +        final Interpreter deserInterpreter = TestUtil.serDeser(origInterpreter);
    
    +        Assert.assertEquals(1337, deserInterpreter.eval("method()"));
    
    +    }
    
    +
    
     }
    
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

21

News mentions

0

No linked articles in our index yet.