Skip to content

Commit

Permalink
Introduce maproulette.secret.key conf and MAPROULETTE_SECRET_KEY env (#…
Browse files Browse the repository at this point in the history
…1128)

MapRoulette API had a dependency on the Play framework's secret key, and this patch separates those keys.
The MapRoulette secret is used to encrypt things specific to maproulette and it no longer depends on the Play application key.

Play 2.9 introduced a change where its application key must be 32 bytes or longer, and this impacted MapRoulette's cryptography with its own internal items. It's easier to manage these separately, similar to how the OSM secrets are not used to encrypt data stored within MapRoulette.
  • Loading branch information
ljdelight authored Jun 2, 2024
1 parent b130e56 commit c6d2bf3
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 4 deletions.
7 changes: 4 additions & 3 deletions app/org/maproulette/framework/model/User.scala
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ object User extends CommonField {
implicit val osmReads: Reads[OSMProfile] = Json.reads[OSMProfile]
implicit val searchResultWrites: Writes[UserSearchResult] = Json.writes[UserSearchResult]
implicit val projectManagerWrites: Writes[ProjectManager] = Json.writes[ProjectManager]
val logger = LoggerFactory.getLogger(this.getClass)

val TABLE = "users"
val FIELD_OSM_ID = "osm_id"
Expand Down Expand Up @@ -416,9 +417,9 @@ object User extends CommonField {
user.copy(apiKey = decryptedAPIKey)
} catch {
case _: BadPaddingException | _: IllegalBlockSizeException =>
LoggerFactory
.getLogger(this.getClass)
.debug("Invalid key found, could be that the application secret on server changed.")
logger.debug(
"Invalid key found, could be that the application secret on server changed."
)
user
case e: Throwable => throw e
}
Expand Down
2 changes: 1 addition & 1 deletion app/org/maproulette/utils/Crypto.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import org.maproulette.Config
*/
@Singleton
class Crypto @Inject() (config: Config) {
val key = config.config.get[String]("play.http.secret.key")
val key: String = config.config.get[String]("maproulette.secret.key")

def encrypt(value: String): String = {
val cipher: Cipher = Cipher.getInstance("AES/ECB/PKCS5Padding")
Expand Down
6 changes: 6 additions & 0 deletions conf/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,12 @@ maproulette {
publicOrigin="https://maproulette.org"
emailFrom="[email protected]"

# The MapRoulette API secret key used to encrypt/decrypt sensitive things from the database, like user API Keys.
# Do not use the default value in production, generate a new key and set it via conf or 'MAPROULETTE_SECRET_KEY' env.
# A secure way to get a distinct key is to run 'openssl rand -base64 32' and set the output as the secret key.
secret.key = "%APPLICATION_SECRET%"
secret.key = "${?MAPROULETTE_SECRET_KEY}"

# redirect for OSM
frontend="http://127.0.0.1:3000"

Expand Down
12 changes: 12 additions & 0 deletions conf/dev.conf.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
include "application.conf"

# The Play application secret key. It's okay for localhost dev conf to be public, but not for any public environment.
# A secure way to get a distinct key is to run 'openssl rand -base64 32' and set the output as the secret key.
# Play 2.9 requires a key of at least 32 characters https://github.com/maproulette/maproulette-backend/issues/1117
play.http.secret.key = "DEVLOCAL_1z8rvducX6AaMTXQl4olw71YHj3MCFpRXXTB73TNnTc="
play.http.secret.key = "${?APPLICATION_SECRET}"

db.default {
url="jdbc:postgresql://localhost:5432/mp_dev"
url=${?MR_DATABASE_URL}
Expand All @@ -16,6 +22,12 @@ maproulette {
debug=true
bootstrap=true

# The MapRoulette API secret key used to encrypt/decrypt sensitive things from the database, like user API Keys.
# Do not use the default value in production, generate a new key and set it via conf or 'MAPROULETTE_SECRET_KEY' env.
# A secure way to get a distinct key is to run 'openssl rand -base64 32' and set the output as the secret key.
secret.key = "DEVLOCAL_Jw8W2PMl434eL85+IRvoT7DA+eNR9a9N3ZK2Gfx4ecs="
secret.key = "${?MAPROULETTE_SECRET_KEY}"

scheduler {
startTimeJitterForMinuteTasks = "15 seconds"
startTimeJitterForHourTasks = "30 seconds"
Expand Down

0 comments on commit c6d2bf3

Please sign in to comment.