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

ehcache 2 to 3 migration of net.sf.ehcache.hibernate.SingletonEhCacheProvider #3129

Open
sarnobat opened this issue Feb 16, 2023 · 4 comments

Comments

@sarnobat
Copy link

I'm trying to upgrade from 2 to 3 and the (large) codebase contains:

net.sf.ehcache.hibernate.SingletonEhCacheProvider

inside xml-based bean containers:

                <prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.SingletonEhCacheProvider</prop>

and I don't see in the migration guide any hints on what is an acceptable way to achieve this:

https://www.ehcache.org/documentation/3.3/migration-guide.html

I'm using Spring 3.2.18 and hibernate as low as 3.3:

./WEB-INF/lib/hibernate-3.2.3.ga.jar
./WEB-INF/lib/hibernate-annotations-3.3.0.ga.jar
./WEB-INF/lib/hibernate-commons-annotations-4.0.1.Final.jar
./WEB-INF/lib/hibernate-validator-5.1.3.Final.jar
./WEB-INF/lib/spring-aop-3.2.18.RELEASE.jar
./WEB-INF/lib/spring-beans-3.2.18.RELEASE.jar
./WEB-INF/lib/spring-context-3.2.18.RELEASE.jar
./WEB-INF/lib/spring-context-support-3.2.18.RELEASE.jar
./WEB-INF/lib/spring-core-3.2.18.RELEASE.jar
./WEB-INF/lib/spring-expression-3.2.18.RELEASE.jar
./WEB-INF/lib/spring-jdbc-3.2.18.RELEASE.jar
./WEB-INF/lib/spring-jms-3.0.3.RELEASE.jar
./WEB-INF/lib/spring-orm-3.2.18.RELEASE.jar
./WEB-INF/lib/spring-oxm-3.2.18.RELEASE.jar
./WEB-INF/lib/spring-security-config-3.1.2.RELEASE.jar
./WEB-INF/lib/spring-security-core-3.2.10.RELEASE.jar
./WEB-INF/lib/spring-security-saml2-core-1.0.0.RC2.jar
./WEB-INF/lib/spring-security-web-3.2.10.RELEASE.jar
./WEB-INF/lib/spring-test-3.2.18.RELEASE.jar
./WEB-INF/lib/spring-tx-3.2.18.RELEASE.jar
./WEB-INF/lib/spring-web-3.2.18.RELEASE.jar
./WEB-INF/lib/spring-webmvc-3.2.18.RELEASE.jar
./WEB-INF/lib/spring-ws-core-2.1.4.RELEASE-all.jar
  1. What is the easiest way to use ehcache 3 with code that currently uses net.sf.ehcache.hibernate.SingletonEhCacheProvider?
  2. Is there a compatibility matrix? I see lots of search results about Hibernate 4+, Spring/Spring Boot at higher versions than my code has.

(note: this is legacy code not written by me :) And we do have plans to modernize but there's a more immediate security concern with ehcache 2 that I need to address)

@chrisdennis
Copy link
Member

The way to do this in a modern setup would be to use Ehcache 3 natively as a JSR-107 provider. I'm not sure I can think of a trivial way to use Ehcache 3 as a caching provider for Hibernate 3.3 (Ehcache 3 was released 8 years after Hibernate 3.3).

Before we explore various crazy bridging options... what's the security problem with Ehcache 2?

@sarnobat
Copy link
Author

sarnobat commented Feb 16, 2023

Thank you for the quick response. Here is the security issue:
CVE-2020-36518

@chrisdennis
Copy link
Member

So that's a vulnerability in Jackson - I think that's only used in the management code for the clustered parts of Ehcache 2.x. Can you tell me how you're installing Ehcache 2.x, what your configuration looks like, and where the scanner is finding the library?

@sarnobat
Copy link
Author

sarnobat commented Feb 17, 2023

(thanks again, will try and get this info from a colleague before I go on a few weeks travel)

EDIT: Here is the info as I understand it (let me know if more is needed - it's the first time I've seen this code!):

1) How I'm using Ehcache 2.X

import org.ehcache.core.Ehcache;
import org.ehcache.config.CacheConfiguration;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;


    @Cacheable(value = MY_FEATURE_SETTINGS_CACHE_NAME, condition = "#root.target.isMyFeatureSettingsCacheEnabled()")
    public List<MyFeatureSetting> getMyFeatureSettings(Long id, MyFeatureSettingType MyFeatureSettingType) throws DomainException {

        try {
            return MyFeatureSettingDao.getMyFeatureSetting(acctId, MyFeatureSettingType);
        } catch (Exception e) {
            throw new DomainException("Failed to getMyFeatureSetting(), acctId=" + acctId, e);
        }
    }

2) What the Configuration looks like (sample)

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">

    <diskStore path="java.io.tmpdir"/>
.........
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="false"
            diskPersistent="false"
            memoryStoreEvictionPolicy="LRU"
    />
</ehcache>

3) Where the scanner is finding the library

applicationContext.xml (with trade secrets redacted)

    <cache:annotation-driven key-generator="myCacheKeyGenerator"/>

    <bean id="myCacheKeyGenerator" class="com.mycompany.CacheKeyGenerator">
        <property name="configManager" ref="myConfigManager"/>
    </bean>

    <bean id="cacheManager" class="org.springframework.cache.support.CompositeCacheManager">
        <property name="cacheManagers"><list>
            <ref bean="myCacheManager"/>
            <ref bean="core.simpleCacheManager"/>
        </list></property>
        <property name="fallbackToNoOpCache" value="true"/>
    </bean>


    <bean id="myCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
        <property name="cacheManager" ref="myCacheFactoryBean"/>
    </bean>

    <bean id="myCacheFactoryBean" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
          p:config-location="classpath:core-ehcache.xml"
          p:cacheManagerName="coreEhCacheManager"
          p:shared="true">
    </bean>
import com.mycompany.ConfigManager;
import org.springframework.cache.interceptor.DefaultKeyGenerator;

public class CacheKeyGenerator extends DefaultKeyGenerator {

    private ConfigManager configManager;

    @Override
    public Object generate(Object target, Method method, Object... params) {
        try {
            if(customCacheEnabled()){
                return generateKey(params);
            }
        } catch(Exception e){
            log.error("Exception using Custom Cache Key Generator, Falling back to Default Key Generator", e);
        }
        return super.generate(target, method, params);
    }

    public static Object generateKey(Object... params) {
        if (params.length == 0) {
            return CacheKey.EMPTY;
        }
        if (params.length == 1) {
            Object param = params[0];
            if (param != null && !param.getClass().isArray()) {
                return param;
            }
        }
        return new CacheKey(params);
    }
}

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

No branches or pull requests

2 participants