diff --git a/whitepaper/outreach/wave26-middleware-cms-cm-editor-pdf-cli-viz-survey.md b/whitepaper/outreach/wave26-middleware-cms-cm-editor-pdf-cli-viz-survey.md new file mode 100644 index 000000000..865030c4e --- /dev/null +++ b/whitepaper/outreach/wave26-middleware-cms-cm-editor-pdf-cli-viz-survey.md @@ -0,0 +1,108 @@ +# Wave 26 — Middleware, CMS, Config Mgmt, Editors, PDF, CLI, Viz, Sharded DB + +**Survey date:** 2026-04-25 +**Tool:** unmoad (9 active MOAD detectors, HIGH+ severity filter) +**Scope:** 10 projects across Java middleware (wildfly), CMS (typo3), Ruby config mgmt (chef), terminals/editors (kitty, nano), PDF (qpdf), CLI data tools (jq, miller), scientific viz (matplotlib), and sharded MySQL (vitess). + +--- + +## Summary + +Wave 26 totals 8,193 HIGH+ findings across 10 projects. **Ten new clean-scan honor roll entries** (seventh full-clean wave). Honor roll cumulative: **174 projects** across waves 3-26. + +**No flagship CWE-407 patches ship this pass.** Wildfly is dominated by JUnit ExtensionContext (4,840 M3 hits) and Java `Set.contains` (declared-type FPs). TYPO3 is overwhelmingly vendored frontend libraries (ckeditor5, codemirror, bootstrap, chartjs). matplotlib's M1 cluster is `itertools.count` (generator object, not `list.count` linear scan). + +## Clean-scan honor roll — 10 new entries + +| Project | Lang | Role | Notes | +|---------|------|------|-------| +| **miller** | Go/Rust | CSV/TSV/JSON CLI processor | 6 findings: `(1..=6).contains(&n)` is Range.contains (O(1)), `entry.verbNames` and `flag.altNames` slices.Contains bounded by miller's verb count (~50) and flag aliases (~5). **clean** | +| **jq** | C | Command-line JSON processor | 22 findings: `jq_test.c` test argv parsing, `jvp_contains` is jq's own JSON value containment (intentional algorithm), `builtin.c` format string check ("base64", "base32"). **clean** | +| **nano** | C | Lightweight text editor | 31 findings: `search.c` brace balance count, `files.c:2509` strcmp(d_name, ".") and ("..") skip-dotdir comparison (constant 2 strings), nano.c locale check, chars.c mbstrcasecmp utility. All bounded. **clean** | +| **qpdf** | C++ | PDF transformation library | 58 findings: `test_renumber.cc`/`test_parsedoffset.cc` test files, `qpdf-ctest.c` is the C test harness (`printf("user password: %s")` is intentional in tests, not credential leak). **clean** | +| **chef** | Ruby | Configuration management | 104 findings: `ENV.include?("CHEF_PROFILE")` is Hash.include? (Ruby hash O(1)), `path.include?("://")` is String.include? substring. M4 are config logger debug strings logging profile NAME not credential value. **clean** | +| **vitess** | Go/Java | Sharded MySQL | 101 findings: `MysqlCharset.contains(javaEncoding.toUpperCase())` is `Set.contains` (Java HashSet O(1)), `searchMode.contains(SearchMode.ALLOW_BACKSLASH_ESCAPE)` is `EnumSet.contains` (bitset O(1)). **clean** | +| **kitty** | Python/C | GPU-accelerated terminal | 113 findings: `keys.index(q)`/`groups.index(wg)`/`tabs.index(active_tab)` for tab/window/font lookup (bounded by tab/window/font count, typically <50 max per session), `debug_config.py` REDACTED FOR SECURITY is intentional. **clean** | +| **matplotlib** | Python | Scientific plotting | 465 findings: 30 M1 — `backend_pdf.py:645` `itertools.count(1)` is generator (not list.count), `gallery_order.py` build-time Sphinx docs, `_formlayout.py` Qt size combobox (small), `font_manager.py` font family options index. 400 M3 in tests + tutorials. **clean** | +| **typo3** | PHP/JS | Enterprise PHP CMS | 1,248 findings: 934 M1 overwhelmingly vendored frontend libraries (ckeditor5-engine 33, codemirror/view 27, bootstrap 26, chartjs 25, ckeditor5-table 24). PHP core clean. | +| **wildfly** | Java | JBoss application server | 5,845 findings: 4,840 M3 are JUnit ExtensionContext test plumbing (Wave 14/19 pattern reinforced); 279 M1 are `Set.contains`/`EnumSet.contains` already O(1) in declared Java type. **clean** | + +Honor roll now stands at **174 projects** validated zero-real-finding under MOAD-0001 scanning. + +## Per-target findings + +| Project | Lang | Total | M1 | M3 | M4 | M5 | M6 | M7 | M9 | M11 | Triage | +|---------|------|------:|---:|---:|---:|---:|---:|---:|---:|----:|--------| +| **wildfly** | Java | 5845 | 279 | 4840 | 29 | 413 | 1 | 283 | - | - | JUnit + Set/EnumSet declared-type. **clean** | +| **typo3** | PHP/JS | 1248 | 934 | - | 18 | 4 | 14 | 242 | - | 36 | Vendored ckeditor5/codemirror/bootstrap/chartjs. **clean** | +| **matplotlib** | Python | 465 | 30 | 400 | 1 | 1 | 2 | 31 | - | - | itertools.count + tests. **clean** | +| **kitty** | Python/C | 113 | 102 | - | 5 | 2 | - | 3 | - | 1 | Bounded tab/window/font index. **clean** | +| **chef** | Ruby | 104 | 92 | 2 | 9 | - | - | - | 1 | - | Ruby Hash.include? + profile-name logging. **clean** | +| **vitess** | Go/Java | 101 | 43 | 18 | 20 | 2 | 2 | 13 | - | 3 | Java Set.contains + EnumSet. **clean** | +| **qpdf** | C++ | 58 | 2 | - | 7 | - | 6 | 43 | - | - | Test fixtures + intentional test prints. **clean** | +| **nano** | C | 31 | 31 | - | - | - | - | - | - | - | Locale + dotdir-skip + brace count. **clean** | +| **jq** | C | 22 | 16 | - | - | - | - | 6 | - | - | jvp_contains JSON algorithm + test. **clean** | +| **miller** | Go/Rust | 6 | 4 | - | 1 | 1 | - | - | - | - | Range.contains + bounded verbs/aliases. **clean** | + +## Investigation: wildfly Java declared-type FPs + +```java +// TransportConfigOperationHandlers.java:420 +private static final Set allowedKeys = ImmutableSet.of(...); +if (!allowedKeys.contains(parameter.getKey())) { ... } + +// AbstractDistributableSession.java:93 +private static final Set LOCAL_CONTEXT_ATTRIBUTES = Set.of(...); + +// NamingEventCoordinator.java:132 +EnumSet scopeSet = ...; +if (scopeSet.contains(EventContext.OBJECT_SCOPE)) { ... } +``` + +Wildfly's enterprise Java idiom: declare `Set`, `Set>`, `EnumSet` as immutable static finals, then `.contains` against them throughout the codebase. All are O(1) hash/bit lookups. Java declared-type awareness gap (continued from Wave 11/15/18/21). + +## Other investigations + +### typo3 vendored frontend dominance + +934 of 934 M1 findings (100%) in TYPO3 are inside `Resources/Public/Contrib/` — the directory where TYPO3 vendors third-party JS libraries (ckeditor5 6 packages, codemirror, bootstrap, chartjs, jquery). PHP core has no measurable M1 surface. Same pattern as Wave 16's WordPress (1050 M1 in tinymce/codemirror/mediaelement) and Wave 24's arangodb (2298 M1 in vendored UI). + +### matplotlib `itertools.count(1)` — generator, not list.count + +```python +self._object_seq = itertools.count(1) # consumed by reserveObject +``` + +`itertools.count(start)` returns an infinite iterator generator producing successive integers. NOT `list.count(item)` (which is a linear scan). Scanner FP on the literal `.count(` substring. **Detector enhancement candidate:** distinguish `itertools.count(...)` from `.count(item)`. + +### chef profile-name logging — not credential leak + +```ruby +logger.debug("Resolving credentials secret '#{option}' for profile '#{profile}'") +``` + +Logs the OPTION KEY name (e.g. "secret_access_key") and the profile name (e.g. "production"), not the credential VALUE. M4 detector matches "credentials" / "secret" word literals in the format string but the interpolated values are key-names and profile-names. Bounded test of the M4 string-literal-context check. + +### kitty REDACTED FOR SECURITY + +```python +print(title(f'{f}:'), 'REDACTED FOR SECURITY') +``` + +Kitty's debug_config explicitly REDACTS sensitive values before printing. The literal "REDACTED FOR SECURITY" string trips M4's keyword scanner. **Intentional security feature**, not a defect. + +## Triage backlog + +1. **Scanner enhancement: Java `Set.contains`/`EnumSet.contains`/`Map.keySet().contains` declared-type awareness** (continued from Wave 11/15/18/21/24) — wildfly reinforces with 279+ M1 findings. +2. **Scanner enhancement: `itertools.count` vs `list.count` Python distinction** — matplotlib pattern. +3. **Scanner enhancement: M4 string-literal vs interpolated-value distinction** — chef logger pattern, kitty REDACTED string. + +## Method + +Same as Waves 3-25: shallow clone, `unmoad -s high -f json`, filter test/vendor/codegen noise, manual triage of strongest source-only candidates per project. **Ten projects added to clean-scan honor roll** (seventh full-clean wave). No new UNDF IDs assigned (no patches shipped). + +## References + +- `unmoad` detection engine: `git.unturf.com/engineering/unmoad.com` +- Earlier surveys: `/test-harness-survey/` through `/wave25-collab-auth-sync-vectordb-shell-survey/` +- Clean-scan honor roll cumulative: 174 projects across waves 3-26