Skip to content

Commit c5bccb1

Browse files
authored
Limit token expiry to 1 hour maximum (elastic#38244) (elastic#38392)
We mention in our documentation for the token expiration configuration maximum value is 1 hour but do not enforce it. This commit adds max limit to the TOKEN_EXPIRATION setting. Note: Since this is a backport and the min max time value support was not there in 6.x, I have selectively picked the change from Setting. The changes were done for zen2.
1 parent 6600806 commit c5bccb1

File tree

3 files changed

+47
-1
lines changed

3 files changed

+47
-1
lines changed

server/src/main/java/org/elasticsearch/common/settings/Setting.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1367,6 +1367,12 @@ public static Setting<TimeValue> timeSetting(
13671367
return new Setting<>(simpleKey, s -> defaultValue.apply(s).getStringRep(), minTimeValueParser(key, minValue), properties);
13681368
}
13691369

1370+
public static Setting<TimeValue> timeSetting(
1371+
final String key, TimeValue defaultValue, final TimeValue minValue, final TimeValue maxValue, final Property... properties) {
1372+
final SimpleKey simpleKey = new SimpleKey(key);
1373+
return new Setting<>(simpleKey, s -> defaultValue.getStringRep(), minMaxTimeValueParser(key, minValue, maxValue), properties);
1374+
}
1375+
13701376
private static Function<String, TimeValue> minTimeValueParser(final String key, final TimeValue minValue) {
13711377
return s -> {
13721378
final TimeValue value = TimeValue.parseTimeValue(s, null, key);
@@ -1383,6 +1389,22 @@ private static Function<String, TimeValue> minTimeValueParser(final String key,
13831389
};
13841390
}
13851391

1392+
private static Function<String, TimeValue> minMaxTimeValueParser(final String key, final TimeValue minValue, final TimeValue maxValue) {
1393+
return s -> {
1394+
final TimeValue value = minTimeValueParser(key, minValue).apply(s);
1395+
if (value.millis() > maxValue.millis()) {
1396+
final String message = String.format(
1397+
Locale.ROOT,
1398+
"failed to parse value [%s] for setting [%s], must be <= [%s]",
1399+
s,
1400+
key,
1401+
maxValue.getStringRep());
1402+
throw new IllegalArgumentException(message);
1403+
}
1404+
return value;
1405+
};
1406+
}
1407+
13861408
public static Setting<TimeValue> timeSetting(String key, TimeValue defaultValue, TimeValue minValue, Property... properties) {
13871409
return timeSetting(key, (s) -> defaultValue, minValue, properties);
13881410
}

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/TokenService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ public final class TokenService extends AbstractComponent {
161161
public static final Setting<SecureString> TOKEN_PASSPHRASE = SecureSetting.secureString("xpack.security.authc.token.passphrase", null,
162162
Property.Deprecated);
163163
public static final Setting<TimeValue> TOKEN_EXPIRATION = Setting.timeSetting("xpack.security.authc.token.timeout",
164-
TimeValue.timeValueMinutes(20L), TimeValue.timeValueSeconds(1L), Property.NodeScope);
164+
TimeValue.timeValueMinutes(20L), TimeValue.timeValueSeconds(1L), TimeValue.timeValueHours(1L), Property.NodeScope);
165165
public static final Setting<TimeValue> DELETE_INTERVAL = Setting.timeSetting("xpack.security.authc.token.delete.interval",
166166
TimeValue.timeValueMinutes(30L), Property.NodeScope);
167167
public static final Setting<TimeValue> DELETE_TIMEOUT = Setting.timeSetting("xpack.security.authc.token.delete.timeout",

x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/TokenServiceTests.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
import static java.time.Clock.systemUTC;
8282
import static org.elasticsearch.repositories.ESBlobStoreTestCase.randomBytes;
8383
import static org.hamcrest.Matchers.containsString;
84+
import static org.hamcrest.Matchers.equalTo;
8485
import static org.hamcrest.Matchers.notNullValue;
8586
import static org.hamcrest.Matchers.nullValue;
8687
import static org.mockito.Matchers.any;
@@ -496,6 +497,29 @@ public void testComputeSecretKeyIsConsistent() throws Exception {
496497
assertArrayEquals(key.getEncoded(), key2.getEncoded());
497498
}
498499

500+
public void testTokenExpiryConfig() {
501+
TimeValue expiration = TokenService.TOKEN_EXPIRATION.get(tokenServiceEnabledSettings);
502+
assertThat(expiration, equalTo(TimeValue.timeValueMinutes(20L)));
503+
// Configure Minimum expiration
504+
tokenServiceEnabledSettings = Settings.builder().put(TokenService.TOKEN_EXPIRATION.getKey(), "1s").build();
505+
expiration = TokenService.TOKEN_EXPIRATION.get(tokenServiceEnabledSettings);
506+
assertThat(expiration, equalTo(TimeValue.timeValueSeconds(1L)));
507+
// Configure Maximum expiration
508+
tokenServiceEnabledSettings = Settings.builder().put(TokenService.TOKEN_EXPIRATION.getKey(), "60m").build();
509+
expiration = TokenService.TOKEN_EXPIRATION.get(tokenServiceEnabledSettings);
510+
assertThat(expiration, equalTo(TimeValue.timeValueHours(1L)));
511+
// Outside range should fail
512+
tokenServiceEnabledSettings = Settings.builder().put(TokenService.TOKEN_EXPIRATION.getKey(), "1ms").build();
513+
IllegalArgumentException ile = expectThrows(IllegalArgumentException.class,
514+
() -> TokenService.TOKEN_EXPIRATION.get(tokenServiceEnabledSettings));
515+
assertThat(ile.getMessage(),
516+
containsString("failed to parse value [1ms] for setting [xpack.security.authc.token.timeout], must be >= [1s]"));
517+
tokenServiceEnabledSettings = Settings.builder().put(TokenService.TOKEN_EXPIRATION.getKey(), "120m").build();
518+
ile = expectThrows(IllegalArgumentException.class, () -> TokenService.TOKEN_EXPIRATION.get(tokenServiceEnabledSettings));
519+
assertThat(ile.getMessage(),
520+
containsString("failed to parse value [120m] for setting [xpack.security.authc.token.timeout], must be <= [1h]"));
521+
}
522+
499523
public void testTokenExpiry() throws Exception {
500524
ClockMock clock = ClockMock.frozen();
501525
TokenService tokenService = new TokenService(tokenServiceEnabledSettings, clock, client, securityIndex, clusterService);

0 commit comments

Comments
 (0)