fix: 【漏洞】修复sql注入

This commit is contained in:
tjlygdx
2026-05-12 17:27:41 +08:00
parent a7bffa795c
commit f1c7204da1

View File

@@ -131,14 +131,12 @@ public class CalciteProvider extends Provider {
try (ConnectionObj con = getConnection(datasourceRequest.getDatasource())) {
datasourceRequest.setDsVersion(con.getConnection().getMetaData().getDatabaseMajorVersion());
String querySql = getTablesSql(datasourceRequest).get(0);
Statement statement = getStatement(con.getConnection(), 30);
ResultSet resultSet = statement.executeQuery(querySql);
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
QueryAndParams queryAndParams = getTablesSql(datasourceRequest).get(0);
try (PreparedStatement statement = prepareStatement(con.getConnection(), queryAndParams, 30);
ResultSet resultSet = statement.executeQuery()) {
if (resultSet != null) {
resultSet.close();
}
}
} catch (Exception e) {
throw e;
@@ -149,13 +147,15 @@ public class CalciteProvider extends Provider {
@Override
public List<DatasetTableDTO> getTables(DatasourceRequest datasourceRequest) {
List<DatasetTableDTO> tables = new ArrayList<>();
try (Connection con = getConnectionFromPool(datasourceRequest.getDatasource().getId()); Statement statement = getStatement(con, 30)) {
try (Connection con = getConnectionFromPool(datasourceRequest.getDatasource().getId())) {
datasourceRequest.setDsVersion(con.getMetaData().getDatabaseMajorVersion());
List<String> tablesSqls = getTablesSql(datasourceRequest);
for (String tablesSql : tablesSqls) {
ResultSet resultSet = statement.executeQuery(tablesSql);
while (resultSet.next()) {
tables.add(getTableDesc(datasourceRequest, resultSet));
List<QueryAndParams> tablesSqls = getTablesSql(datasourceRequest);
for (QueryAndParams tablesSql : tablesSqls) {
try (PreparedStatement statement = prepareStatement(con, tablesSql, 30);
ResultSet resultSet = statement.executeQuery()) {
while (resultSet.next()) {
tables.add(getTableDesc(datasourceRequest, resultSet));
}
}
}
} catch (Exception e) {
@@ -1409,8 +1409,8 @@ public class CalciteProvider extends Provider {
return sql;
}
private List<String> getTablesSql(DatasourceRequest datasourceRequest) throws DEException {
List<String> tableSqls = new ArrayList<>();
private List<QueryAndParams> getTablesSql(DatasourceRequest datasourceRequest) throws DEException {
List<QueryAndParams> tableSqls = new ArrayList<>();
DatasourceConfiguration.DatasourceType datasourceType = DatasourceConfiguration.DatasourceType.valueOf(datasourceRequest.getDatasource().getType());
DatasourceConfiguration configuration = null;
String database = "";
@@ -1428,13 +1428,13 @@ public class CalciteProvider extends Provider {
database = databasePrams[0];
}
if (database.contains(".")) {
tableSqls.add("show tables");
tableSqls.add(new QueryAndParams("show tables"));
} else {
tableSqls.add(String.format("SELECT TABLE_NAME,TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '%s' ;", database));
tableSqls.add(new QueryAndParams("SELECT TABLE_NAME,TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ?", database));
}
break;
case mongo:
tableSqls.add("show tables");
tableSqls.add(new QueryAndParams("show tables"));
break;
case mysql:
case mariadb:
@@ -1449,44 +1449,112 @@ public class CalciteProvider extends Provider {
String[] databasePrams = matcher.group(3).split("\\?");
database = databasePrams[0];
}
tableSqls.add(String.format("SELECT TABLE_NAME,TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '%s' ;", database));
tableSqls.add(new QueryAndParams("SELECT TABLE_NAME,TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ?", database));
break;
case oracle:
configuration = JsonUtil.parseObject(datasourceRequest.getDatasource().getConfiguration(), Oracle.class);
if (StringUtils.isEmpty(configuration.getSchema())) {
DEException.throwException(Translator.get("i18n_schema_is_empty"));
}
tableSqls.add("select table_name, comments, owner from all_tab_comments where owner='" + configuration.getSchema() + "' AND table_type = 'TABLE'");
tableSqls.add("select table_name, comments, owner from all_tab_comments where owner='" + configuration.getSchema() + "' AND table_type = 'VIEW'");
tableSqls.add("SELECT \n" + " m.mview_name,\n" + " c.comments\n" + "FROM \n" + " ALL_MVIEWS m\n" + "LEFT JOIN \n" + " ALL_TAB_COMMENTS c \n" + "ON \n" + " m.owner = c.owner \n" + " AND m.mview_name = c.table_name\n" + " AND c.table_type = 'MATERIALIZED VIEW'\n" + "WHERE m.OWNER ='DE_SCHEMA'".replace("DE_SCHEMA", configuration.getSchema()));
tableSqls.add(new QueryAndParams("select table_name, comments, owner from all_tab_comments where owner = ? AND table_type = 'TABLE'", configuration.getSchema()));
tableSqls.add(new QueryAndParams("select table_name, comments, owner from all_tab_comments where owner = ? AND table_type = 'VIEW'", configuration.getSchema()));
tableSqls.add(new QueryAndParams("SELECT \n" +
" m.mview_name,\n" +
" c.comments\n" +
"FROM \n" +
" ALL_MVIEWS m\n" +
"LEFT JOIN \n" +
" ALL_TAB_COMMENTS c \n" +
"ON \n" +
" m.owner = c.owner \n" +
" AND m.mview_name = c.table_name\n" +
" AND c.table_type = 'MATERIALIZED VIEW'\n" +
"WHERE m.OWNER = ?", configuration.getSchema()));
break;
case db2:
configuration = JsonUtil.parseObject(datasourceRequest.getDatasource().getConfiguration(), Db2.class);
if (StringUtils.isEmpty(configuration.getSchema())) {
DEException.throwException(Translator.get("i18n_schema_is_empty"));
}
tableSqls.add("select TABNAME, REMARKS from syscat.tables WHERE TABSCHEMA ='DE_SCHEMA' AND \"TYPE\" = 'T'".replace("DE_SCHEMA", configuration.getSchema()));
tableSqls.add(new QueryAndParams("select TABNAME, REMARKS from syscat.tables WHERE TABSCHEMA = ? AND \"TYPE\" = 'T'", configuration.getSchema()));
break;
case sqlServer:
configuration = JsonUtil.parseObject(datasourceRequest.getDatasource().getConfiguration(), Sqlserver.class);
if (StringUtils.isEmpty(configuration.getSchema())) {
DEException.throwException(Translator.get("i18n_schema_is_empty"));
}
tableSqls.add("SELECT \n" + " t.name AS TableName, \n" + " ep.value AS TableDescription \n" + "FROM \n" + " sys.tables t \n" + "LEFT OUTER JOIN sys.schemas sc ON sc.schema_id =t.schema_id \n" + "LEFT OUTER JOIN \n" + " sys.extended_properties ep ON t.object_id = ep.major_id \n" + " AND ep.minor_id = 0 \n" + " AND ep.class = 1 \n" + " AND ep.name = 'MS_Description'\n" + "where sc.name ='DS_SCHEMA'".replace("DS_SCHEMA", configuration.getSchema()));
tableSqls.add("SELECT \n" + " t.name AS TableName, \n" + " ep.value AS TableDescription \n" + "FROM \n" + " sys.views t \n" + "LEFT OUTER JOIN sys.schemas sc ON sc.schema_id =t.schema_id \n" + "LEFT OUTER JOIN \n" + " sys.extended_properties ep ON t.object_id = ep.major_id \n" + " AND ep.minor_id = 0 \n" + " AND ep.class = 1 \n" + " AND ep.name = 'MS_Description'\n" + "where sc.name ='DS_SCHEMA'".replace("DS_SCHEMA", configuration.getSchema()));
tableSqls.add(new QueryAndParams("SELECT \n" +
" t.name AS TableName, \n" +
" ep.value AS TableDescription \n" +
"FROM \n" +
" sys.tables t \n" +
"LEFT OUTER JOIN sys.schemas sc ON sc.schema_id =t.schema_id \n" +
"LEFT OUTER JOIN \n" +
" sys.extended_properties ep ON t.object_id = ep.major_id \n" +
" AND ep.minor_id = 0 \n" +
" AND ep.class = 1 \n" +
" AND ep.name = 'MS_Description'\n" +
"where sc.name = ?", configuration.getSchema()));
tableSqls.add(new QueryAndParams("SELECT \n" +
" t.name AS TableName, \n" +
" ep.value AS TableDescription \n" +
"FROM \n" +
" sys.views t \n" +
"LEFT OUTER JOIN sys.schemas sc ON sc.schema_id =t.schema_id \n" +
"LEFT OUTER JOIN \n" +
" sys.extended_properties ep ON t.object_id = ep.major_id \n" +
" AND ep.minor_id = 0 \n" +
" AND ep.class = 1 \n" +
" AND ep.name = 'MS_Description'\n" +
"where sc.name = ?", configuration.getSchema()));
break;
case pg:
configuration = JsonUtil.parseObject(datasourceRequest.getDatasource().getConfiguration(), Pg.class);
if (StringUtils.isEmpty(configuration.getSchema())) {
DEException.throwException(Translator.get("i18n_schema_is_empty"));
}
tableSqls.add("SELECT \n" + " relname AS TableName, \n" + " obj_description(relfilenode::regclass, 'pg_class') AS TableDescription \n" + "FROM \n" + " pg_class \n" + "WHERE \n" + " relkind in ('r','p', 'f') \n" + " AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'SCHEMA') ".replace("SCHEMA", configuration.getSchema()));
tableSqls.add("SELECT \n" + " c.relname AS view_name,\n" + " COALESCE(d.description, 'No description provided') AS view_description\n" + "FROM \n" + " pg_class c\n" + "JOIN \n" + " pg_namespace n ON c.relnamespace = n.oid\n" + "LEFT JOIN \n" + " pg_description d ON c.oid = d.objoid\n" + "WHERE \n" + " c.relkind = 'v' \n" + " AND n.nspname = 'SCHEMA'".replace("SCHEMA", configuration.getSchema()));
tableSqls.add("SELECT \n" + " c.relname AS materialized_view_name,\n" + " COALESCE(d.description, '') AS view_description\n" + "FROM \n" + " pg_class c\n" + "JOIN \n" + " pg_namespace n ON c.relnamespace = n.oid\n" + "LEFT JOIN \n" + " pg_description d ON c.oid = d.objoid\n" + "WHERE \n" + " c.relkind = 'm' and n.nspname ='SCHEMA'; ".replace("SCHEMA", configuration.getSchema()));
tableSqls.add(new QueryAndParams("SELECT \n" +
" relname AS TableName, \n" +
" obj_description(relfilenode::regclass, 'pg_class') AS TableDescription \n" +
"FROM \n" +
" pg_class \n" +
"WHERE \n" +
" relkind in ('r','p', 'f') \n" +
" AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = ?)", configuration.getSchema()));
tableSqls.add(new QueryAndParams("SELECT \n" +
" c.relname AS view_name,\n" +
" COALESCE(d.description, 'No description provided') AS view_description\n" +
"FROM \n" +
" pg_class c\n" +
"JOIN \n" +
" pg_namespace n ON c.relnamespace = n.oid\n" +
"LEFT JOIN \n" +
" pg_description d ON c.oid = d.objoid\n" +
"WHERE \n" +
" c.relkind = 'v' \n" +
" AND n.nspname = ?", configuration.getSchema()));
tableSqls.add(new QueryAndParams("SELECT \n" +
" c.relname AS materialized_view_name,\n" +
" COALESCE(d.description, '') AS view_description\n" +
"FROM \n" +
" pg_class c\n" +
"JOIN \n" +
" pg_namespace n ON c.relnamespace = n.oid\n" +
"LEFT JOIN \n" +
" pg_description d ON c.oid = d.objoid\n" +
"WHERE \n" +
" c.relkind = 'm' and n.nspname = ?", configuration.getSchema()));
break;
case redshift:
configuration = JsonUtil.parseObject(datasourceRequest.getDatasource().getConfiguration(), CK.class);
tableSqls.add("SELECT \n" + " relname AS TableName, \n" + " obj_description(relfilenode::regclass, 'pg_class') AS TableDescription \n" + "FROM \n" + " pg_class \n" + "WHERE \n" + " relkind in ('r','p', 'f') \n" + " AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'SCHEMA') ".replace("SCHEMA", configuration.getSchema()));
tableSqls.add(new QueryAndParams("SELECT \n" +
" relname AS TableName, \n" +
" obj_description(relfilenode::regclass, 'pg_class') AS TableDescription \n" +
"FROM \n" +
" pg_class \n" +
"WHERE \n" +
" relkind in ('r','p', 'f') \n" +
" AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = ?)", configuration.getSchema()));
break;
case ck:
configuration = JsonUtil.parseObject(datasourceRequest.getDatasource().getConfiguration(), CK.class);
@@ -1500,20 +1568,40 @@ public class CalciteProvider extends Provider {
database = databasePrams[0];
}
if (datasourceRequest.getDsVersion() < 22) {
tableSqls.add("SELECT name, name FROM system.tables where database='DATABASE';".replace("DATABASE", database));
tableSqls.add(new QueryAndParams("SELECT name, name FROM system.tables where database = ?", database));
} else {
tableSqls.add("SELECT name, comment FROM system.tables where database='DATABASE';".replace("DATABASE", database));
tableSqls.add(new QueryAndParams("SELECT name, comment FROM system.tables where database = ?", database));
}
break;
default:
tableSqls.add("show tables");
tableSqls.add(new QueryAndParams("show tables"));
}
return tableSqls;
}
private PreparedStatement prepareStatement(Connection connection, QueryAndParams queryAndParams, int queryTimeout) throws SQLException {
PreparedStatement statement = connection.prepareStatement(queryAndParams.sql());
statement.setQueryTimeout(queryTimeout);
List<Object> params = queryAndParams.params();
for (int i = 0; i < params.size(); i++) {
statement.setObject(i + 1, params.get(i));
}
return statement;
}
private record QueryAndParams(String sql, List<Object> params) {
private QueryAndParams(String sql) {
this(sql, Collections.emptyList());
}
private QueryAndParams(String sql, Object... params) {
this(sql, Arrays.asList(params));
}
}
private String getSchemaSql(DatasourceDTO datasource) throws DEException {
DatasourceConfiguration.DatasourceType datasourceType = DatasourceConfiguration.DatasourceType.valueOf(datasource.getType());
switch (datasourceType) {