From d503665c743c17b4446c1eef58ac3733af2fde85 Mon Sep 17 00:00:00 2001 From: Jakob Odersky Date: Tue, 12 Jun 2018 15:32:16 -0700 Subject: Improve security of generated tokens (#174) Also deprecates the token generators in core. Fixes SECURITY-29 --- src/main/scala/xyz/driver/core/generators.scala | 30 ++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/main/scala/xyz/driver/core/generators.scala b/src/main/scala/xyz/driver/core/generators.scala index 3c85447..d57980e 100644 --- a/src/main/scala/xyz/driver/core/generators.scala +++ b/src/main/scala/xyz/driver/core/generators.scala @@ -17,17 +17,37 @@ object generators { private val random = new Random import random._ + private val secureRandom = new java.security.SecureRandom() private val DefaultMaxLength = 10 private val StringLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ".toSet - private val NonAmbigiousCharacters = "abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789".toSet - private val Numbers = "0123456789".toSet - - private def nextTokenString(length: Int, charSet: Set[Char]): String = - List.fill(length)(oneOf(charSet)).mkString + private val NonAmbigiousCharacters = "abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789" + private val Numbers = "0123456789" + + private def nextTokenString(length: Int, chars: IndexedSeq[Char]): String = { + val builder = new StringBuilder + for (_ <- 0 until length) { + builder += chars(secureRandom.nextInt(chars.length)) + } + builder.result() + } + /** Creates a random invitation token. + * + * This token is meant fo human input and avoids using ambiguous characters such as 'O' and '0'. It + * therefore contains less entropy and is not meant to be used as a cryptographic secret. */ + @deprecated( + "The term 'token' is too generic and security and readability conventions are not well defined. " + + "Services should implement their own version that suits their security requirements.", + "1.11.0" + ) def nextToken(length: Int): String = nextTokenString(length, NonAmbigiousCharacters) + @deprecated( + "The term 'token' is too generic and security and readability conventions are not well defined. " + + "Services should implement their own version that suits their security requirements.", + "1.11.0" + ) def nextNumericToken(length: Int): String = nextTokenString(length, Numbers) def nextInt(maxValue: Int, minValue: Int = 0): Int = random.nextInt(maxValue - minValue) + minValue -- cgit v1.2.3