java-topology/whitepaper/outreach/selenium.md
russell@unturf.com 9a0253e724 browser-automation: 4 CWE-407 patches (selenium x2, playwright, webdriverio)
selenium-0001: SessionCapabilitiesMutator list.contains O(NxM) -> LinkedHashSet
  O(N+M). Grid Node session mutation hot path. Bench: 192x at N=M=1000.

selenium-0002: ChromiumOptions merge helpers consolidate four list.contains
  loops behind addArgumentsUnique/addEncodedExtensionsUnique. Bench: 254x
  at N=M=1000.

playwright-0001: roleUtils validRoles / allowsNameFromContent Array.includes
  on 20-70 element constant arrays per element. Converted to Set<string>
  at module load. Bench: 11x at N=10000 elements.

webdriverio-0001: xpath-conditions extractOrConditions orMatches.find +
  values.includes per regex match -> Map<attr, Set<values>>. Bench: 6x at
  K=V=60 in the 'mobileSelectorPerformanceOptimizer'.

Each defect ships: ticket, patch with complexity-gate header, Python
benchmark + correctness test, Makefile, outreach brief. All 16 tests
pass. UNDF IDs: 1276 (playwright), 1277 (selenium-0001), 1288
(selenium-0002), 1289 (webdriverio).
2026-04-22 18:14:39 -04:00

3.5 KiB
Raw Permalink Blame History

Selenium — CWE-407 Disclosure Brief

Project: Selenium (SeleniumHQ/selenium) Disclosure date: 2026-04-22 Severity: MEDIUM-HIGH Speedup: 191.9x (selenium-0001 N=M=1000) and 253.8x (selenium-0002 N=M=1000), confirmed by benchmark Status: patch-ready, 2 patches plus test suite, benchmarks complete


Summary

Selenium carries two confirmed CWE-407 defects (MOAD-0001 — A Sedimentary Defect) in its capability merge paths. Both patterns live in mainstream code paths every production user hits. SessionCapabilitiesMutator runs on every Grid Node session creation; ChromiumOptions runs inside every Java client that targets Chrome, Edge, or Chromium-based browsers. Each merge walks client-provided args and extensions against the existing slot stereotype (or builder state) via ArrayList.contains inside a forEach loop, giving O(N×M) per merge.

At N=M=1000 args the defective path ran 24.7ms; the patched path ran 0.13ms on our bench. For a CI farm running 50 sessions/second with 3050 flags plus an extension payload, this adds measurable latency to every session handoff.

The Defects

selenium-0001 (MOAD-0001 — MEDIUM-HIGH): java/src/org/openqa/selenium/grid/node/config/SessionCapabilitiesMutator.java:136-141, 154-159, 194-199

Grid Node's session mutator merges slot stereotype caps with client-requested caps. Three forEach loops (Chromium args, Chromium extensions, Firefox args) each carry !stereotypeArguments.contains(arg) inside a forEach, producing O(N×M) per session creation.

// SessionCapabilitiesMutator.java:136-141 (mergeChromiumOptions, args path)
arguments.forEach(
    arg -> {
      if (!stereotypeArguments.contains(arg)) {   // O(M) scan per arg
        stereotypeArguments.add(arg);
      }
    });

Fix: pre-build a LinkedHashSet from the stereotype list once, iterate incoming with Set.add semantics. Cost drops to O(N+M), order preserved.

selenium-0002 (MOAD-0001 — MEDIUM): java/src/org/openqa/selenium/chromium/ChromiumOptions.java:283-303, 317-323, 345-361

ChromiumOptions.mergeInPlace and mergeInOptionsFromCaps repeat the same List.contains dedup pattern across four merge loops. Every Selenium Java client that builds Chrome, Edge, or Chromium-based capabilities hits this on every merge call.

Fix: introduce addArgumentsUnique(Collection<String>) and addEncodedExtensionsUnique(Collection<String>) helpers that build a HashSet view once per call. Four call sites consolidate behind the helpers.

Benchmark (N=M) defective fixed speedup
100 0.21ms 0.02ms 11.3x
500 5.22ms 0.12ms 42.6x
1000 24.73ms 0.13ms 191.9x

(selenium-0001 numbers shown; selenium-0002 reaches 253.8x at N=M=1000 due to the 4-pass repetition of the same merge.)

Scanner Evidence

Our open-source static scanner unmoad detects both patterns at HIGH severity via the array-includes-in-loop rule. Trigger and clean fixture pairs for both defects ship in tests/integration/fixtures/moad_0001/ and run as part of our scanner's CI.

Patches

  • selenium-0001-grid-session-mutator-list-contains.patch (UNDF-2026-000001277)
  • selenium-0002-chromiumoptions-merge-args-extensions-list-contains.patch (UNDF-2026-000001288)

Both patches preserve semantics (insertion order, dedup behavior) and compile-check against mainline. Full test + bench suite at defects/selenium/ in the java-topology research repo.