2.5 KiB
ClickHouse — CWE-407 Disclosure Brief
2026-03-27 · Patch available — awaiting upstream merge
Finding
One O(n²) defect in ClickHouse's query analyzer column transformer. findReplacementExpression() uses std::find on replacements_names for every column-transformer application during query analysis, causing O(C×T×R) overhead per query. Patch ready for upstream review.
The Defects
clickhouse-0001 (PATCHED — HIGH): src/Analyzer/ColumnTransformers.h
// Inside findReplacementExpression() — per column per transformer per query:
auto it = std::find(replacements_names.begin(),
replacements_names.end(),
column_name);
// O(C×T×R) — columns × transformers × replacement entries
std::find on replacements_names vector for every column in every transformer in every query. For C columns, T transformers, R replacement entries: O(C × T × R). Measured ratio: 200×.
Complexity Proof
For C=10 columns, T=10 transformers, R=200 replacements:
- O(C×T×R) = 20,000 comparisons per query analysis
- Fixed:
unordered_map<column_name, replacement_expr>→ O(C×T) - 200× measured ratio.
Impact
All ClickHouse deployments using column transformers in queries — EXCEPT, REPLACE, and APPLY column transformers in SELECT * queries. These are widely used in ClickHouse for schema evolution and query convenience. ClickHouse is a high-performance analytical database used for real-time analytics at scale. OLAP queries on wide tables (many columns) with multiple transformers maximize C×T×R.
The Fix
Replace replacements_names vector scan with unordered_map:
// Before
auto it = std::find(replacements_names.begin(), replacements_names.end(), column_name);
// After
// CWE-407 fix: unordered_map index for O(1) replacement lookup instead of O(R) std::find.
auto it = replacements_index.find(column_name);
if (it != replacements_index.end()) {
return it->second; // direct expression lookup
}
Patch
defects/clickhouse/patch/clickhouse-0001-column-transformer-map.patch
What We Ask
- Confirm receipt and assign a GitHub Security Advisory or issue reference.
- Validate the patch against your query analyzer and column transformer test suite.
- Assess CVE eligibility — fires on every query with column transformers on wide tables.
- Coordinate a disclosure date — we are targeting 90 days from first contact.
Contact: see cover email. This brief is confidential until coordinated disclosure.