Skip to content

fix: WallFilter 全面审计修复 — 13处 bug 修复与架构改进#6623

Merged
wenshao merged 2 commits intomasterfrom
fix/wall-filter-audit-fixes
Mar 15, 2026
Merged

fix: WallFilter 全面审计修复 — 13处 bug 修复与架构改进#6623
wenshao merged 2 commits intomasterfrom
fix/wall-filter-audit-fixes

Conversation

@wenshao
Copy link
Copy Markdown
Member

@wenshao wenshao commented Mar 15, 2026

Bug 修复:

  • fix: SPI 排序后遍历错误变量导致 getOrder() 优先级失效
  • fix: statement_execute 第一重载 WallContext ThreadLocal 泄漏
  • fix: SyntaxErrorViolation 异常消息双逗号 (", , druid-version")
  • fix: setTenantColumn 在 config 为 null 时 NPE
  • fix: executeBatch 统计未过滤 JDBC SUCCESS_NO_INFO(-2)/EXECUTE_FAILED(-3) 负值
  • fix: tenantColumnsLocal ThreadLocal 从未 remove 导致线程池内存泄漏
  • fix: provider/config/inited/dbTypeName 缺少 volatile 存在多线程可见性问题
  • fix: preprocessResultSet 中冗余 null 检查
  • fix: getPhysicalColumn/getLogicColumn Map.get() 返回 null 时 auto-unbox NPE
  • fix: resultSet_findColumn 对隐藏列未抛出 SQLException
  • fix: wallUpdateCheck 中 item.value 类型强转 ClassCastException 风险

架构改进:

  • refactor: tenantColumnsLocal 从 ThreadLocal 改为 ResultSetProxy attribute, 消除多 ResultSet 串扰问题
  • refactor: init() 增加重入保护防止重复初始化丢失缓存

文档:

  • docs: 补齐 wall-security-guide.md, 新增架构原理、多租户隔离、SPI 扩展、 UPDATE 安全检查、JMX 监控、特权模式等章节

Bug 修复:
- fix: SPI 排序后遍历错误变量导致 getOrder() 优先级失效
- fix: statement_execute 第一重载 WallContext ThreadLocal 泄漏
- fix: SyntaxErrorViolation 异常消息双逗号 (", , druid-version")
- fix: setTenantColumn 在 config 为 null 时 NPE
- fix: executeBatch 统计未过滤 JDBC SUCCESS_NO_INFO(-2)/EXECUTE_FAILED(-3) 负值
- fix: tenantColumnsLocal ThreadLocal 从未 remove 导致线程池内存泄漏
- fix: provider/config/inited/dbTypeName 缺少 volatile 存在多线程可见性问题
- fix: preprocessResultSet 中冗余 null 检查
- fix: getPhysicalColumn/getLogicColumn Map.get() 返回 null 时 auto-unbox NPE
- fix: resultSet_findColumn 对隐藏列未抛出 SQLException
- fix: wallUpdateCheck 中 item.value 类型强转 ClassCastException 风险

架构改进:
- refactor: tenantColumnsLocal 从 ThreadLocal 改为 ResultSetProxy attribute,
  消除多 ResultSet 串扰问题
- refactor: init() 增加重入保护防止重复初始化丢失缓存

文档:
- docs: 补齐 wall-security-guide.md, 新增架构原理、多租户隔离、SPI 扩展、
  UPDATE 安全检查、JMX 监控、特权模式等章节

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@wenshao wenshao requested a review from Copilot March 15, 2026 02:17
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR performs a broad WallFilter audit: it fixes multiple correctness/concurrency issues (SPI ordering, ThreadLocal leaks, batch count stats, hidden-column behavior, visibility) and expands the Wall security guide with architecture, multi-tenant isolation, SPI extension, UPDATE value checks, JMX, and privileged mode.

Changes:

  • Fix SPI ordering iteration, re-entrant init() guard, ThreadLocal context cleanup, and multi-thread visibility via volatile.
  • Refactor tenant-column handling from ThreadLocal to ResultSetProxy attributes to avoid thread-pool leaks and cross-ResultSet interference.
  • Expand wall-security-guide.md with architecture diagrams, configuration matrices, multi-tenant, SPI, UPDATE checks, JMX, and privileged mode.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
doc/wall-security-guide.md Major documentation expansion covering architecture and operational usage (multi-tenant, SPI, JMX, privileged mode).
core/src/test/java/com/alibaba/druid/bvt/filter/wall/WallFilterConfigSpiForNullDbTypeTest.java Updates expectations to validate correct SPI ordering behavior.
core/src/main/java/com/alibaba/druid/wall/WallFilter.java Core fixes/refactors: init reentrance guard, SPI iteration bug fix, ThreadLocal cleanup, batch stats, hidden-column findColumn behavior, tenant attribute refactor.
core/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxyImpl.java Replaces auto-unboxing NPE with explicit handling for missing column mappings.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1619 to +1623
Integer physical = logicColumnMap.get(logicColumn);
if (physical == null) {
throw new IllegalArgumentException("Invalid column index: " + logicColumn);
}
return physical;
Comment on lines +1631 to +1635
Integer logical = physicalColumnMap.get(physicalColumn);
if (logical == null) {
throw new IllegalArgumentException("Invalid column index: " + physicalColumn);
}
return logical;
}

private static final ThreadLocal<List<Integer>> tenantColumnsLocal = new ThreadLocal<List<Integer>>();
public static final String ATTR_TENANT_COLUMNS = "wall.tenantColumns";
int physicalColumn = chain.resultSet_findColumn(resultSet, columnLabel);
List<Integer> hiddenColumns = resultSet.getHiddenColumns();
if (hiddenColumns != null && hiddenColumns.contains(physicalColumn)) {
throw new SQLException("Column '" + columnLabel + "' not found");
TenantCallBack callback = provider.getConfig().getTenantCallBack();
if (callback != null && hasNext) {
List<Integer> tenantColumns = tenantColumnsLocal.get();
List<Integer> tenantColumns = (List<Integer>) resultSet.getAttribute(ATTR_TENANT_COLUMNS);
- Add SQLState "S0022" (column not found) to hidden column SQLException
  for JDBC compatibility
- Change ATTR_TENANT_COLUMNS from public to private to avoid exposing
  internal implementation detail as API surface

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@wenshao wenshao merged commit dbbf4ae into master Mar 15, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants