[Bug] Auto-trusted serialization allow list skips array component classes
I maintainer di solito rispondono entro 1 giorno
@Icesource ci sta già lavorando.
Dal 4/11/2026.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 78/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- java
- Ambito
- distributed-systems
Direzione di ricerca
Inizia leggendo SerializeSecurityConfigurator.checkClass e il suo attraversamento a partire dalle firme dei servizi. Segui la gestione degli array e confrontala con il ramo GenericArrayType di checkType; poi esamina i test esistenti sulla sicurezza della serializzazione per individuare il punto giusto in cui aggiungere un caso di regressione. Il lavoro è concluso quando un Payload[] dichiarato fa sì che Payload venga considerato attendibile automaticamente e il test di regressione copre l’errore Hessian2 segnalato in modalità STRICT.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Pre-check
- I am sure that all the content I provide is in English.
Search before asking
- I searched existing issues and found no report of this concrete array-component case.
Related reports such as #13752 (generic/subtype allow-list questions) and #16491 (sealed subtypes) have different triggers.
Apache Dubbo Component
Java SDK (apache/dubbo)
Dubbo Version
- Apache Dubbo 3.3.6, using the official Maven artifact.
- OpenJDK 17.0.20.1 (Homebrew), macOS 26.3.2.
- The same array early-return is present on the current
3.3branch at2d9730c6ab4358d94c6e3594fdd2dca0009fe912.
Steps to reproduce this issue
Declare a serializable DTO only through an array in a service signature:
public interface ArrayService { Payload[] read(); }
public static class Payload implements Serializable { public String text = "ok"; }
With autoTrustSerializeClass=true, exact-class trust (the default), STRICT checking and Hessian2, an ordinary call to read() fails while the provider serializes the response. Payload[] is auto-trusted, but Payload is not.
The reproduction below uses a real loopback dubbo:// transport with injvm=false, no registry and no custom allow-list. Provider and consumer run in one JVM. Each command starts a fresh JVM so that allow-list state cannot leak between cases.
Complete runnable reproduction
Save this as pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>repro</groupId>
<artifactId>dubbo-array-trust</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>3.3.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.36</version>
</dependency>
</dependencies>
</project>
Save this as RpcArrayProbe.java:
package com.review.probe;
import java.io.Serializable;
import java.net.ServerSocket;
import org.apache.dubbo.config.*;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
public class RpcArrayProbe {
public interface ArrayService { Payload[] read(); }
public static class Payload implements Serializable { public String text = "ok"; }
public static class ArrayServiceImpl implements ArrayService {
public Payload[] read() { return new Payload[]{new Payload()}; }
}
public static void main(String[] args) throws Exception {
int port;
try (ServerSocket socket = new ServerSocket(0, 1, java.net.InetAddress.getLoopbackAddress())) {
port = socket.getLocalPort();
}
ApplicationConfig app = new ApplicationConfig("array-rpc-probe");
app.setQosEnable(false);
app.setSerializeCheckStatus(args[1]);
ProtocolConfig protocol = new ProtocolConfig("dubbo", port);
protocol.setHost("127.0.0.1");
protocol.setSerialization(args[0]);
protocol.setPreferSerialization(args[0]);
ServiceConfig<ArrayService> service = new ServiceConfig<>();
service.setInterface(ArrayService.class);
service.setRef(new ArrayServiceImpl());
DubboBootstrap bootstrap = DubboBootstrap.getInstance();
ReferenceConfig<ArrayService> reference = new ReferenceConfig<>();
try {
bootstrap.application(app).registry(new RegistryConfig("N/A")).protocol(protocol).service(service).start();
reference.setInterface(ArrayService.class);
reference.setUrl("dubbo://127.0.0.1:" + port + "?serialization=" + args[0]
+ "&prefer.serialization=" + args[0]);
reference.setInjvm(false);
reference.setRetries(0);
reference.setTimeout(5000);
Payload[] result = reference.get().read();
if (result.length != 1 || !"ok".equals(result[0].text)) throw new AssertionError();
System.out.println("RPC_RESULT " + String.join(" ", args) + " PASS");
} catch (Throwable failure) {
System.out.println("RPC_RESULT " + String.join(" ", args) + " FAIL " + failure);
} finally {
reference.destroy();
bootstrap.destroy();
}
}
}
Run on JDK 17:
mvn -B -ntp dependency:build-classpath -Dmdep.outputFile=classpath.txt
mkdir -p classes
javac -cp "$(cat classpath.txt)" -d classes RpcArrayProbe.java
java -cp "classes:$(cat classpath.txt)" com.review.probe.RpcArrayProbe hessian2 STRICT
java -cp "classes:$(cat classpath.txt)" com.review.probe.RpcArrayProbe hessian2 WARN
java -cp "classes:$(cat classpath.txt)" com.review.probe.RpcArrayProbe fastjson2 STRICT
Observed results on 3.3.6:
| Serializer | Check mode | Result |
|---|---|---|
| Hessian2 | STRICT | Fails: Payload is not in the allow list |
| Hessian2 | WARN | Succeeds |
| Fastjson2 | STRICT | Succeeds for this concrete array-return case |
Relevant failure (transport wrapper omitted):
Failed to send response
java.io.IOException: org.apache.dubbo.common.serialize.SerializationException:
java.lang.IllegalArgumentException: [Serialization Security] Serialized class
com.review.probe.RpcArrayProbe$Payload is not in allow list.
Current mode is `STRICT`, will disallow to deserialize it by default.
What you expected to happen
The declared component class Payload should be auto-trusted when Payload[] is reached during service-signature scanning, along with the fields normally visited for a directly declared Payload.
SerializeSecurityConfigurator.checkClass currently adds the array class and returns immediately when clazz.isArray() is true. It never visits clazz.getComponentType(). A concrete Payload[] is represented as a Class, so the existing GenericArrayType branch in checkType does not compensate for this.
Anything else
This is a functional compatibility issue in automatic allow-list discovery. It does not affect every array call: an explicit allow-list entry, package-prefix trust, or another scanned signature/field referencing Payload directly can mask the omission. The Fastjson2 result above is limited to this reproduction.
A minimal fix is to visit the array component through the existing checkClass traversal. That also covers multidimensional arrays and DTO array fields, while retaining the existing visited-type cache and exact-class trust policy.
Do you have a (mini) reproduction demo?
- Yes, the complete reproduction is included above.
Are you willing to submit a pull request to fix on your own?
- Yes, I am submitting a fix with regression tests.
Code of Conduct
- I agree to follow this project's Code of Conduct.
Fix and related follow-up
The array component fix for this issue is https://github.com/apache/dubbo/pull/16570 (linked to close this issue on merge).
A separate allow-list scanning problem involving missing optional dependencies is tracked in https://github.com/apache/dubbo/issues/16574, with its independent fix in https://github.com/apache/dubbo/pull/16575. That follow-up addresses traversal failure isolation; it does not replace the array component fix.
- Lingua principale
- Java
- Stelle
- 41.6k
- Fork
- 26.3k
- Merge medio
- 1g 22h
- PR unite (30g)
- 19
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di apache/dubbo
-
[Bug] QoS count command ignores the times argument after cdForse già presa @CCCLL l’ha presa 19 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
apache/dubbo#16530 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
[Bug] AccessLogFilter accesslog path warnings are garbled and name the wrong accesslog.fixed.path valueForse già presa @CCCLL l’ha presa 19 giorni fa. Aperta
Difficoltà 1/5 1-3 ore Idoneità per principianti 88/100
I maintainer di solito rispondono entro 1 giorno
-
[Bug] dubbo.protocol.triple.max-message-size is only read from OS environment variablesForse già presa @CCCLL l’ha presa 20 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
I maintainer di solito rispondono entro 1 giorno
-
[Bug] StreamUtils treats InputStream.available() as the remaining stream lengthForse già presa Una pull request collegata a questa issue è aperta o già unita. Apertacomponent/need-triage type/need-triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
apache/dubbo#16510 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
[Bug] Negative frame data length causes IllegalArgumentException in ExchangeCodecForse già presa @L1nq0 l’ha presa 64 giorni fa. Apertacomponent/need-triage type/need-triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di apache/dubbo
Issue simili
-
Document and enforce pull request review guidelinesForse già presa @dashorst l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
I maintainer di solito rispondono entro 1 giorno
-
`Time.at(t, in: nil)` returns UTC instead of the local time (or the time zone of `t`), unlike CRubyAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
hermes-queue
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 72/100
chrisalunlloyd2-sudo/mindpalace#349 ·
I maintainer di solito rispondono entro 1 giorno
-
Retry-After parser accepts invalid delay-seconds valuesForse già presa @Dhruvraj-Rana l’ha presa oggi. ApertaBug
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
open-telemetry/opentelemetry-java#9018 ·
I maintainer di solito rispondono entro 2 giorni
-
dropwizard-testing: DAOTest.inTransaction leaves the transaction open when an Error is thrownAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
dropwizard/dropwizard#11410 ·
I maintainer di solito rispondono entro 1 giorno