Removing, deprecating and replacing usage of black/whitelist (#29254)

This commit is contained in:
Johan Andrén 2020-06-18 15:48:28 +02:00 committed by GitHub
parent 25ea7b7f5e
commit 1e9e984727
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 168 additions and 144 deletions

View file

@ -105,14 +105,14 @@ The procedure for changing from Java serialization to Jackson would look like:
described in @ref:[Serialization with Jackson](../serialization-jackson.md).
* Test the system with the new serialization in a new test cluster (no rolling update).
* Remove the binding for the marker interface in `akka.actor.serialization-bindings`, so that Jackson is not used for serialization (toBinary) yet.
* Configure `akka.serialization.jackson.whitelist-class-prefix=["com.myapp"]`
* Configure `akka.serialization.jackson.allowed-class-prefix=["com.myapp"]`
* This is needed for Jackson deserialization when the `serialization-bindings` isn't defined.
* Replace `com.myapp` with the name of the root package of your application to trust all classes.
* Roll out the change.
* Java serialization is still used, but this version is prepared for next roll out.
1. Rolling update to enable serialization with Jackson.
* Add the binding to the marker interface in `akka.actor.serialization-bindings` to the Jackson serializer.
* Remove `akka.serialization.jackson.whitelist-class-prefix`.
* Remove `akka.serialization.jackson.allowed-class-prefix`.
* Roll out the change.
* Old nodes will still send messages with Java serialization, and that can still be deserialized by new nodes.
* New nodes will send messages with Jackson serialization, and old node can deserialize those because they were

View file

@ -271,22 +271,22 @@ Scala
Java
: @@snip [RemoteDeploymentDocTest.java](/akka-docs/src/test/java/jdocs/remoting/RemoteDeploymentDocTest.java) { #deploy }
### Remote deployment whitelist
### Remote deployment allow list
As remote deployment can potentially be abused by both users and even attackers a whitelist feature
As remote deployment can potentially be abused by both users and even attackers an allow list feature
is available to guard the ActorSystem from deploying unexpected actors. Please note that remote deployment
is *not* remote code loading, the Actors class to be deployed onto a remote system needs to be present on that
remote system. This still however may pose a security risk, and one may want to restrict remote deployment to
only a specific set of known actors by enabling the whitelist feature.
only a specific set of known actors by enabling the allow list feature.
To enable remote deployment whitelisting set the `akka.remote.deployment.enable-whitelist` value to `on`.
To enable remote deployment allow list set the `akka.remote.deployment.enable-allow-list` value to `on`.
The list of allowed classes has to be configured on the "remote" system, in other words on the system onto which
others will be attempting to remote deploy Actors. That system, locally, knows best which Actors it should or
should not allow others to remote deploy onto it. The full settings section may for example look like this:
@@snip [RemoteDeploymentWhitelistSpec.scala](/akka-remote/src/test/scala/akka/remote/classic/RemoteDeploymentWhitelistSpec.scala) { #whitelist-config }
@@snip [RemoteDeploymentAllowListSpec.scala](/akka-remote/src/test/scala/akka/remote/classic/RemoteDeploymentAllowListSpec.scala) { #allow-list-config }
Actor classes not included in the whitelist will not be allowed to be remote deployed onto this system.
Actor classes not included in the allow list will not be allowed to be remote deployed onto this system.
## Lifecycle and Failure Recovery Model

View file

@ -19,7 +19,7 @@ to ensure that a fix can be provided without delay.
## Security Related Documentation
* @ref:[Java Serialization](../serialization.md#java-serialization)
* @ref:[Remote deployment whitelist](../remoting.md#remote-deployment-whitelist)
* @ref:[Remote deployment allow list](../remoting.md#remote-deployment-allow-list)
* @ref:[Remote Security](../remoting-artery.md#remote-security)
## Fixed Security Vulnerabilities

View file

@ -69,7 +69,7 @@ such as:
* `java.io.Serializable`
* `java.util.Comparable`.
The blacklist of possible serialization gadget classes defined by Jackson databind are checked
The deny list of possible serialization gadget classes defined by Jackson databind are checked
and disallowed for deserialization.
@@@ warning
@ -350,12 +350,12 @@ That type of migration must be configured with the old class name as key. The ac
### Remove from serialization-bindings
When a class is not used for serialization any more it can be removed from `serialization-bindings` but to still
allow deserialization it must then be listed in the `whitelist-class-prefix` configuration. This is useful for example
allow deserialization it must then be listed in the `allowed-class-prefix` configuration. This is useful for example
during rolling update with serialization changes, or when reading old stored data. It can also be used
when changing from Jackson serializer to another serializer (e.g. Protobuf) and thereby changing the serialization
binding, but it should still be possible to deserialize old data with Jackson.
@@snip [config](/akka-serialization-jackson/src/test/scala/doc/akka/serialization/jackson/SerializationDocSpec.scala) { #whitelist-class-prefix }
@@snip [config](/akka-serialization-jackson/src/test/scala/doc/akka/serialization/jackson/SerializationDocSpec.scala) { #allowed-class-prefix }
It's a list of class names or prefixes of class names.

View file

@ -28,13 +28,13 @@ Java
: @@snip [StatefulMapConcat.java](/akka-docs/src/test/java/jdocs/stream/operators/flow/StatefulMapConcat.java) { #zip-with-index }
In this sample we let the value of the elements have an effect on the following elements, if an element starts
with `blacklist:word` we add it to a black list and filter out any subsequent entries of `word`:
with `deny:word` we add it to a deny list and filter out any subsequent entries of `word`:
Scala
: @@snip [StatefulMapConcat.scala](/akka-docs/src/test/scala/docs/stream/operators/flow/StatefulMapConcat.scala) { #blacklist }
: @@snip [StatefulMapConcat.scala](/akka-docs/src/test/scala/docs/stream/operators/flow/StatefulMapConcat.scala) { #denylist }
Java
: @@snip [StatefulMapConcat.java](/akka-docs/src/test/java/jdocs/stream/operators/flow/StatefulMapConcat.java) { #blacklist }
: @@snip [StatefulMapConcat.java](/akka-docs/src/test/java/jdocs/stream/operators/flow/StatefulMapConcat.java) { #denylist }
For cases where there is a need to emit elements based on the state when the stream ends, it is possible to add an extra
element signalling the end of the stream before the `statefulMapConcat` operator.

View file

@ -43,40 +43,39 @@ public class StatefulMapConcat {
// #zip-with-index
}
static void blacklist() {
// #blacklist
Source<String, NotUsed> fruitsAndBlacklistCommands =
static void denylist() {
// #denylist
Source<String, NotUsed> fruitsAndDenyCommands =
Source.from(
Arrays.asList(
"banana", "pear", "orange", "blacklist:banana", "banana", "pear", "banana"));
Arrays.asList("banana", "pear", "orange", "deny:banana", "banana", "pear", "banana"));
Flow<String, String, NotUsed> blacklistingFlow =
Flow<String, String, NotUsed> denyFilterFlow =
Flow.of(String.class)
.statefulMapConcat(
() -> {
Set<String> blacklist = new HashSet<>();
Set<String> denyList = new HashSet<>();
return (element) -> {
if (element.startsWith("blacklist:")) {
blacklist.add(element.substring(10));
if (element.startsWith("deny:")) {
denyList.add(element.substring(10));
return Collections
.emptyList(); // no element downstream when adding a blacklisted keyword
} else if (blacklist.contains(element)) {
.emptyList(); // no element downstream when adding a deny listed keyword
} else if (denyList.contains(element)) {
return Collections
.emptyList(); // no element downstream if element is blacklisted
.emptyList(); // no element downstream if element is deny listed
} else {
return Collections.singletonList(element);
}
};
});
fruitsAndBlacklistCommands.via(blacklistingFlow).runForeach(System.out::println, system);
fruitsAndDenyCommands.via(denyFilterFlow).runForeach(System.out::println, system);
// prints
// banana
// pear
// orange
// pear
// #blacklist
// #denylist
}
static void reactOnEnd() {

View file

@ -34,33 +34,33 @@ class StatefulMapConcat {
// #zip-with-index
}
def blacklist(): Unit = {
// #blacklist
val fruitsAndBlacklistCommands = Source(
"banana" :: "pear" :: "orange" :: "blacklist:banana" :: "banana" :: "pear" :: "banana" :: Nil)
def denylist(): Unit = {
// #denylist
val fruitsAndDeniedCommands = Source(
"banana" :: "pear" :: "orange" :: "deny:banana" :: "banana" :: "pear" :: "banana" :: Nil)
val blacklistingFlow = Flow[String].statefulMapConcat { () =>
var blacklist = Set.empty[String]
val denyFilterFlow = Flow[String].statefulMapConcat { () =>
var denyList = Set.empty[String]
{ element =>
if (element.startsWith("blacklist:")) {
blacklist += element.drop(10)
Nil // no element downstream when adding a blacklisted keyword
} else if (blacklist(element)) {
Nil // no element downstream if element is blacklisted
if (element.startsWith("deny:")) {
denyList += element.drop(10)
Nil // no element downstream when adding a deny listed keyword
} else if (denyList(element)) {
Nil // no element downstream if element is deny listed
} else {
element :: Nil
}
}
}
fruitsAndBlacklistCommands.via(blacklistingFlow).runForeach(println)
fruitsAndDeniedCommands.via(denyFilterFlow).runForeach(println)
// prints
// banana
// pear
// orange
// pear
// #blacklist
// #denylist
}
def reactOnEnd(): Unit = {