Pin PlatformIO packages and toolchains, rebase protected SDK overrides, and add WebSocket receive regression coverage. Document isolated candidate validation, archive provenance, and remaining gates.
22 KiB
Wi-Fi management-frame security update plan
Initial review date: 2026-09-16; integration status updated 2026-09-18. The original review was a focused documentation-only follow-up to dependency advisory coverage. At that initial review, no correction was implemented, exploit reproduced, build run, device accessed, or upgrade approved. The fix-bearing complete IDF 5.5.3 vendor bundle is now integrated in the validated candidate; this is not radio-hardware vulnerability closure or deployment approval. See current integration evidence and semantic rebase review.
Decision
Prefer a complete, immutable Espressif IDF 5.5 maintenance-release bundle, integrated through a compatible pinned PlatformIO package/toolchain, over transplanting Wi-Fi archives into IDF 5.5.0. IDF 5.5.3 is the verified fix-bearing reference candidate/minimum demonstrated release here, not a recommendation to deploy it in preference to all later maintenance releases. The earlier coverage records 5.5.4/5.5.5; selecting a newer deployment candidate requires the same immutable provenance and compatibility gates below, not a repeat broad advisory audit.
Do not change PMF/WPA3 policy as an automatic mitigation. Do not replace only libnet80211.a, edit only a callback declaration, relax source guards, or overwrite the installed SDK. The vendor correction is integrated in the fresh candidate build; deployed old firmware remains exposed, and target/radio validation remains pending. PMF/WPA3 has not been weakened.
Current applicability and trigger limits
Rechecked authoritative source src/wifi_manager.c:315–363:
- SoftAP uses
WIFI_AUTH_WPA2_WPA3_PSK, four clients,pmf_cfg.capable=true,required=false,WPA3_SAE_PWE_BOTH. AP/APSTA are real supported paths, including live fallback transitions (set_runtime_ap_enabled). Optional PMF is not PMF disabled. - Station uses PMF capability in both profiles; mixed has WPA2 minimum/optional PMF, WPA3 requires PMF. Do not downgrade station profiles to address a demonstrated SoftAP trigger.
- Existing generated
sdkconfig.hidentifies ESP32-S3 and enables SoftAP, WPA3 SAE, SoftAP SAE, SAE H2E and SAE-PK support. This is build metadata, not proof of a running device's current mode or negotiated association. - Architecture: the permanent Wi-Fi manager owns driver operations and bounded events; application NVS is authoritative, driver storage is RAM-only, AP policy is off/fallback/always. Working edits require explicit save. Preserve manager ownership, secret wiping and secret-free status. UART0 recovery and native USB UART1 access must remain independent of network success. Broker single-writer/multiple-isolated-observer behavior is unchanged.
The official contained fix says that when the supplicant sends an authentication response for an already-connected station, with keys installed after a successful four-way handshake, management encryption was selected from bss->pmf_enable without checking whether the frame was robust. The encryption code assumed header space that had not been allocated, causing memory corruption. The fix checks robust-management-frame status before encryption.
This supports a current-feature exposure candidate when SoftAP is active with the relevant station/key/PMF state. Radio delivery of the relevant management exchange, rather than application HTTPS/SSH authentication, is the pertinent access path (inference from the described Wi-Fi operation). The public text does not establish whether an attacker must know the PSK, personally complete association, or can spoof an existing station's exchange. It supplies no packet-level proof, CVSS, reliable arbitrary-code-execution claim, or exhaustive affected-mode matrix. Do not characterize this as proven unauthenticated remote exploitation, nor assume application login protects it. STA-only exclusion is limited to the described AP-response path, not a blanket clean bill for the opaque bundle.
The same vendor change also fixes an RSN-IE length/allocation mismatch, deauthentication-reason parsing, and default SAE PWE values. The project's short configured IE set has not been shown to trigger the allocation issue; do not conflate that uncertainty with the established old ABI/bundle identity.
Official immutable provenance
Official sources fetched in this review:
- 5.5.3 release, also release API: explicitly names the management-frame memory-corruption correction under
a3927641. - Merge commit, checked through its official commit API:
a3927641bfd0aedfaab3514cba3d7fb01378ce4d. Its title emphasizes SAE defaults; the title alone omits the security detail. - Contained fix patch:
caf4cad3b422be5c2f93afeff4cd07796a262b46, “Backport some wifi fixes,” with the trigger explanation. This is the merge's second parent, not a conflicting identification. - Annotated release tag object: tag object
b31fcc7a314a44ad992b58f589f7d1d8a4fadff6resolves to IDF commit2c211b236707889e8400c4dc5644dd5c4ee071e0. Immutable comparison reports ahead 195 / behind 0, establishing inclusion of the merge.
Exact published source/ABI delta
The fix changes four paths:
| Path relative to IDF | Published change |
|---|---|
components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h |
wpa_funcs.wpa_ap_get_wpa_ie: uint8_t *(*)(uint8_t *len) becomes uint8_t *(*)(size_t *len) |
components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c |
Matching callback implementation takes size_t *ie_len; assignment from hapd->wpa_auth->wpa_ie_len remains |
components/esp_wifi/lib |
Submodule d7373a90dc3f0be841b29911e33de5f99988dbff → a4e903fe43bf09a95022f9802db43d39740ccc0b |
components/esp_wifi/include/esp_wifi_types_generic.h |
Two SAE PWE documentation comments record default WPA3_SAE_PWE_BOTH; not structure-layout changes |
The historical shared IDF 5.5.0 header and callback take uint8_t *; esp_wpa_main.c registers the callback for SoftAP. The callback slot/pointer size need not change for this to be an ABI break: the width and interpretation of the pointed-to output change (one byte versus a size_t, four bytes on ESP32-S3). Mixed old/new caller and callee can corrupt storage or leave an incorrect length. Casting the callback does not fix the contract. Both sides, including the opaque caller, must agree.
The visible C edits are the length correction/interface marker. The management-encryption fix is in the vendor binary update, not a public C hunk that can be copied into this application.
Bundle identity: baseline, fix point, release point are different
- Historical shared installed baseline matches Wi-Fi submodule
8a1b7bbc00e895d040c5c9a6fb9d1db2bbfc7958from IDF v5.5, not the fix's immediate predecessord7373a90…. - The exact fix-point bundle is
a4e903fe43bf09a95022f9802db43d39740ccc0b. - The complete 5.5.3 release points to
e0befaa593277b4e80726079fbd521b4681754c2, verified again at the immutable release commit. Wi-Fi comparison reports ahead 3 / behind 0. Do not call the fix-point bundle the final 5.5.3 bundle.
Calculated Git blob SHA-1 (blob <length>\0 plus bytes) of all seven installed S3 archives and compared against official metadata for baseline, fix point, and release point:
| Archive | Installed = baseline Git blob | Fix-point Git blob | 5.5.3-release Git blob |
|---|---|---|---|
libcore.a |
ec2e76caad4c29ee92ec45432e0dc3bf946ea4c7 |
af63b0f8254bde084b2f474cdba1c1d63b4ae750 |
9f7b14a8bf6eec64973da8adc65d35b5ba9bee49 |
libespnow.a |
d4925dc7f73173077e8ed58abbbe5a59b5bb7be5 |
da0537c3f754a9d638fbecd4f4d806bfa66316b4 |
132b4f67e339ca2081d2add91c14eefa39476ff9 |
libmesh.a |
5cd43bf5a0a0388fb6f093a154401f00227d9570 |
6ae30c90ba59ab949e98db89b6b51daab434a5a0 |
2e9dc1c8c7afbf033337b4175032e9b1161e3262 |
libnet80211.a |
6ee20bec142638dc0a442b9642de9fa62db6ddd0 |
8ce8a2a6a9a753e31508bd609bf0a0d1d44c332f |
2800d447ec385d33869373696ba8191292647694 |
libpp.a |
c9fc98fe529c9ff2891839fdb9a41b1189c03c49 |
536fd25e30a1be76ff122d93e7481f1da22e6892 |
8944bcad7371621045f376cf74c62fde6f368cbb |
libsmartconfig.a |
31518eb9336f07de14b4a71c0389217a54ed3ec7 |
19e8274e0961fdf88351a0dec6e0d696b8ee2b94 |
4dc759e25617aa00b9e12887fd092a1d5780a170 |
libwapi.a |
0604ff76aa9134b475daf08496e03350d5ef8f09 |
e43863a22e93990b8a4deb7c4efc8e4c27566789 |
65655b6feab0572a6e8a1200946d53a21f3f4722 |
All historical shared-SDK archives matched baseline; all differ from both newer bundles. This is artifact identity, not proof that every archive is linked or contains the defect. Remote binaries were not downloaded during the initial review. Later candidate archive download/verification and complete Wi-Fi/PHY/coexistence/supplicant package comparisons are recorded in the integration/rebase reviews; the candidate uses the release-point column, not this old baseline. Git IDs are provenance identifiers, not independently measured remote SHA-256 digests or a vendor signature verification.
The release API advertises the submodule-inclusive esp-idf-v5.5.3.zip, asset ID 357881088, SHA-256 d16e6b57b1df1a523aff6a1d0ef2f99cf058cb71e73f694429769eaaea171428. This is vendor-published metadata, not a locally verified download. The release is marked immutable=false; therefore pin the resolved commit/submodules and verify artifact hashes, not merely a tag URL. Espressif warns that GitHub's automatic source archives omit submodules; those are not complete SDK inputs.
PMF/WPA3 mitigation assessment
Both the v5.5 documentation source and immutable candidate documentation, plus the installed type header, establish:
pmf_cfg.capableis deprecated, effectively true internally. Setting it false is not a supported PMF-off mitigation.required=falsepermits optional PMF; it does not disable it.esp_wifi_disable_pmf_config()is the documented optional-PMF disable API. Disabling PMF on WPA3 or WPA2/WPA3 mixed SoftAP returns an error.- WPA3 mandates PMF. WPA2-only mode by itself still does not prove PMF is disabled.
No issue-specific official workaround was found in the inspected release/fix text. The API documentation explains general configuration, not an endorsement that disabling PMF safely mitigates all defects in this change. The trigger supplies a rationale that actually eliminating bss->pmf_enable could avoid the described encryption path; the opaque implementation and lifecycle have not been proved to honor that invariant across existing associations/restarts.
Consequently, a WPA2-only plus explicit PMF-disable implementation is at most an unapproved conditional workaround candidate. It would remove SAE benefits and management-frame protection, require explicit owner acceptance, documented threat trade-offs, correct manager-owned stop/reconfigure/start sequencing, checked API results, and target evidence that negotiated PMF cannot reappear across APSTA/fallback transitions. It would not repair the RSN-IE allocation defect. Do not implement it as a silent downgrade, global WPA3 Kconfig removal, or station-profile change.
If operational containment is urgently required before an update, the owner may explicitly choose existing AP-off policy (removes the described AP response path) or Wi-Fi-off (removes radio service), accepting lost network/fallback access. These are feature-withdrawal containment options, not vendor-certified workarounds or a source fix. Preserve and verify UART0/native USB access first; do not automatically persist policy changes. No containment action was taken here.
What a coherent replacement entails
Preferred: complete vendor maintenance release
Use all IDF source, private/public headers, Wi-Fi/PHY/coexistence libraries and other submodules from one resolved release, with its toolchain and Python/build requirements. Do not install final-release blobs alongside fix-point-only C edits or mix two release revisions. Preserve the application security policies separately through audited overrides.
Current integration disposition (supplied parent evidence, 2026-09-18):
| Input | Current state | Remaining boundary |
|---|---|---|
Root platformio.ini |
Platform 6.13.0, framework 3.50503.0 / IDF 5.5.3, Xtensa and RISC-V 14.2.0+20251107 | Exact version pins, not complete immutable root dependency closure; default root build timed out during installation at 200 seconds before compilation |
Isolated app-validated |
Fresh build PASS; 95,552 B RAM / 1,749,493 B flash (+1,212 / −19,408 B versus historical 94,340 / 1,768,901 B) | Linked size is not runtime reserve |
| Protected corrections | Nine C sources plus forced header; per-entry semantic rebase, five new signed WS receive checks; 982 cases / 10 mutation checks | No original correction removed as superseded; retain exact fail-closed guards |
| Actual build/host validation | Explicit candidate SDK/core/build with interop and web performance PASS 24/24; source equality 3,237 files, identical pre/post hash recorded in validation | Not radio-hardware vulnerability closure or full target acceptance |
| Radio delivery | All packaged Wi-Fi/PHY/coexistence/supplicant files match locked framework archive; candidate callback is size_t * |
Not independent opaque-code correctness or recursive upstream submodule provenance |
| Notices | Nine entries semantically rebased, 66 unchanged, 75 total; 36 fixtures PASS; two actual bundles each 77 files / 4,433,930 bytes | Recipient/source/legal clearance pending |
The completed semantic rebase review covers candidate originals, not only Wi-Fi: HTTPS cleanup/private-key release, HTTPD scratch/null-read handling, server-local TLS policy, DHCP bounds, TLS EMS failure, X.509 allocation failure; retain/revalidate wolfSSH password/parser/ordering/ABI changes and wolfCrypt settings. Mark each correction retained, rebased, or superseded with source/test evidence. Upstream fixes do not automatically supersede local lifetime/policy additions in the same source. Also retain silent-panic/no-coredump and heap-wipe policy guards. The durable architecture's older four-correction summary is not the complete current inventory; the current generator and code map are authoritative.
Contingency: vendor-supported backport onto 5.5.0
The smallest published delta against the fix's own parent is the four-path change above. The smallest proven safe delta against this project's 5.5.0 is not established.
A candidate backport must at least pair both callback changes with one complete ESP32-S3 Wi-Fi archive set from the same vendor revision, retain the vendor patch/provenance, and establish compatibility with all private Wi-Fi headers, OS adapter tables, supplicant structures/callbacks, PHY/coexistence interfaces, configuration ABI and toolchain. All seven S3 archives form the conservative replacement set; do not mix old optional archives with new ones simply because current linking omits them. This minimum set is necessary for coherent provenance, not sufficient proof of cross-baseline compatibility.
Ask Espressif for a supported 5.5.0 backport bundle or an explicit compatibility statement with its required source/header/library/toolchain prerequisites, confirming both management-frame and IE-length corrections. The immediate-parent blob pointer differs from baseline; successful linking alone cannot establish binary layout/calling-contract compatibility. Without that evidence or a complete audited dependency closure, choose the full-release path rather than treating the two C signature edits plus blobs as approved.
Implementation plan history and remaining acceptance
Steps 1–4 below preserve the original plan: package selection, isolated preparation, override rebase and fresh candidate build/host checks now have the evidence above. Complete immutable dependency closure is not claimed. Steps 5–6 remain acceptance/release gates; historical “no code change yet” language is not a new blocker.
- Compatibility/provenance gate first, no code change yet. Resolve one deployment release and PlatformIO delivery combination. Record immutable SDK commit, recursive submodule pins, package/toolchain identities and SHA-256 manifests. Confirm vendor inclusion of the fix. Obtain missing packaging/ABI evidence; if unavailable, report the blocker instead of guessing a framework URL or transplanting archives.
- Prepare isolated inputs after approval. Do not modify the user's shared installed SDK. Obtain complete vendor inputs in a dedicated location, verify provenance/hashes, and compare only relevant integration surfaces and protected-source entries. Keep existing managed components pinned where compatible; explicitly review any resolver-required changes. Review license/notice/source-delivery updates for new radio/SDK artifacts.
- Rebase security contracts. Implement a reviewed per-entry disposition and exact new source pins, retain fail-closed guards, and verify every generated override/forced header reaches the actual targets. Add a bundle-consistency check for the selected SDK and archive identities so an old/new mixed bundle fails deterministically. Do not enable unrelated features, regenerate web assets, migrate credentials, or alter partitions.
- Build/host gates in the later implementation task only. Clean candidate build with the selected toolchain; inspect linked archive paths/map, generated configuration and actual compilation inputs. Run SDK override, crypto, parser, ordering/interop, authentication/protocol, build-policy and notice validations as applicable to the resolved input changes. Record sizes and compare resource budgets; a host pass is not radio validation. Existing historical passes do not validate this candidate.
- Target gates under explicit device authorization. Exercise WPA2 with/without negotiated PMF and WPA3 SoftAP; authenticate/reassociate after keys are installed; cover PMF optional/required behavior, four clients, disconnect/reconnect and AP/STA/APSTA/fallback transitions. Obtain vendor regression guidance or an authorized isolated-radio reproduction for the exact trigger; ordinary reconnect tests alone do not prove vulnerability closure. Stress concurrent HTTPS/WebSocket/SSH and verify bounded recovery, heap/stack reserve, queue behavior, no secret/crash-memory disclosure, and unchanged broker isolation. Verify UART0 recovery and native USB UART1 operation while Wi-Fi fails/stops/restarts. Include persisted-config reboot tests without erasure.
- Release gate. Keep PMF/WPA3 security at least unchanged. Record exact artifacts and test evidence, retain a controlled recovery image and configuration backup procedure, and mark the old image as still exposed rather than calling rollback a security fix. No flash erase, upload, pin changes or deployment until separately authorized. Update durable project memory only when implemented contracts/ownership genuinely change.
Open evidence and review boundary
- Resolved: official fix IDs/description; exact visible ABI delta; all seven installed S3 archives match baseline; distinct fix and final-release bundles; release/fix ancestry; current application configuration; PMF-disable restrictions; exact-IDF/hash guards; recommended versus installed toolchain mismatch.
- Current resolved integration: official PlatformIO 6.13.0 / IDF 5.5.3 delivery and exact toolchain selection, semantic override rebase, fresh candidate build and 24/24 host validation, whole packaged radio-component equality and notice rebase.
- Still unresolved: complete immutable ancillary/tool/Python/managed dependency closure; independent PHY/coexistence upstream submodule provenance; opaque binary implementation correctness; packet-level attacker requirements; target/runtime/resource evidence and deployment acceptance. A 5.5.0 transplant remains unproved and was not selected.
- A follow-up GitHub API request for candidate
components/esp_phy/libreturned HTTP 403 rate limit exceeded. The sequential metadata query stopped there, so PHY/coexistence pins were not established; no inference was drawn from that failure. Already completed Wi-Fi/release/ancestry queries succeeded. Official raw documentation remained available. Do not treat this partial metadata boundary as a compatibility clearance. - Historical initial-review validation only: read-only local source/package/config inspection; local seven-archive Git-blob hashing; official patch/release/tag/content/comparison/toolchain/documentation reads. No broad repeated dependency audit, binary download, PlatformIO invocation, build, test suite, device operation, configuration edit, or asset generation. Documentation links/provenance do not constitute signed-vendor attestation, exhaustive security certification, or Phase 9 sign-off.