Skip to content

Commit 647e8da

Browse files
authored
do not render env variables in configs (#771) (#791)
* do not render env variables in configs * redact username when logging configs * Update ActorSystemSpec.scala * add test scalafmt * try/finally
1 parent 1206d71 commit 647e8da

File tree

6 files changed

+91
-13
lines changed

6 files changed

+91
-13
lines changed

actor-tests/src/test/scala/org/apache/pekko/actor/ActorSystemSpec.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,23 @@ class ActorSystemSpec extends PekkoSpec(ActorSystemSpec.config) with ImplicitSen
380380
}
381381
} finally shutdown(sys)
382382
}
383+
"not include username in toString" in {
384+
// Actor System toString is output to logs and we don't want env variable values appearing in logs
385+
val system =
386+
ActorSystem(
387+
"config-test-system",
388+
ConfigFactory
389+
.parseString("""pekko.test.java.property.home = "${user.home}"""")
390+
.withFallback(PekkoSpec.testConf))
391+
try {
392+
val debugText = system.settings.toString
393+
val username = System.getProperty("user.name")
394+
val userHome = System.getProperty("user.home")
395+
(debugText should not).include(username)
396+
(debugText should not).include(userHome)
397+
debugText should include("<username>")
398+
} finally shutdown(system)
399+
}
383400
}
384401

385402
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.pekko.actor.typed
19+
20+
import com.typesafe.config.ConfigFactory
21+
import org.apache.pekko
22+
import pekko.actor.typed.scaladsl.Behaviors
23+
import pekko.testkit.PekkoSpec
24+
25+
import scala.annotation.nowarn
26+
27+
@nowarn("msg=possible missing interpolator")
28+
class ActorSystemSpec extends PekkoSpec {
29+
"ActorSystem" should {
30+
"not include username in toString" in {
31+
// Actor System toString is output to logs and we don't want env variable values appearing in logs
32+
val system = ActorSystem(Behaviors.empty[String], "config-test-system",
33+
ConfigFactory
34+
.parseString("""pekko.test.java.property.home = "${user.home}"""")
35+
.withFallback(PekkoSpec.testConf))
36+
try {
37+
val debugText = system.settings.toString
38+
val username = System.getProperty("user.name")
39+
val userHome = System.getProperty("user.home")
40+
(debugText should not).include(username)
41+
(debugText should not).include(userHome)
42+
debugText should include("<username>")
43+
} finally {
44+
system.terminate()
45+
}
46+
}
47+
}
48+
}

actor-typed/src/main/scala/org/apache/pekko/actor/typed/ActorSystem.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import scala.concurrent.{ ExecutionContextExecutor, Future }
1919

2020
import com.typesafe.config.{ Config, ConfigFactory }
2121
import org.slf4j.Logger
22-
2322
import org.apache.pekko
2423
import pekko.{ actor => classic, Done }
2524
import pekko.actor.{ Address, BootstrapSetup, ClassicActorSystemProvider }
@@ -29,7 +28,7 @@ import pekko.actor.typed.internal.{ EventStreamExtension, InternalRecipientRef }
2928
import pekko.actor.typed.internal.adapter.{ ActorSystemAdapter, GuardianStartupBehavior, PropsAdapter }
3029
import pekko.actor.typed.receptionist.Receptionist
3130
import pekko.annotation.DoNotInherit
32-
import pekko.util.Helpers.Requiring
31+
import pekko.util.Helpers.{ ConfigOps, Requiring }
3332

3433
/**
3534
* An ActorSystem is home to a hierarchy of Actors. It is created using
@@ -324,7 +323,7 @@ final class Settings(val config: Config, val classicSettings: classic.ActorSyste
324323
/**
325324
* Returns the String representation of the Config that this Settings is backed by
326325
*/
327-
override def toString: String = config.root.render
326+
override def toString: String = config.renderWithRedactions()
328327

329328
private val typedConfig = config.getConfig("pekko.actor.typed")
330329

actor/src/main/scala/org/apache/pekko/actor/ActorSystem.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ object ActorSystem {
489489
/**
490490
* Returns the String representation of the Config that this Settings is backed by
491491
*/
492-
override def toString: String = config.root.render
492+
override def toString: String = config.renderWithRedactions()
493493

494494
}
495495

actor/src/main/scala/org/apache/pekko/dispatch/Dispatchers.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414
package org.apache.pekko.dispatch
1515

1616
import java.util.concurrent.{ ConcurrentHashMap, ThreadFactory }
17-
import scala.concurrent.ExecutionContext
1817
import scala.annotation.{ nowarn, tailrec }
18+
import scala.concurrent.ExecutionContext
19+
1920
import com.typesafe.config.{ Config, ConfigFactory, ConfigValueType }
2021
import org.apache.pekko
2122
import pekko.ConfigurationException
@@ -259,7 +260,8 @@ class Dispatchers @InternalApi private[pekko] (
259260
*/
260261
private def configuratorFrom(cfg: Config): MessageDispatcherConfigurator = {
261262
if (!cfg.hasPath("id"))
262-
throw new ConfigurationException("Missing dispatcher 'id' property in config: " + cfg.root.render)
263+
throw new ConfigurationException("Missing dispatcher 'id' property in config: " +
264+
cfg.renderWithRedactions())
263265

264266
cfg.getString("type") match {
265267
case "Dispatcher" => new DispatcherConfigurator(cfg, prerequisites)

actor/src/main/scala/org/apache/pekko/util/Helpers.scala

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,12 @@ package org.apache.pekko.util
2828

2929
import java.time.{ Instant, LocalDateTime, ZoneId }
3030
import java.time.format.DateTimeFormatter
31-
import java.util.Comparator
32-
import java.util.Locale
31+
import java.util.{ Comparator, Locale }
3332
import java.util.concurrent.TimeUnit
3433
import java.util.regex.Pattern
35-
3634
import scala.annotation.tailrec
37-
import scala.concurrent.duration.Duration
38-
import scala.concurrent.duration.FiniteDuration
39-
40-
import com.typesafe.config.Config
35+
import scala.concurrent.duration.{ Duration, FiniteDuration }
36+
import com.typesafe.config.{ Config, ConfigRenderOptions }
4137

4238
object Helpers {
4339

@@ -179,6 +175,22 @@ object Helpers {
179175

180176
def getNanosDuration(path: String): FiniteDuration = getDuration(path, TimeUnit.NANOSECONDS)
181177

178+
/**
179+
* Used to redact sensitive information in config data when we are logging it
180+
* or adding it to exception messages.
181+
*
182+
* This includes redacting environment variable values and the username associated with the running process.
183+
*
184+
* @return redacted version of the configuration text
185+
* @see https://github.com/apache/incubator-pekko/pull/771
186+
* @since 1.0.2
187+
*/
188+
def renderWithRedactions(): String = {
189+
val username = System.getProperty("user.name")
190+
val configText = config.root.render(ConfigRenderOptions.defaults().setShowEnvVariableValues(false))
191+
configText.replace(username, "<username>")
192+
}
193+
182194
private def getDuration(path: String, unit: TimeUnit): FiniteDuration =
183195
Duration(config.getDuration(path, unit), unit)
184196
}

0 commit comments

Comments
 (0)