Skip to content

Commit

Permalink
【安全】序列化安全能力增强,支持自定义序列化package白名单列表,提升安全性及定制性;
Browse files Browse the repository at this point in the history
xuxueli committed Dec 31, 2024
1 parent 1dca166 commit cf3bb5d
Showing 14 changed files with 159 additions and 52 deletions.
2 changes: 1 addition & 1 deletion doc/XXL-RPC官方文档.md
Original file line number Diff line number Diff line change
@@ -856,7 +856,7 @@ XXL-RPC默认将 "XXL-RPC-ADMIN" 作为原生注册中心。其他Java服务框
### v1.8.1 Release Notes[2024-11-24]
- 1、【优化】仓库模块 xxl-rpc-netty-shade 接耦拆分;升级netty版本至最新版;
- 3、【优化】long-polling逻辑完善;
- 4、【TODO】【安全】序列化组件强化,提升安全性及定制性;
- 4、【安全】序列化安全能力增强,支持自定义序列化package白名单列表,提升安全性及定制性;
- 5、【TODO】通讯报文长度可配置;
- 6、【TODO】路由对象支持可配置,当前根据iface,太固定;
- 7、【TODO】客户端并发锁超时优化;
Original file line number Diff line number Diff line change
@@ -2,10 +2,6 @@

import com.xxl.rpc.core.invoker.call.CallType;
import com.xxl.rpc.core.invoker.route.LoadBalance;
import com.xxl.rpc.core.remoting.Client;
import com.xxl.rpc.core.remoting.impl.netty.client.NettyClient;
import com.xxl.rpc.core.serializer.Serializer;
import com.xxl.rpc.core.serializer.impl.JsonbSerializer;

import java.lang.annotation.*;

@@ -33,20 +29,6 @@
*/
String version() default "";

/**
* client
*
* @return
*/
Class<? extends Client> client() default NettyClient.class;

/**
* serializer
*
* @return
*/
Class<? extends Serializer> serializer() default JsonbSerializer.class;

/**
* callType
*
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
package com.xxl.rpc.core.invoker.config;

import com.xxl.rpc.core.remoting.Client;
import com.xxl.rpc.core.remoting.impl.netty.client.NettyClient;
import com.xxl.rpc.core.serializer.Serializer;
import com.xxl.rpc.core.serializer.impl.JsonbSerializer;

import java.util.List;

/**
* invoke config
*
@@ -12,6 +19,21 @@ public class InvokerConfig {
*/
private boolean open = true;

/**
* client, for network
*/
private Class<? extends Client> client = NettyClient.class;

/**
* serializer, process request and response
*/
private Class<? extends Serializer> serializer = JsonbSerializer.class;

/**
* serializer allow package list, for security
*/
private List<String> serializerAllowPackageList;

/**
* accessToken (optional), for rpc-safe
*/
@@ -21,6 +43,12 @@ public class InvokerConfig {

public InvokerConfig() {
}
public InvokerConfig(boolean open, Class<? extends Client> client, Class<? extends Serializer> serializer, List<String> serializerAllowPackageList) {
this.open = open;
this.client = client;
this.serializer = serializer;
this.serializerAllowPackageList = serializerAllowPackageList;
}
public InvokerConfig(boolean open) {
this.open = open;
}
@@ -33,4 +61,28 @@ public void setOpen(boolean open) {
this.open = open;
}

public Class<? extends Client> getClient() {
return client;
}

public void setClient(Class<? extends Client> client) {
this.client = client;
}

public Class<? extends Serializer> getSerializer() {
return serializer;
}

public void setSerializer(Class<? extends Serializer> serializer) {
this.serializer = serializer;
}

public List<String> getSerializerAllowPackageList() {
return serializerAllowPackageList;
}

public void setSerializerAllowPackageList(List<String> serializerAllowPackageList) {
this.serializerAllowPackageList = serializerAllowPackageList;
}

}
Original file line number Diff line number Diff line change
@@ -52,16 +52,6 @@ public class XxlRpcReferenceBean {
*/
private String version = null;

/**
* client, for network
*/
private Class<? extends Client> client = NettyClient.class;

/**
* serializer, process request and response
*/
private Class<? extends Serializer> serializer = JsonbSerializer.class;

/**
* call type
*/
@@ -87,12 +77,6 @@ public void setIface(Class<?> iface) {
public void setVersion(String version) {
this.version = version;
}
public void setClient(Class<? extends Client> client) {
this.client = client;
}
public void setSerializer(Class<? extends Serializer> serializer) {
this.serializer = serializer;
}
public void setCallType(CallType callType) {
this.callType = callType;
}
@@ -139,12 +123,6 @@ private void valid() throws Exception {
if (this.iface == null) {
throw new XxlRpcException("xxl-rpc reference iface missing.");
}
if (this.client == null) {
throw new XxlRpcException("xxl-rpc reference client missing.");
}
if (this.serializer == null) {
throw new XxlRpcException("xxl-rpc reference serializer missing.");
}
if (this.callType == null) {
throw new XxlRpcException("xxl-rpc reference callType missing.");
}
@@ -155,11 +133,20 @@ private void valid() throws Exception {
throw new XxlRpcException("xxl-rpc reference timeout invlid.");
}

// build instance
// valid invoker config
if (rpcBootstrap == null) {
throw new XxlRpcException("xxl-rpc reference rpcBootstrap missing.");
}
this.serializerInstance = serializer.newInstance();
if (rpcBootstrap.getInvokerConfig().getClient() == null) {
throw new XxlRpcException("xxl-rpc reference client missing.");
}
if (rpcBootstrap.getInvokerConfig().getSerializer() == null) {
throw new XxlRpcException("xxl-rpc reference serializer missing.");
}

// build instance
this.serializerInstance = rpcBootstrap.getInvokerConfig().getSerializer().newInstance();
this.serializerInstance.allowPackageList(rpcBootstrap.getInvokerConfig().getSerializerAllowPackageList());
}


@@ -251,7 +238,7 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
XxlRpcResponseFuture rpcFuture = null;
try {
// get client instance
Client clientInstance = rpcBootstrap.getInvoker().getClient(registerInstance, client, serializerInstance);
Client clientInstance = rpcBootstrap.getInvoker().getClient(registerInstance, rpcBootstrap.getInvokerConfig().getClient(), serializerInstance);

// send request
if (CallType.SYNC == callType) {
Original file line number Diff line number Diff line change
@@ -42,8 +42,6 @@ public void doWith(Field field) throws IllegalArgumentException, IllegalAccessEx
referenceBean.setAppname(rpcReference.appname());
referenceBean.setIface(iface);
referenceBean.setVersion(rpcReference.version());
referenceBean.setClient(rpcReference.client());
referenceBean.setSerializer(rpcReference.serializer());
referenceBean.setCallType(rpcReference.callType());
referenceBean.setLoadBalance(rpcReference.loadBalance());
referenceBean.setTimeout(rpcReference.timeout());
Original file line number Diff line number Diff line change
@@ -87,6 +87,7 @@ public void start() throws Exception {

// 1、serializer init
this.serializerInstance = rpcBootstrap.getProviderConfig().getSerializer().newInstance();
this.serializerInstance.allowPackageList(rpcBootstrap.getProviderConfig().getSerializerAllowPackageList());

// 2、server init
this.serverInstance = rpcBootstrap.getProviderConfig().getServer().newInstance();
Original file line number Diff line number Diff line change
@@ -5,6 +5,8 @@
import com.xxl.rpc.core.serializer.Serializer;
import com.xxl.rpc.core.serializer.impl.JsonbSerializer;

import java.util.List;

/**
* Provider Config
*
@@ -27,6 +29,11 @@ public class ProviderConfig {
*/
private Class<? extends Serializer> serializer = JsonbSerializer.class;

/**
* serializer allow package list, for security
*/
private List<String> serializerAllowPackageList;

/**
* server port (generate address)
*/
@@ -56,13 +63,15 @@ public ProviderConfig() {
}
public ProviderConfig(Class<? extends Server> server,
Class<? extends Serializer> serializer,
List<String> serializerAllowPackageList,
int port,
int corePoolSize,
int maxPoolSize,
String address) {
this.open = true;
this.server = server;
this.serializer = serializer;
this.serializerAllowPackageList = serializerAllowPackageList;
this.port = port;
this.corePoolSize = corePoolSize;
this.maxPoolSize = maxPoolSize;
@@ -96,6 +105,14 @@ public void setSerializer(Class<? extends Serializer> serializer) {
this.serializer = serializer;
}

public List<String> getSerializerAllowPackageList() {
return serializerAllowPackageList;
}

public void setSerializerAllowPackageList(List<String> serializerAllowPackageList) {
this.serializerAllowPackageList = serializerAllowPackageList;
}

public int getPort() {
return port;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.xxl.rpc.core.serializer;

import java.util.List;

/**
* serializer
*
@@ -11,6 +13,13 @@
*/
public abstract class Serializer {

/**
* allow package list
*
* @param packageList
*/
public abstract void allowPackageList(List<String> packageList);

/**
* serialize
*
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.xxl.rpc.core.serializer.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.filter.Filter;
import com.xxl.rpc.core.serializer.Serializer;

import java.util.List;

/**
* jsonb serializer
*
* @author xuxueli 2024-12-27
*/
public class JsonSerializer extends Serializer {

/**
* jsonb reader autoTypeBeforeHandler
*/
private static Filter autoTypeBeforeHandler = JSONReader.autoTypeFilter("com", "org","io");

/**
* allowPackageList
*
* @param packageList
*/
@Override
public void allowPackageList(List<String> packageList) {
if (packageList!=null && !packageList.isEmpty()) {
autoTypeBeforeHandler = JSONReader.autoTypeFilter((String[]) packageList.toArray());
}
}

@Override
public <T> byte[] serialize(T obj) {
return JSON.toJSONBytes(obj,
JSONWriter.Feature.WriteClassName);
}

@Override
public <T> Object deserialize(byte[] bytes, Class<T> clazz) {
return JSON.parseObject(bytes, clazz,
autoTypeBeforeHandler,
JSONReader.Feature.SupportClassForName
/*JSONReader.Feature.SupportAutoType*/);
}

}
Original file line number Diff line number Diff line change
@@ -6,6 +6,10 @@
import com.alibaba.fastjson2.filter.Filter;
import com.xxl.rpc.core.serializer.Serializer;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
* jsonb serializer
*
@@ -16,8 +20,15 @@ public class JsonbSerializer extends Serializer {
/**
* jsonb reader autoTypeBeforeHandler
*/
private static final Filter autoTypeBeforeHandler = JSONReader.autoTypeFilter("com", "org","io");
private static Filter autoTypeBeforeHandler = JSONReader.autoTypeFilter("com", "org","io");


@Override
public void allowPackageList(List<String> packageList) {
if (packageList!=null && !packageList.isEmpty()) {
autoTypeBeforeHandler = JSONReader.autoTypeFilter((String[]) packageList.toArray());
}
}

@Override
public <T> byte[] serialize(T obj) {
Original file line number Diff line number Diff line change
@@ -33,7 +33,7 @@ public static void main(String[] args) throws Exception {
XxlRpcBootstrap rpcBootstrap = new XxlRpcBootstrap();
rpcBootstrap.setBaseConfig(new BaseConfig("test", "xxl-rpc-sample-frameless-client"));
rpcBootstrap.setRegister(localRegister);
rpcBootstrap.setInvokerConfig(new InvokerConfig(true));
rpcBootstrap.setInvokerConfig(new InvokerConfig(true, NettyClient.class, JsonbSerializer.class, null));

// 3、start
rpcBootstrap.start();
@@ -58,8 +58,6 @@ public static void main(String[] args) throws Exception {

private static DemoService buildReferenceBean(XxlRpcBootstrap rpcBootstrap, CallType callType) throws Exception {
XxlRpcReferenceBean referenceBean = new XxlRpcReferenceBean();
referenceBean.setClient(NettyClient.class);
referenceBean.setSerializer(JsonbSerializer.class);
referenceBean.setCallType(callType);
referenceBean.setLoadBalance(LoadBalance.ROUND);
referenceBean.setIface(DemoService.class);
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ public static void main(String[] args) throws Exception {
// 1、XxlRpcBootstrap
XxlRpcBootstrap rpcBootstrap = new XxlRpcBootstrap();
rpcBootstrap.setBaseConfig(new BaseConfig("test", "xxl-rpc-sample-frameless-server"));
rpcBootstrap.setProviderConfig(new ProviderConfig(NettyServer.class, JsonbSerializer.class, -1, -1, 7080, null));
rpcBootstrap.setProviderConfig(new ProviderConfig(NettyServer.class, JsonbSerializer.class, null, -1, -1, 7080, null));

// 2、start
rpcBootstrap.start();
Loading

0 comments on commit cf3bb5d

Please sign in to comment.