fix: WallFilter 全面审计修复 — 13处 bug 修复与架构改进#6623
Merged
Conversation
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>
There was a problem hiding this comment.
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 viavolatile. - Refactor tenant-column handling from
ThreadLocaltoResultSetProxyattributes to avoid thread-pool leaks and cross-ResultSet interference. - Expand
wall-security-guide.mdwith 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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug 修复:
架构改进:
文档: