From 8cafbae72d0abce86f026a247fd46760f3445e03 Mon Sep 17 00:00:00 2001 From: Simon Greatrix Date: Sat, 29 Nov 2025 11:24:41 +0000 Subject: [PATCH 1/2] Proposed fix for environment variables not being decrypted --- jasypt-spring-boot-starter/pom.xml | 2 +- ...ystemEnvironmentPropertySourceWrapper.java | 120 +++++++++++++----- ...mEnvironmentPropertySourceWrapperTest.java | 55 ++++++++ pom.xml | 2 +- 4 files changed, 146 insertions(+), 33 deletions(-) create mode 100644 jasypt-spring-boot/src/test/java/com/ulisesbocchio/jasyptspringboot/wrapper/EncryptableSystemEnvironmentPropertySourceWrapperTest.java diff --git a/jasypt-spring-boot-starter/pom.xml b/jasypt-spring-boot-starter/pom.xml index 91159e7..846f75b 100644 --- a/jasypt-spring-boot-starter/pom.xml +++ b/jasypt-spring-boot-starter/pom.xml @@ -50,7 +50,7 @@ uk.org.webcompere system-stubs-jupiter - 2.0.1 + 2.1.8 test diff --git a/jasypt-spring-boot/src/main/java/com/ulisesbocchio/jasyptspringboot/wrapper/EncryptableSystemEnvironmentPropertySourceWrapper.java b/jasypt-spring-boot/src/main/java/com/ulisesbocchio/jasyptspringboot/wrapper/EncryptableSystemEnvironmentPropertySourceWrapper.java index ba1f9c7..37fa359 100644 --- a/jasypt-spring-boot/src/main/java/com/ulisesbocchio/jasyptspringboot/wrapper/EncryptableSystemEnvironmentPropertySourceWrapper.java +++ b/jasypt-spring-boot/src/main/java/com/ulisesbocchio/jasyptspringboot/wrapper/EncryptableSystemEnvironmentPropertySourceWrapper.java @@ -1,5 +1,10 @@ package com.ulisesbocchio.jasyptspringboot.wrapper; +import java.util.AbstractMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + import com.ulisesbocchio.jasyptspringboot.EncryptablePropertyFilter; import com.ulisesbocchio.jasyptspringboot.EncryptablePropertyResolver; import com.ulisesbocchio.jasyptspringboot.EncryptablePropertySource; @@ -9,53 +14,106 @@ import org.springframework.core.env.PropertySource; import org.springframework.core.env.SystemEnvironmentPropertySource; -import java.util.Map; - /** *

EncryptableSystemEnvironmentPropertySourceWrapper class.

* * @author Tomas Tulka (@ttulka) * @version $Id: $Id */ -public class EncryptableSystemEnvironmentPropertySourceWrapper extends SystemEnvironmentPropertySource implements EncryptablePropertySource> { +public class EncryptableSystemEnvironmentPropertySourceWrapper extends SystemEnvironmentPropertySource + implements EncryptablePropertySource> { + + + /** + * A map that will wrap the System environment variables map and decrypt them. + */ + private static class DecryptingMap extends AbstractMap { + + final CachingDelegateEncryptablePropertySource> encryptableDelegate; - private final CachingDelegateEncryptablePropertySource> encryptableDelegate; - /** - *

Constructor for EncryptableSystemEnvironmentPropertySourceWrapper.

- * - * @param delegate a {@link org.springframework.core.env.SystemEnvironmentPropertySource} object - * @param resolver a {@link com.ulisesbocchio.jasyptspringboot.EncryptablePropertyResolver} object - * @param filter a {@link com.ulisesbocchio.jasyptspringboot.EncryptablePropertyFilter} object - */ - public EncryptableSystemEnvironmentPropertySourceWrapper(SystemEnvironmentPropertySource delegate, EncryptablePropertyResolver resolver, EncryptablePropertyFilter filter) { - super(delegate.getName(), delegate.getSource()); - encryptableDelegate = new CachingDelegateEncryptablePropertySource<>(delegate, resolver, filter); + DecryptingMap(SystemEnvironmentPropertySource delegate, EncryptablePropertyResolver resolver, EncryptablePropertyFilter filter) { + encryptableDelegate = new CachingDelegateEncryptablePropertySource<>(delegate, resolver, filter); + } + + @Override + public int size() { + return encryptableDelegate.getSource().size(); + } + + @Override + public boolean isEmpty() { + return encryptableDelegate.getSource().isEmpty(); } - /** {@inheritDoc} */ @Override - public Object getProperty(String name) { - return encryptableDelegate.getProperty(name); + public Set keySet() { + return encryptableDelegate.getSource().keySet(); } - /** {@inheritDoc} */ @Override - public PropertySource> getDelegate() { - return encryptableDelegate; + public boolean containsKey(Object key) { + return encryptableDelegate.getSource().containsKey(key); } - /** {@inheritDoc} */ @Override - public Origin getOrigin(String key) { - Origin fromSuper = EncryptablePropertySource.super.getOrigin(key); - if (fromSuper != null) { - return fromSuper; - } - String property = resolvePropertyName(key); - if (super.containsProperty(property)) { - return new SystemEnvironmentOrigin(property); - } - return null; + public Set> entrySet() { + HashSet> entries = new HashSet<>(); + Set keys = encryptableDelegate.getSource().keySet(); + for (String key : keys) { + entries.add(new AbstractMap.SimpleEntry<>(key, encryptableDelegate.getProperty(key))); + } + return entries; } + + } + + private final CachingDelegateEncryptablePropertySource> encryptableDelegate; + + + /** + *

Constructor for EncryptableSystemEnvironmentPropertySourceWrapper.

+ * + * @param delegate a {@link org.springframework.core.env.SystemEnvironmentPropertySource} object + * @param resolver a {@link com.ulisesbocchio.jasyptspringboot.EncryptablePropertyResolver} object + * @param filter a {@link com.ulisesbocchio.jasyptspringboot.EncryptablePropertyFilter} object + */ + public EncryptableSystemEnvironmentPropertySourceWrapper( + SystemEnvironmentPropertySource delegate, + EncryptablePropertyResolver resolver, + EncryptablePropertyFilter filter + ) { + super(delegate.getName(), new DecryptingMap(delegate, resolver, filter)); + encryptableDelegate = ((DecryptingMap) getSource()).encryptableDelegate; + } + + + /** {@inheritDoc} */ + @Override + public PropertySource> getDelegate() { + return encryptableDelegate; + } + + + /** {@inheritDoc} */ + @Override + public Origin getOrigin(String key) { + Origin fromSuper = EncryptablePropertySource.super.getOrigin(key); + if (fromSuper != null) { + return fromSuper; + } + String property = resolvePropertyName(key); + if (super.containsProperty(property)) { + return new SystemEnvironmentOrigin(property); + } + return null; + } + + + /** {@inheritDoc} */ + @Override + public Object getProperty(String name) { + return encryptableDelegate.getProperty(name); + } + } diff --git a/jasypt-spring-boot/src/test/java/com/ulisesbocchio/jasyptspringboot/wrapper/EncryptableSystemEnvironmentPropertySourceWrapperTest.java b/jasypt-spring-boot/src/test/java/com/ulisesbocchio/jasyptspringboot/wrapper/EncryptableSystemEnvironmentPropertySourceWrapperTest.java new file mode 100644 index 0000000..ef42258 --- /dev/null +++ b/jasypt-spring-boot/src/test/java/com/ulisesbocchio/jasyptspringboot/wrapper/EncryptableSystemEnvironmentPropertySourceWrapperTest.java @@ -0,0 +1,55 @@ +package com.ulisesbocchio.jasyptspringboot.wrapper; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.HashMap; +import java.util.List; + +import javax.crypto.spec.SecretKeySpec; + +import com.ulisesbocchio.jasyptspringboot.EncryptablePropertyFilter; +import com.ulisesbocchio.jasyptspringboot.EncryptablePropertyResolver; +import com.ulisesbocchio.jasyptspringboot.encryptor.SimpleGCMConfig; +import com.ulisesbocchio.jasyptspringboot.encryptor.SimpleGCMStringEncryptor; +import com.ulisesbocchio.jasyptspringboot.filter.DefaultLazyPropertyFilter; +import com.ulisesbocchio.jasyptspringboot.filter.DefaultPropertyFilter; +import com.ulisesbocchio.jasyptspringboot.resolver.DefaultPropertyResolver; +import org.jasypt.encryption.StringEncryptor; +import org.junit.jupiter.api.Test; +import org.springframework.boot.context.properties.source.ConfigurationProperty; +import org.springframework.boot.context.properties.source.ConfigurationPropertyName; +import org.springframework.boot.context.properties.source.ConfigurationPropertySource; +import org.springframework.core.env.StandardEnvironment; +import org.springframework.core.env.SystemEnvironmentPropertySource; +import org.springframework.mock.env.MockEnvironment; + +class EncryptableSystemEnvironmentPropertySourceWrapperTest { + + @Test + void environmentVariablesAreDecrypted() { + SimpleGCMConfig simpleGCMConfig = new SimpleGCMConfig(); + simpleGCMConfig.setActualKey(new SecretKeySpec(new byte[] { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 },"AES")); + StringEncryptor stringEncryptor = new SimpleGCMStringEncryptor(simpleGCMConfig); + + MockEnvironment environment = new MockEnvironment(); + + HashMap map = new HashMap<>(); + map.put("TEST_KEY_PLAIN", "PLAIN_VALUE"); + map.put("TEST_KEY_ENCRYPTED", "ENC(" + stringEncryptor.encrypt("ENCRYPTED_VALUE") + ")"); + + SystemEnvironmentPropertySource delegate = new SystemEnvironmentPropertySource(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, map); + EncryptablePropertyResolver resolver = new DefaultPropertyResolver(stringEncryptor,environment); + EncryptablePropertyFilter filter = new DefaultLazyPropertyFilter(environment); + + EncryptableSystemEnvironmentPropertySourceWrapper wrapper = new EncryptableSystemEnvironmentPropertySourceWrapper(delegate, resolver, filter); + + ConfigurationPropertySource configurationPropertySource = ConfigurationPropertySource.from(wrapper); + + ConfigurationProperty value = configurationPropertySource.getConfigurationProperty(ConfigurationPropertyName.of("test.key.plain")); + assertEquals("PLAIN_VALUE", value.getValue()); + + value = configurationPropertySource.getConfigurationProperty(ConfigurationPropertyName.of("test.key.encrypted")); + assertEquals("ENCRYPTED_VALUE", value.getValue()); + } + +} diff --git a/pom.xml b/pom.xml index 37be680..1c0954d 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ UTF-8 1.8 - 2.7.6 + 3.5.8 2021.0.5 1.9.3 3.10.1 From 2c8af4cb900c6f8bcee2b3c75788c89e40cfd472 Mon Sep 17 00:00:00 2001 From: Simon Greatrix Date: Sat, 29 Nov 2025 11:34:26 +0000 Subject: [PATCH 2/2] Removed style changes --- ...ystemEnvironmentPropertySourceWrapper.java | 146 ++++++++---------- 1 file changed, 68 insertions(+), 78 deletions(-) diff --git a/jasypt-spring-boot/src/main/java/com/ulisesbocchio/jasyptspringboot/wrapper/EncryptableSystemEnvironmentPropertySourceWrapper.java b/jasypt-spring-boot/src/main/java/com/ulisesbocchio/jasyptspringboot/wrapper/EncryptableSystemEnvironmentPropertySourceWrapper.java index 37fa359..bcbb568 100644 --- a/jasypt-spring-boot/src/main/java/com/ulisesbocchio/jasyptspringboot/wrapper/EncryptableSystemEnvironmentPropertySourceWrapper.java +++ b/jasypt-spring-boot/src/main/java/com/ulisesbocchio/jasyptspringboot/wrapper/EncryptableSystemEnvironmentPropertySourceWrapper.java @@ -20,100 +20,90 @@ * @author Tomas Tulka (@ttulka) * @version $Id: $Id */ -public class EncryptableSystemEnvironmentPropertySourceWrapper extends SystemEnvironmentPropertySource - implements EncryptablePropertySource> { +public class EncryptableSystemEnvironmentPropertySourceWrapper extends SystemEnvironmentPropertySource implements EncryptablePropertySource> { - /** - * A map that will wrap the System environment variables map and decrypt them. - */ - private static class DecryptingMap extends AbstractMap { + /** + * A map that will wrap the System environment variables map and decrypt them. + */ + private static class DecryptingMap extends AbstractMap { - final CachingDelegateEncryptablePropertySource> encryptableDelegate; + final CachingDelegateEncryptablePropertySource> encryptableDelegate; - DecryptingMap(SystemEnvironmentPropertySource delegate, EncryptablePropertyResolver resolver, EncryptablePropertyFilter filter) { - encryptableDelegate = new CachingDelegateEncryptablePropertySource<>(delegate, resolver, filter); - } + DecryptingMap(SystemEnvironmentPropertySource delegate, EncryptablePropertyResolver resolver, EncryptablePropertyFilter filter) { + encryptableDelegate = new CachingDelegateEncryptablePropertySource<>(delegate, resolver, filter); + } - @Override - public int size() { - return encryptableDelegate.getSource().size(); - } + @Override + public int size() { + return encryptableDelegate.getSource().size(); + } + + @Override + public boolean isEmpty() { + return encryptableDelegate.getSource().isEmpty(); + } + + @Override + public Set keySet() { + return encryptableDelegate.getSource().keySet(); + } + + @Override + public boolean containsKey(Object key) { + return encryptableDelegate.getSource().containsKey(key); + } + + @Override + public Set> entrySet() { + HashSet> entries = new HashSet<>(); + Set keys = encryptableDelegate.getSource().keySet(); + for (String key : keys) { + entries.add(new AbstractMap.SimpleEntry<>(key, encryptableDelegate.getProperty(key))); + } + return entries; + } - @Override - public boolean isEmpty() { - return encryptableDelegate.getSource().isEmpty(); } - @Override - public Set keySet() { - return encryptableDelegate.getSource().keySet(); + private final CachingDelegateEncryptablePropertySource> encryptableDelegate; + + /** + *

Constructor for EncryptableSystemEnvironmentPropertySourceWrapper.

+ * + * @param delegate a {@link org.springframework.core.env.SystemEnvironmentPropertySource} object + * @param resolver a {@link com.ulisesbocchio.jasyptspringboot.EncryptablePropertyResolver} object + * @param filter a {@link com.ulisesbocchio.jasyptspringboot.EncryptablePropertyFilter} object + */ + public EncryptableSystemEnvironmentPropertySourceWrapper(SystemEnvironmentPropertySource delegate, EncryptablePropertyResolver resolver, EncryptablePropertyFilter filter) { + super(delegate.getName(), new DecryptingMap(delegate, resolver, filter)); + encryptableDelegate = ((DecryptingMap) getSource()).encryptableDelegate; } + /** {@inheritDoc} */ @Override - public boolean containsKey(Object key) { - return encryptableDelegate.getSource().containsKey(key); + public Object getProperty(String name) { + return encryptableDelegate.getProperty(name); } + /** {@inheritDoc} */ @Override - public Set> entrySet() { - HashSet> entries = new HashSet<>(); - Set keys = encryptableDelegate.getSource().keySet(); - for (String key : keys) { - entries.add(new AbstractMap.SimpleEntry<>(key, encryptableDelegate.getProperty(key))); - } - return entries; + public PropertySource> getDelegate() { + return encryptableDelegate; } - } - - private final CachingDelegateEncryptablePropertySource> encryptableDelegate; - - - /** - *

Constructor for EncryptableSystemEnvironmentPropertySourceWrapper.

- * - * @param delegate a {@link org.springframework.core.env.SystemEnvironmentPropertySource} object - * @param resolver a {@link com.ulisesbocchio.jasyptspringboot.EncryptablePropertyResolver} object - * @param filter a {@link com.ulisesbocchio.jasyptspringboot.EncryptablePropertyFilter} object - */ - public EncryptableSystemEnvironmentPropertySourceWrapper( - SystemEnvironmentPropertySource delegate, - EncryptablePropertyResolver resolver, - EncryptablePropertyFilter filter - ) { - super(delegate.getName(), new DecryptingMap(delegate, resolver, filter)); - encryptableDelegate = ((DecryptingMap) getSource()).encryptableDelegate; - } - - - /** {@inheritDoc} */ - @Override - public PropertySource> getDelegate() { - return encryptableDelegate; - } - - - /** {@inheritDoc} */ - @Override - public Origin getOrigin(String key) { - Origin fromSuper = EncryptablePropertySource.super.getOrigin(key); - if (fromSuper != null) { - return fromSuper; - } - String property = resolvePropertyName(key); - if (super.containsProperty(property)) { - return new SystemEnvironmentOrigin(property); + /** {@inheritDoc} */ + @Override + public Origin getOrigin(String key) { + Origin fromSuper = EncryptablePropertySource.super.getOrigin(key); + if (fromSuper != null) { + return fromSuper; + } + String property = resolvePropertyName(key); + if (super.containsProperty(property)) { + return new SystemEnvironmentOrigin(property); + } + return null; } - return null; - } - - - /** {@inheritDoc} */ - @Override - public Object getProperty(String name) { - return encryptableDelegate.getProperty(name); - } - }