|
24 | 24 | import java.io.ByteArrayOutputStream; |
25 | 25 | import java.io.IOException; |
26 | 26 | import java.io.InvalidClassException; |
| 27 | +import java.io.ObjectInputFilter; |
27 | 28 | import java.io.ObjectInputStream; |
28 | 29 | import java.io.ObjectOutputStream; |
29 | 30 | import java.net.ServerSocket; |
@@ -69,6 +70,29 @@ public class TransformUpgrader implements AutoCloseable { |
69 | 70 | private static final Logger LOG = LoggerFactory.getLogger(TransformUpgrader.class); |
70 | 71 | private static final String UPGRADE_NAMESPACE = "transform:upgrade:"; |
71 | 72 |
|
| 73 | + public static final String DESERIALIZATION_FILTER_PROPERTY = |
| 74 | + "beam.transformUpgrader.deserializationFilter"; |
| 75 | + |
| 76 | + private static final String DEFAULT_DESERIALIZATION_FILTER_PATTERN = |
| 77 | + "maxdepth=100;maxrefs=10000;maxbytes=10485760;maxarray=10000;" |
| 78 | + + "org.apache.beam.**;" |
| 79 | + + "com.google.**;" |
| 80 | + + "org.apache.kafka.**;" |
| 81 | + + "org.apache.avro.**;" |
| 82 | + + "org.joda.time.**;" |
| 83 | + + "!java.lang.ProcessBuilder;" |
| 84 | + + "!java.lang.Runtime;" |
| 85 | + + "!java.lang.Thread;" |
| 86 | + + "java.lang.**;" |
| 87 | + + "java.util.**;" |
| 88 | + + "java.io.**;" |
| 89 | + + "java.math.**;" |
| 90 | + + "java.time.**;" |
| 91 | + + "!*"; |
| 92 | + |
| 93 | + private static final ObjectInputFilter DEFAULT_DESERIALIZATION_FILTER = |
| 94 | + ObjectInputFilter.Config.createFilter(DEFAULT_DESERIALIZATION_FILTER_PATTERN); |
| 95 | + |
72 | 96 | @VisibleForTesting static final String UPGRADE_KEY = "upgraded_to_version"; |
73 | 97 |
|
74 | 98 | private ExpansionServiceClientFactory clientFactory; |
@@ -463,12 +487,21 @@ public static byte[] toByteArray(Object object) { |
463 | 487 | * A utility method that converts a byte array obtained by invoking {@link #toByteArray(Object)} |
464 | 488 | * back to a Java object. |
465 | 489 | * |
| 490 | + * <p>Applies a deserialization filter with resource limits and a package allowlist. The filter |
| 491 | + * pattern can be overridden via the {@link #DESERIALIZATION_FILTER_PROPERTY} system property. |
| 492 | + * |
466 | 493 | * @param bytes an array of bytes generated by invoking the {@link #toByteArray(Object)} method. |
467 | 494 | * @return re-generated object. |
468 | 495 | */ |
469 | 496 | public static Object fromByteArray(byte[] bytes) throws InvalidClassException { |
470 | 497 | try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes); |
471 | 498 | ObjectInputStream in = new ObjectInputStream(bis)) { |
| 499 | + String customPattern = System.getProperty(DESERIALIZATION_FILTER_PROPERTY); |
| 500 | + ObjectInputFilter filter = |
| 501 | + (customPattern != null && !customPattern.isEmpty()) |
| 502 | + ? ObjectInputFilter.Config.createFilter(customPattern) |
| 503 | + : DEFAULT_DESERIALIZATION_FILTER; |
| 504 | + in.setObjectInputFilter(filter); |
472 | 505 | return in.readObject(); |
473 | 506 | } catch (InvalidClassException e) { |
474 | 507 | LOG.info( |
|
0 commit comments