Files
ESP32_Serial_Swiss_Army_Knife/docs/idf_security_review.md
T
Commander1024 51f835c22f Harden SSH parsing and add notice tooling
- Enforce exact service and channel names with bounded failure parsing
- Add hash-pinned offline notice assembly and regression coverage
- Record advisory dispositions, provenance, integration evidence, and
  remaining gates
2026-09-16 15:06:38 +02:00

43 KiB
Raw Blame History

Focused installed ESP-IDF security applicability review

Finite applicability completion — 2026-09-16

Current disposition supersedes the historical recommendations below. This slice covers exactly the six previously named mbedTLS findings and the disabled/unused-feature entries on the first page of the official IDF advisory index. It is not an exhaustive CVE inventory, security certification, upgrade approval, or Phase 9 sign-off. Only this document was edited; no source/configuration/generated-file edits, build, test compilation, or device commands were performed.

Effective source and configuration evidence

Rechecked installed ESP-IDF 5.5.0 / mbedTLS 3.6.3, not just upstream release ranges. Evidence is the existing .pio/build/esp32-s3-devkitc-1-n16r8/ configuration and compilation database, installed source under /home/mscholz/.platformio/packages/framework-espidf/, and the checked-in override renderer. This establishes configured inputs, not executable freshness or the firmware running on a device.

  • The current registry has eight C replacements plus one wolfSSH internal-header overlay. The seven-source count in the September 15 addendum is historical. Read-only python3 -B inspection called verify_version() and render_entry() only for the six IDF-owned entries, checked original hashes, and compared rendered bytes against existing generated copies: all six matched. No generator or build was run; wolfSSH bytes were outside this slice.
  • Filtered compilation entries select generated dhcpserver.c, ssl_tls.c and x509_create.c, but original ecdh.c, pk_ecc.c, pkparse.c, ecp_curves.c, asn1write.c, x509_crt.c, ssl_tls12_server.c and httpd_ws.c. None of the six newly classified findings has a project source backport. The mbedTLS entries use MBEDTLS_CONFIG_FILE="mbedtls/esp_config.h"; inspected command flags add no alternative user config. esp_config.h includes the generated sdkconfig.h and maps its ECP/NIST options to the library macros.
  • Generated header: CONFIG_MBEDTLS_ECP_C=1, CONFIG_MBEDTLS_ECP_NIST_OPTIM=1, CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=1, TLS 1.2 and client/server support enabled, TLS 1.3 absent. P-521 is enabled (maximum ECP output 66 bytes). Hardware MPI support is enabled, not a replacement for all software ECC reduction. Both mbedTLS client/server ticket options are enabled, but CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is absent. Do not describe tickets as globally compiled out.
  • Rechecked generated EMS error branch (mbedtls_ssl_tls/ssl_tls.c:70837086) returns before derivation, and generated X.509 OID allocation (mbedtls_x509_create/x509_create.c:313317) checks NULL before copying. These fixes are separate from ECDH, PK parsing, basicConstraints and ASN.1 value-state issues.

Additional installed-source SHA-256 evidence (paths below relative to components/mbedtls/mbedtls/library/; earlier original hashes remain unchanged):

Source SHA-256
ecdh.c 85439414902f8421db8921c69a0be771ed69a7c69f0722127298f41a1d330ba8
pk_ecc.c 19ba6ca1251a610a53e3654a7727ba881c358a29d46f4586ab3c7e07c846b5bf
pkparse.c 36c0590c516a1b4ad99bfefc213da1a19a2e27638ee3f267ea3365cc738ecf17
x509_crt.c 799f6993d323d9158bf832967f404e9c63b0d76c0a72023be7a80c42630020fd
ecp_curves.c 29329ed2ecad6e68f615b1b5a3e7c592a0b625c4d1a1090280e305fa9afb51d3
ssl_tls12_server.c ddf8d37e862d4176d27b928592b1971d2f397f50c4b1fac2443d099c3e9cab99

Disposition matrix

Addressed means the specified source correction exists, not target acceptance. Not-current-path means this finding's prerequisite is absent in the inspected configuration/callers, not that the library is patched. Excluded is a threat-model boundary, not technical immunity. Unresolved marks evidence/coverage still absent.

Finding Disposition Current evidence and boundary
CVE-2026-45160 DHCP; CVE-2026-50581 TLS 1.2 EMS; CVE-2026-34874 X.509 OID OOM Addressed, scoped source corrections Existing pinned generated inputs match the renderer. Earlier host/build evidence remains attributed below; not rerun. EMS correction is TLS 1.2 only.
CVE-2026-35336 ECDH small output buffer Not-current-path; primitive unpatched ecdh.c:649659 compares mpi_size(z) but writes curve-width bytes. HTTPS TLS premaster storage includes MBEDTLS_ECP_MAX_BYTES; no application direct caller supplies a small buffer. See caller qualification below.
CVE-2026-50583 zero-length ECC PK parse Not-current-path / configuration not affected Advisory explicitly excludes built-in ECC in 3.x. MBEDTLS_ECP_C is enabled; pk.h:179182 requires it to be absent for MBEDTLS_PK_USE_PSA_EC_DATA. Active ECP-backed parser rejects ilen < 1 before inspecting the point.
CVE-2026-49300 basicConstraints Not-current-path; parser unpatched Both lax parsing behaviors exist. No untrusted certificate/trust-root enrollment or HTTPS client-certificate authentication was found; local identity validation requires CA=false. No current cross-validator CA promotion path established.
CVE-2026-54435 ECC optimized reduction side channel Excluded attacker model; affected code active NIST optimization and deterministic ECDSA are enabled; P-256 identities use mbedTLS. Privileged-local precise execution traces / physical side channels are outside this network-focused review. No constant-time, hardware immunity, or key-extraction-resistance claim.
CVE-2026-50586 NewSessionTicket disclosure Not-current-path; server tickets disabled, primitive unpatched HTTPS defaults session_tickets=false, application does not override it; ESP-TLS callback registration is additionally compiled out. mbedTLS ticket machinery itself remains enabled.
CVE-2025-48965 stale ASN.1 value length Not-current-path; primitive unpatched asn1write.c:412415 still clears pointer without length. Certificate creation uses fresh subject/issuer lists, each a single fixed-format nonempty CN. Exact upstream one-line fix is now resolved below.
CVE-2026-45541 WS subprotocol Not-current-path; SDK unpatched Existing manual-admission/NULL-subprotocol disposition below remains; not reclassified as globally fixed by this slice.
Target fault behavior, local side-channel feasibility, running firmware, advisories beyond this finite set/index page Unresolved / not evaluated No runtime measurements, fault injection, exhaustive inventory or target acceptance supplied by this review. Revisit applicability whenever callers, features or trust enrollment change.

Evidence for the six named findings

CVE-2026-35336: fetched the official ECDH advisory and source fix 1d71bcc31cb8080b14b0dcbc6bc859c11d622c0f. First fixed 3.6.x release: 3.6.7. Installed vulnerable comparison matches the removed hunk. ssl_tls12_server.c:37853789 passes handshake->premaster; ssl_misc.h:990 sizes it as MBEDTLS_PREMASTER_SIZE, whose union in ssl.h:691724 includes _pms_ecdh[MBEDTLS_ECP_MAX_BYTES]. Although the TLS call's blen argument is MBEDTLS_MPI_MAX_SIZE, the actual object, not merely that argument, is sufficient for every enabled ECDH curve. The advisory explicitly says TLS ECDH is unaffected. Targeted src/ search found no direct mbedtls_ecdh_calc_secret() caller.

Also checked the installed Wi-Fi adapter rather than assuming HTTPS is the only SDK consumer: wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c:803 uses the DPP maximum 66; DPP is not enabled in the generated configuration. Its crypto_ecdh_set_peerkey() at line 1290 uses pbits / 8; the inspected OWE caller in src/rsn_supp/wpa.c restricts both offered/received group to 19 (P-256), so this does not supply the advisory's non-byte-aligned P-521/floor-size trigger. OWE support is compiled in; this is not a blanket audit of its parsing or every SDK ECDH wrapper. Future arbitrary-curve callers must allocate and pass at least (pbits + 7) / 8, or use MBEDTLS_ECP_MAX_BYTES. A pinned ecdh.c backport is defense in depth, not a demonstrated current HTTPS overflow correction.

CVE-2026-50583: fetched the official zero-length ECC public-key advisory. It affects driver-only PSA ECC in 3.5.03.6.6, not built-in ECC. Original pk_ecc.c:204220 has the unchecked *pub only under MBEDTLS_PK_USE_PSA_EC_DATA; its active #else calls mbedtls_ecp_point_read_binary(), whose ecp.c:775777 checks ilen < 1. Application PK parsing does occur, in src/web_security.c:409414 and src/ssh_security.c:156181, as well as ESP-TLS identity loading. Neither trusted storage nor a post-parse key check is being used as the exclusion: the decisive evidence is the built-in ECP path. Advisory identifies 0e2d7037db4048dbf1c194508c07384a818261d5 as the 3.6.x fix; no backport is installed or needed to close this configuration-specific finding. Reassess before moving to driver-only ECC.

CVE-2026-49300: fetched the official basicConstraints advisory. Installed x509_crt.c:494555 lacks the inner-SEQUENCE length equality check and accepts INTEGER in place of BOOLEAN. The extension caller at line 966 supplies end_ext_octet, so comparison against the exact inner sequence is still necessary. First fixed 3.6.x release: 3.6.7.

Current src/web_security.c generates its own P-256 self-signed identity, basicConstraints(false, -1), and parses persisted identity at lines 409414. Validation checks matching keys, expected subject/issuer, self-signature, and specifically rejects ca_istrue != 0 at lines 442444. src/web_server.c:673691 retains default cacert_pem=NULL; generated ESP-TLS selects MBEDTLS_SSL_VERIFY_NONE for server peer authentication (CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL absent). Application authentication is not certificate-chain enrollment. Targeted application searches found no outbound ESP-TLS/HTTP client or untrusted certificate/CSR import; Wi-Fi configuration uses personal PSK/SAE profiles, not EAP credential/CA provisioning. These are current-use observations, not global removal of X.509/client/enterprise support (those libraries/features are available). A corrupt local blob being rejected is not evidence that the library parser is fixed.

Backport provenance correction: fetched sequence fix 07f45b87681c1a0680c260089d3e6349b25fdd08. The advisory's listed “Basic fix #2,” 4fb9c9e439fd1e7e44697d23d50f00b4642fbe08, changes test encodings only. A bounded official commit-history query for library/x509_crt.c at tag mbedtls-3.6.7 located the actual INTEGER-rejection source change f67b8e5bded0c531b29480b8c5b7285366b1b153, also fetched and compared. Do not backport the advisory's two listed hashes and claim both source defects fixed. No parser backport or runtime vector validation was performed here.

CVE-2026-54435: fetched the official optimized modp side-channel advisory. First fixed 3.6.x release: 3.6.7. Installed ecp_curves.c retains specialized P-256 reduction and data-dependent carry/sign handling (NEXT, LAST, mbedtls_ecp_fix_negative, around lines 49005036); no override replaces it. Application key generation/loading and certificate signing genuinely use P-256; this is not an unused-crypto finding. Upstream requires privileged-local sufficiently precise traces (typically an untrusted OS attacking an enclave); physical side channels are also possible, not measured here. Disabling NIST optimization is an upstream workaround for NIST curves only, carries substantial performance cost, and does not cover Koblitz/Montgomery curves. No configuration change is recommended blindly on this resource-constrained target. Reopen for a local/physical attacker threat model or deliberate maintained-library update; the upstream multi-commit fix range was identified in the advisory but not patch-audited in this excluded slice.

CVE-2026-50586: fetched the official TLS 1.2 ticket disclosure advisory. First fixed 3.6.x release: 3.6.7. Original ssl_tls12_server.c:42424246 still declares uninitialized tlen/lifetime; failed ticket generation may disclose four stack bytes. esp_https_server.h:183192 defaults client CA to NULL and session_tickets=false; the application preserves both. Generated HTTPS create_secure_context() initializes tickets only under config->session_tickets; generated ESP-TLS registers callbacks only under CONFIG_ESP_TLS_SERVER_SESSION_TICKETS and non-NULL cfg->ticket_ctx. Neither prerequisite holds. This is disabled server-side TLS session tickets, not application WebSocket/admin tickets, cookies, or compiled-out mbedTLS ticket support. Reassess and backport/init both outputs before enabling the feature; advisory lists 99ccd257e2d6c5fc53bc970e3e533a90c363f8e1 and 548ed19f707565db5fb4c2487edd7ae1bea50199 (not patch-verified here).

CVE-2025-48965: re-fetched the official ASN.1 advisory. First fixed release: 3.6.4. Rechecked original stale-length branch and fixed-format CN generation (src/web_security.c:92111,128240); subject and issuer are separate fresh lists, not repeated OIDs within one list. No application direct named-data/string-name API consumer besides those fixed name setters was identified. This is not the separately addressed OID-allocation failure. A bounded official history query for library/asn1write.c at mbedtls-3.6.4 resolved and fetched fix 2df7ab7c0c3d5bb8a31481073c494521d10d4eba: exactly cur->val.len = 0; after clearing cur->val.p, plus repeated-OID tests. Its context matches installed lines 412415. The older unresolved-fix-commit statement below is now resolved; the source bug remains unpatched. If backported defensively, select actual nested target mbedcrypto, retain source pin/notices and allocation-failure preservation, and test nonempty→empty→same-length replacement and serialization.

Bounded IDF advisory-index snapshot: disabled/unused features

Fetched official IDF index, page 1 on 2026-09-16: ten entries spanning February 3September 3, 2026, newest listed A2DP/L2CAP. Fetched each of the eight remaining feature advisories below; the other two are DHCP and WS already covered above. Pages 23, broader historical/vendor advisory coverage and future publications were not reviewed. Later affected-release labels do not establish that installed 5.5.0 is fixed; dispositions here rely on feature/target/caller absence, not release-table inference.

Official advisory / CVE Required feature Snapshot disposition and local evidence
GHSA-xcpr-5mqp-9qvv, CVE-2026-81508 Bluedroid Classic A2DP sink; paired BR/EDR source Not-current-path: BT disabled; no BT host compile inputs.
GHSA-v335-fxwc-rc44, CVE-2026-81507 Bluedroid Classic L2CAP configuration Not-current-path: same disabled BT evidence; no claim that authentication would mitigate this unauthenticated path.
GHSA-3pp8-42fh-3j3c, CVE-2026-46532 Bluedroid AVRCP target, paired BR/EDR peer Not-current-path: same disabled BT evidence.
GHSA-9r76-858f-v6jh, CVE-2026-45542 NimBLE protocomm Security2 provisioning Not-current-path: BT/NimBLE absent; no application protocomm/Wi-Fi provisioning API use found. SoftAP itself is not this provisioning service.
GHSA-h7r3-gmg9-xjmg, CVE-2026-25507 BLE provisioning teardown with keep_ble_on=true Not-current-path: same disabled BLE/no provisioning service evidence, not a verified vendor UAF fix.
GHSA-v6r2-f6p2-88cj, CVE-2026-55687 Hardware JPEG decoder DQT parsing Not-current-path: ESP32-S3 configuration, no esp_driver_jpeg compilation input or application JPEG calls. No malformed-image testing.
GHSA-w82j-7q63-7pqm, CVE-2026-45329; GHSA-mmgp-73p4-92xp, CVE-2026-45328 ESP-TEE REE/TEE secure-service wrappers Not-current-path: target is Xtensa ESP32-S3, not the advisory's supported RISC-V TEE SoCs; no esp_tee compilation inputs or enabled TEE setting. This exclusion is distinct from choosing not to implement secure boot/encrypted NVS.

Local snapshot evidence: generated sdkconfig.h selects CONFIG_IDF_TARGET="esp32s3" / CONFIG_IDF_TARGET_ARCH_XTENSA=1; no enabled CONFIG_BT_ENABLED, CONFIG_BT_BLUEDROID_ENABLED, CONFIG_BT_NIMBLE_ENABLED or ESP-TEE option. Filtered existing compilation database counts for /bt/host/, /esp_tee/, /esp_driver_jpeg/: 0 each. src/ searches for provisioning/protocomm/JPEG APIs found none. This is a feature screen, not inspection or certification of the disabled vendor implementations. Re-enabling any feature invalidates its disposition.

Parent handoff and remaining limits

No new current-path actionable source correction established among these six named findings. Keep the existing DHCP/EMS/OID-allocation fixes. Optional defense-in-depth candidates are the exact ASN.1 one-line fix, ECDH curve-width bounds check and both basicConstraints source fixes; they must not be represented as already implemented. The basicConstraints test-only commit mismatch is actionable backport guidance, not evidence of a present authentication bypass. Preserve server ticket disablement and re-review before introducing certificate imports, driver-only ECC, arbitrary-curve ECDH callers or local isolation requirements.

Completed evidence work: official six-advisory fetches, focused upstream patch comparisons/history queries, original-source/config/caller inspection, read-only equality checks of six IDF generated overrides, and filtered configured-input inspection. Document-scoped git diff --check and the corrected document-presence/link-count check passed (the initial checker incorrectly expected twice the number of advisory URLs). Concurrent changes appeared in other agents' parser/override/release-notice files during the review; none were edited or reverted here, and source/configuration evidence above is the inspected snapshot, not certification of subsequent changes. No exploits, new host regression tests, build or device validation were run. The finite applicability questions above are dispositioned; full advisory coverage, runtime fault/timing behavior and whole-phase target acceptance remain unresolved. Do not summarize this as “all CVEs safe.”

Implementation addendum — 2026-09-15

Implemented, with host/build evidence; not target validation or a completed advisory review. Source checked against tools/security_overrides.py, cmake/security_overrides.cmake and the existing generated copies:

  • CVE-2026-45160: pinned DHCP backport handles PAD/END before length access, validates remaining payload length and minimum type/IP lengths, and advances by the validated length. Remaining-length comparisons deliberately avoid forming out-of-object pointers.
  • CVE-2026-50581: TLS 1.2 EMS calc_verify failure now returns ret before derivation. This is the TLS 1.2 hunk only, not the upstream TLS 1.3 correction or a global mbedTLS update.
  • CVE-2026-34874: X.509 OID allocation failure now returns MBEDTLS_ERR_X509_ALLOC_FAILED before memcpy().
  • The registry now has seven entries: the four historical entries below plus dhcpserver on lwip, mbedtls_ssl_tls on nested target mbedtls, and mbedtls_x509_create on nested target mbedx509. Nested-target selection validates the allowlist and owning SDK library directory, rejects imported/alias targets, and retains the exactly-one-source/property-preservation checks. All seven generated copies were read-only verified against rendered pinned inputs; each carries the project modification notice dated 2026-09-15, retaining upstream notices.
  • Still unpatched: CVE-2026-45541 WS negotiation and CVE-2025-48965 ASN.1 named-data state. Their baseline applicability qualifications below remain; the three backports do not fix them.

Supplied parent evidence: pio run PASS, 94,340 B linked RAM / 1,767,217 B flash (unchanged RAM, 64,092 B flash from the 9C 1,831,309 B baseline; includes the wolf crypto policy). Parent reports all four focused commands in hardening validation passed; independent reviewer reports the SDK-override and wolf-crypto-policy suites passed with no blocking implementation defects. These commands were not rerun for this documentation update. No target evidence, dependency upgrade, asset regeneration or device operation is claimed. Broader advisory review and whole-phase acceptance remain open.

Historical pre-mitigation research baseline — 2026-09-15

The remainder preserves the original investigation, hashes, applicability and proposed tests. Statements such as “not implemented,” “current,” four entries and original compilation inputs describe that earlier snapshot, not the implementation above.

Review date: 2026-09-15. Scope: the installed /home/mscholz/.platformio/packages/framework-espidf, current application source, and checked-in/generated security overrides. Review and recommendations only; no fixes implemented. No build, test compilation, upload, monitor, erase, or device operations were performed.

This is not a complete IDF/mbedTLS advisory inventory, certification, or statement that an old version is safe. Advisory release tables are not sufficient to identify downstream backports: the installed implementation and actual source registration were inspected.

Decision summary

Issue Confirmed local finding Application applicability Recommended priority
CVE-2026-45160, DHCP option parsing Original vulnerable parser compiled; no override Exposed whenever the project SoftAP/DHCP server is active; adjacent associated client, no application login required First correction: backport the release/v5.5 bounds fix
CVE-2026-45541, WS subprotocol parsing Vulnerable SDK function compiled; no override Faulty tokenization loop not reached by current application upgrades, which pass NULL; both routes are ordinary HTTP handlers Defense-in-depth backport; preserve current admission-before-101 design
CVE-2026-50581, ignored EMS error Missing early return in installed ssl_compute_master() TLS 1.2/EMS path used by HTTPS; hash/allocation failure prerequisite. Cipher restriction and disabled renegotiation do not remove this path Prompt fail-closed correction alongside DHCP/X.509 work
CVE-2025-48965, ASN.1 named-data state Zero-length replacement clears pointer but leaves stale length Current certificate names are trusted, single nonempty CNs; malicious repeated-OID/empty-value trigger not provided by current name generation Lower-priority library correction/regression coverage
CVE-2026-34874, X.509 name allocation failure (3.6.6 fix) Unchecked allocation immediately followed by memcpy() Used by local certificate creation, even with the safe fixed CN; OOM can trigger it Prompt correction; fixed input is not a mitigation

Important correction to issue classification: CVE-2025-48965 is not the X.509 allocation-failure bug. Its official advisory describes a stale val.len after a zero-length replacement. CVE-2026-34874 is the separate unchecked allocation fixed in 3.6.6. Do not merge their applicability or mark either fixed by the project's HTTPD scratch allocator changes.

Exact reviewed baseline and registration

Installed components/esp_common/include/esp_idf_version.h defines 5.5.0. components/mbedtls/mbedtls/include/mbedtls/build_info.h defines 3.6.3, 0x03060300. The following SHA-256 values were calculated from installed bytes, not inferred from version labels. Paths are relative to the installed IDF root:

Installed source SHA-256
components/esp_common/include/esp_idf_version.h 30fdfbed6cc0055a89f3454f61b56d5e5643bbc46c0774aae63e41869cf2947a
components/lwip/apps/dhcpserver/dhcpserver.c 953f46189bc64680ea5fa761e75511fadb3aebf698a0d9dff251d77166d78b80
components/esp_http_server/src/httpd_ws.c e514f603a696e3e775573bc8882a350691e31fcae96e435f9062248e7c91677c
components/mbedtls/mbedtls/library/ssl_tls.c b726c0c55bc5f32255f129d55f9f2fface85ce83de90a2d16c9017b93b738bff
components/mbedtls/mbedtls/library/asn1write.c 6667aebb1e5f0500ef4a281fe2752fc7bc59610e7bfc01d2916d224e5bc5c3e3
components/mbedtls/mbedtls/library/x509_create.c fd399239aee30384786a19b47bfe5dd22b979d5d89bb38f29f0c82a3d81daaf7

Checked-in edits are part of the effective source

Root CMakeLists.txt:1516 includes cmake/security_overrides.cmake after project(). That file invokes tools/security_overrides.py, loads its manifest, and replaces exactly one source on the resolved component target, preserving source properties and original quoted-include directory. Version/source/hash/edit ambiguity fails configuration.

The registry currently has exactly four entries:

Entry Component Protected original SHA-256
wolfssh_internal wolfssl__wolfssh 81ff1f9166708abd5c2911e9fe57c0aee01c88b5d3f68c909ee8a856d37f36a9
https_server esp_https_server 6481942b62e51125e2a43441fa0900cbda74bd2ea05c82f0c29eb4933c31946e
httpd_parse esp_http_server 6bba77064aaa68a06f8d4c01432064a1b050c91ed22741c547785b0d8a6c07d8
esp_tls_mbedtls esp-tls 09210c5a601647ca5775d127a2951bab2f3e509192b53487bbea8a93d8731b78

Read-only Python inspection called verify_version() and render_entry() in memory (not generate()), verified all four original pins, and compared rendered bytes with the existing generated files: all four matched exactly. This did not rewrite installed or generated files.

The existing .pio/build/esp32-s3-devkitc-1-n16r8/security_overrides/manifest.cmake and narrowly filtered compile_commands.json register those four generated sources, but register original dhcpserver.c, httpd_ws.c, ssl_tls.c, asn1write.c, and x509_create.c. Thus HTTPS cleanup, HTTPD scratch wiping/null handling, TLS policy, and wolfSSH fixes do not constitute fixes for these five findings.

This confirms existing configured compilation inputs, not freshness of the executable, successful rebuilding, or the firmware installed on a device.

mbedTLS registration constraint

Installed components/mbedtls/CMakeLists.txt imports upstream nested targets. The existing compile database's object paths confirm:

  • ssl_tls.c → target mbedtls (.../CMakeFiles/mbedtls.dir/ssl_tls.c.obj).
  • x509_create.c → target mbedx509.
  • asn1write.c → target mbedcrypto.

The current replacement helper resolves an IDF component's COMPONENT_LIB; it does not resolve these nested library targets. Simply adding Entry(..., "mbedtls", ...) would select the component wrapper, not the actual owning target, and should fail its exactly-one-source check. A future patch must minimally add an explicit, validated target-selection mechanism for these three nested targets while retaining current component resolution for existing entries. Do not weaken the match check or add duplicate source compilation to the wrapper.

CVE-2026-45160 — DHCP server parse_options()

Official GHSA-g764-gwc3-75m5 and fetched release/v5.5 patch.

Exact upstream fix commit: d51b1076092487e533eadf8b48c9c8579d3a6712.

Confirmed installed dhcpserver.c:902952:

  • Loop only checks optptr < end.
  • Message type reads optptr[2] without validating a length byte or payload.
  • Requested IP compares four bytes without a declared/remaining-length check.
  • Advancement reads optptr[1] without ensuring it exists.
  • PAD is not treated as a one-byte option.

The GHSA lists later affected point releases and a planned 5.5.5 fix; that is not evidence excluding 5.5.0. The old implementation is directly present here.

Reachability

src/wifi_manager.c:create_default_wifi_netifs() explicitly builds ESP_NETIF_DEFAULT_WIFI_AP() and installs default AP handlers. Installed esp_netif_defaults.h:5961 sets ESP_NETIF_DHCP_SERVER | ESP_NETIF_FLAG_AUTOUP. Existing generated configuration has CONFIG_LWIP_DHCPS=1. start_radio_and_policy() selects AP/APSTA when policy requires it; set_runtime_ap_enabled() also permits STA→APSTA activation.

This is therefore an applicable exposure when SoftAP is active, not a hypothetical unused SDK feature. A station-only moment is not a permanent mitigation if fallback or administrative policy can enable AP later. The official impact is adjacent-network denial of service, not demonstrated heap disclosure: the advisory says overread bytes are not echoed. WPA association controls reduce access but do not fix the parser. No live attack or actual device AP state was tested.

Add a pinned idf entry for components/lwip/apps/dhcpserver/dhcpserver.c, component lwip, using the exact original hash above. Backport the official patch's PAD definition and parser changes:

  1. Skip PAD; terminate at END before reading a length.
  2. Require a length byte and the entire declared payload to fit.
  3. Require message-type payload length ≥1 and requested-IP length ≥4.
  4. Advance using the already-validated opt_len; remove the obsolete end flag.
  5. Retain notices and existing post-loop state behavior.

For a strict-C bounds implementation, consider remaining-length comparisons (end - optptr >= 2, then opt_len <= remaining - 2) rather than constructing a pointer beyond the object in the upstream optptr + 2 + opt_len > end check. If chosen, document this small deviation and test equivalence; this review did not apply or test either form.

Future tests: empty options, lone option code, missing length, oversized payload, PAD sequences, END at boundary, short type/IP fields, valid DISCOVER/REQUEST/RELEASE and option combinations. Verify actual generated lwip compilation input, no duplicate original, and no changes to AP policy, broker, UART0, or USB recovery.

CVE-2026-45541 — WS subprotocol negotiation

Official GHSA-3j8v-xgrq-5vg8 and fetched release/v5.5 patch.

Exact upstream fix commit: 00a2f7fbbbd8fe6d04729022e1d5c9a49435bfe8.

Installed httpd_ws.c:7095 has strtok_r() followed by a do loop that dereferences its possibly NULL result. It also compares using sizeof(subprotocol), the pointer size rather than protocol length. A nonempty delimiter-only header can yield no tokens.

Current route registration avoids the defective loop

  • Existing configuration has CONFIG_HTTPD_WS_SUPPORT=1; disabling WS at compile time is not the reason for non-reachability.
  • src/web_server.c:518539 defines serial and admin upgrade routes with .is_websocket = false; omitted supported_subprotocol members of these static initializers are NULL. start_server() actually registers the serial handler array and optional admin route.
  • src/web_serial_transport.c:745 and src/web_admin_transport.c:570 use web_httpd_upgrade() after admission.
  • src/web_httpd_adapter.c:174 calls httpd_ws_respond_server_handshake(request, NULL).
  • Installed httpd_ws_get_response_subprotocol() returns at its supported_subprotocol == NULL check before tokenization. The optional registration adapter also rejects is_websocket or supported_subprotocol.

Conclusion: vulnerable library bytes are present, but this CVE's NULL-token dereference is not reachable through the current application upgrade paths. The official generic warning about pre-application-authentication crashes applies to automatic SDK WS negotiation with a non-NULL supported protocol; it should not be copied onto these manual-admission routes without this qualification. TLS alone is not a general mitigation.

Add a separately pinned httpd_ws.c entry for component esp_http_server; do not conflate it with the existing httpd_parse.c entry. Backport the upstream while (s != NULL) loop, exact-length match and explicit next-token step, retaining notices. Do not enable automatic upgrades or add a subprotocol to justify the patch.

Future tests: empty/delimiter-only headers, NULL supported protocol, unsupported protocol, exact match and prefix mismatch, plus current cookie/Origin/ticket admission-before-101 behavior. Mark it as a defense-in-depth fix, not closure of a demonstrated unauthenticated application crash.

Bounded mbedTLS 3.6.3 review

CVE-2026-50581 — EMS calculation failure ignored

Official advisory, published 2026-07-07. Affects through 3.6.6; first fixed 3.6.x release is 3.6.7, not 3.6.6.

Fetched basic fix: f595df4569c1a1650ad9d077e2f2e819e9f1dddb. Advisory gives test/documentation range 338572c1d805a31b875a448536bcb50d72f9bc40..27065ceb643a4266888ba1f200e4f20845e801cf; that range was not reviewed here.

Confirmed installed ssl_tls.c:70417085: session_hash[48], initial seed_len=64, and handshake->calc_verify() error only logged; execution continues. The override edits esp-tls/esp_tls_mbedtls.c, not this file. The server's two ECDHE-ECDSA AES-GCM suites use SHA-256/SHA-384 and TLS 1.2; EMS remains relevant even without renegotiation. Installed esp_config.h:10941097 enables EMS when CONFIG_MBEDTLS_TLS_ENABLED, which is 1 in the existing generated header.

A calculation/allocation failure can leave an uninitialized hash and potentially retain length 64, causing a 16-byte buffer overread. Per upstream, this does not directly disclose stack contents or the master secret; a correctly functioning peer rejects the incorrect Finished message. Higher-level master-secret uniqueness attacks require additional conditions, including both peers affected and induced failures. No direct HTTPS login bypass, practical remote fault trigger, or device exploit was established. Low historical memory minima justify fault testing, not an assertion that this failure occurred.

Minimal recommendation: pinned ssl_tls.c replacement on actual target mbedtls, inserting return ret; immediately after the existing MBEDTLS_SSL_DEBUG_RET(1, "calc_verify", ret) inside the error branch. Preserve EMS; do not disable it as a shortcut. The fetched commit also changes ssl_tls13_server.c for a separate resumption-secret error: do not claim the one-line TLS 1.2 backport implements that second fix or globally updates mbedTLS. Current HTTPS policy is TLS 1.2 only.

Future tests should inject calc_verify failure for both SHA paths, ensure PRF/key derivation and successful handshake progression do not occur, preserve success behavior, and exercise cleanup. Exact driver/backend failure inducibility on the target remains unresolved; no preprocessing/cryptographic or fault-injection test was run.

CVE-2025-48965 — ASN.1 named-data inconsistency, not OOM

Official advisory and 3.6.4 release notes. Affects through 3.6.3; fixed in 3.6.4.

Installed asn1write.c:374435 checks allocation failures when creating a node/OID/value and preserves old data until replacement allocation succeeds. However, the val_len == 0 branch frees cur->val.p and sets it NULL without resetting cur->val.len. Reusing the same OID or writing the inconsistent list can dereference NULL. Official examples include DC=foo,DC=#0000 and DC=foo,DC=#0000,DC=bar.

src/web_security.c:92111,128257 builds CN=ESP32 SAK <six hex digits> from the MAC, initializes a fresh writer, and sets subject and issuer separately. There is no repeated OID or empty value in either name. Thus the faulty primitive exists and is indirectly called, but the official hostile-name trigger is not supplied by this certificate-generation path. Do not say “not applicable because the project never creates certificates”; it does. Do not treat separate subject/issuer lists as repeated attributes in one list.

Minimal recommendation: ensure cur->val.len = 0 when clearing the value, on actual target mbedcrypto, with a pin on the installed file. Retain the existing preserve-old-on-allocation-failure logic. The official advisory/release was fetched, but an exact upstream CVE-2025-48965 fix commit was not resolved or patch-verified in this bounded review; obtain and compare the specific 3.6.4 change before implementing/pinning a claimed official backport. Test nonempty→empty→same-length replacement, list serialization after empty replacement, repeated OIDs, and allocation failures independently.

CVE-2026-34874 — x509_string_to_names() allocation failure

Official advisory and 3.6.6 release notes. Affects 3.5.03.6.5; fixed in 3.6.6.

Fetched basic fix: bfaf4a47fd33da860796feaba6235847acb71127. The advisory identifies tests/documentation through 4704b6b4bd963f1331582374e881184addf8f523; those additional changes were not reviewed here.

Installed x509_create.c:306310 allocates the known attribute's OID and calls memcpy(oid.p, ...) without checking NULL. The project's CN takes exactly this recognized-attribute branch through both name setters. Trusted names avoid the previous CVE, not this OOM defect. Application return-code checks cannot catch a fault that happens inside the setter before it returns.

Minimal recommendation: pinned x509_create.c replacement on actual target mbedx509; directly after oid.p = mbedtls_calloc(1, oid.len), add the official three-line NULL guard returning MBEDTLS_ERR_X509_ALLOC_FAILED. Preserve existing application cleanup and fail-closed identity publication. No new buffer or policy change is required.

The upstream advisory discusses arbitrary code execution on microcontrollers where address zero is writable. That impact was not demonstrated for this ESP32-S3 memory map; confirmed here is the unchecked write path and potential failure during certificate generation, not practical code execution. Test OID allocation failure at each setter, clean writer destruction, no persistence/publication of incomplete material, preservation of the old identity on failed rotation, and successful retry.

Actionable next correction and remaining evidence

  1. Implement the pinned DHCP parser backport first. It is the clearest currently reachable unauthenticated network-input defect in this scope. Do not merely change advisory wording or a version label.
  2. In the same security correction effort, support explicit nested-target overrides and backport the EMS early return and X.509 allocation guard. Verify each protected source appears exactly once on its real owner target; retain all existing four corrections and their source properties.
  3. Backport WS defensively and add registration/NULL-subprotocol regression coverage without changing application admission. Resolve the exact ASN.1 3.6.4 patch before adding that lower-priority correction.
  4. Before acceptance, run focused parser/allocation/error-propagation tests against the generated compilation inputs, then a firmware build and target checks under separately authorized implementation/validation work. None were performed for this review. Ensure failures cannot compromise UART0 recovery, native USB independence, broker ownership, or bounded transport isolation.
  5. A full IDF upgrade is an alternative maintenance strategy, but must rebase/re-audit all existing source pins, private HTTPD contracts, and TLS behavior. Updating only to mbedTLS 3.6.6 would leave CVE-2026-50581 unresolved. This document does not certify any upgrade candidate against the full advisory set.

Unresolved boundaries: exact ASN.1 fix commit; target-specific OOM/hash failure reproducibility and impact; actual running firmware/configuration; complete mbedTLS/IDF advisory coverage and downstream release integration. Existing source registration and generated-byte equality are confirmed; patch application, tests, linking, and device behavior are not.

Review mechanics: project code-map/current-state read first; targeted source, configuration and compilation-input inspection; official advisories and four exact fix patches fetched. No large release-history index was used. Some GitHub API requests timed out/returned no results and direct ReadTheDocs access via Python returned HTTP 403; official raw advisory sources and individual release pages supplied the evidence above. One read-only inspection command hit its 10-second timeout; a linear-time replacement completed the inspection. No source modifications were made, and this review owns only this document.