From 3e07ea52885f88d3fbec444dfd592f27bfb65647 Mon Sep 17 00:00:00 2001 From: jvoisin Date: Mon, 1 Apr 2019 11:33:35 +0200 Subject: [PATCH 1/2] Use a random key to "encrypt" the remember-me cookie's value Since Spring's default remember-me technique is terrible security-wise (`user:timstamp:md5(use:timestamp:password:key)`), we should at least use a random key, instead of a fixed one, otherwise, and attacker able to capture the cookies might be able to trivially bruteforce offline the password of the associated user. --- .../player/security/GlobalSecurityConfig.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/airsonic-main/src/main/java/org/airsonic/player/security/GlobalSecurityConfig.java b/airsonic-main/src/main/java/org/airsonic/player/security/GlobalSecurityConfig.java index 7ea77579..0fc53768 100644 --- a/airsonic-main/src/main/java/org/airsonic/player/security/GlobalSecurityConfig.java +++ b/airsonic-main/src/main/java/org/airsonic/player/security/GlobalSecurityConfig.java @@ -22,6 +22,8 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic import org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import java.security.SecureRandom; + @Configuration @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) @@ -31,6 +33,14 @@ public class GlobalSecurityConfig extends GlobalAuthenticationConfigurerAdapter static final String FAILURE_URL = "/login?error=1"; + private static final String key; + + static { + byte[] array = new byte[32]; + new SecureRandom().nextBytes(array); + key = new String(array); + } + @Autowired private SecurityService securityService; @@ -162,8 +172,8 @@ public class GlobalSecurityConfig extends GlobalAuthenticationConfigurerAdapter // see http://docs.spring.io/spring-security/site/docs/3.2.4.RELEASE/reference/htmlsingle/#csrf-logout .and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout", "GET")).logoutSuccessUrl( "/login?logout") - .and().rememberMe().key("airsonic"); + .and().rememberMe().key(key); } } -} \ No newline at end of file +} From 268dc6e13dd1d84f309db3a4bd7d0d864c4b5bf1 Mon Sep 17 00:00:00 2001 From: jvoisin Date: Tue, 2 Apr 2019 10:13:29 +0200 Subject: [PATCH 2/2] Factorise the key generation into a static method --- .../player/security/GlobalSecurityConfig.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/airsonic-main/src/main/java/org/airsonic/player/security/GlobalSecurityConfig.java b/airsonic-main/src/main/java/org/airsonic/player/security/GlobalSecurityConfig.java index 0fc53768..41a9f03f 100644 --- a/airsonic-main/src/main/java/org/airsonic/player/security/GlobalSecurityConfig.java +++ b/airsonic-main/src/main/java/org/airsonic/player/security/GlobalSecurityConfig.java @@ -33,14 +33,6 @@ public class GlobalSecurityConfig extends GlobalAuthenticationConfigurerAdapter static final String FAILURE_URL = "/login?error=1"; - private static final String key; - - static { - byte[] array = new byte[32]; - new SecureRandom().nextBytes(array); - key = new String(array); - } - @Autowired private SecurityService securityService; @@ -79,6 +71,11 @@ public class GlobalSecurityConfig extends GlobalAuthenticationConfigurerAdapter auth.authenticationProvider(new JWTAuthenticationProvider(jwtKey)); } + private static String generateRememberMeKey() { + byte[] array = new byte[32]; + new SecureRandom().nextBytes(array); + return new String(array); + } @Configuration @Order(1) @@ -172,7 +169,7 @@ public class GlobalSecurityConfig extends GlobalAuthenticationConfigurerAdapter // see http://docs.spring.io/spring-security/site/docs/3.2.4.RELEASE/reference/htmlsingle/#csrf-logout .and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout", "GET")).logoutSuccessUrl( "/login?logout") - .and().rememberMe().key(key); + .and().rememberMe().key(generateRememberMeKey()); } }