wave26 survey: 10 clean-scan additions (7th full-clean wave)

wildfly, typo3, chef, kitty, qpdf, jq, miller, matplotlib, vitess, nano
all clean. Honor roll cumulative: 174 projects.

Wildfly 4840 M3 are JUnit ExtensionContext. Wildfly 279 M1 are
Set/EnumSet declared-type FPs. TYPO3 934 M1 are 100% vendored frontend
(ckeditor5, codemirror, bootstrap, chartjs). matplotlib itertools.count
distinguished from list.count needed.

Three more scanner enhancement candidates (Java declared-type for the
fifth time, itertools.count vs list.count, M4 interpolated-value vs
string-literal).
This commit is contained in:
russell@unturf.com 2026-04-25 17:10:46 -04:00
parent cb35b92c97
commit f0f1b4be7e
No known key found for this signature in database

View file

@ -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<T>.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<String>.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<String>.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<String>.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<String> allowedKeys = ImmutableSet.of(...);
if (!allowedKeys.contains(parameter.getKey())) { ... }
// AbstractDistributableSession.java:93
private static final Set<String> LOCAL_CONTEXT_ATTRIBUTES = Set.of(...);
// NamingEventCoordinator.java:132
EnumSet<EventScope> scopeSet = ...;
if (scopeSet.contains(EventContext.OBJECT_SCOPE)) { ... }
```
Wildfly's enterprise Java idiom: declare `Set<String>`, `Set<Class<?>>`, `EnumSet<Enum>` 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 `<list>.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<T>.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