Skip to content

Signing and ingress hardening - #11282

Merged
thebentern merged 6 commits into
developfrom
security-block-a
Jul 29, 2026
Merged

Signing and ingress hardening#11282
thebentern merged 6 commits into
developfrom
security-block-a

Conversation

@caveman99

@caveman99 caveman99 commented Jul 29, 2026

Copy link
Copy Markdown
Member

Five follow-ups from the post-release backlog, one commit each.

  • NodeDB::updateUser and the NodeInfo downgrade drop gated on getMeshNode(), which is hot-store only, so a signer evicted to the warm tier could be identity-spoofed with an unsigned NodeInfo. Both now use isKnownXeddsaSigner(), matching the Router gate.
  • perhapsEncode ignored the return of encryptCurve25519(). On failure encrypted.bytes holds no ciphertext, so the plaintext went out labelled pki_encrypted.
  • Licensed nodes sign unicasts since Sign plaintext packets in licensed mode #10969, but the receive-side downgrade check was still broadcast-only. Widened to mirror the perhapsEncode gate.
  • UDP multicast ingress did not clamp hop_limit/hop_start to HOP_MAX the way MQTT ingress does.

Summary by CodeRabbit

  • Security Improvements

    • Improved protection against unsigned identity and node-information broadcasts from devices known to use digital signing.
    • Strengthened signature downgrade prevention across additional broadcast/authorization contexts.
    • Enforced hop-count limits for encrypted UDP packets to prevent invalid relaying.
  • Bug Fixes

    • PKI encryption failures are now detected and reported, preventing packets from continuing as if encryption succeeded.

@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

⚡ Try this PR in the Web Flasher

Flash this PR in the Web Flasher

firmware commit boards expires

Warning

This is an automated, unreviewed CI test build. Back up your device configuration
before flashing, and only flash devices you are able to recover.

Supported boards built by this PR (31)
Device Board Platform
Crowpanel Adv 3.5 TFT elecrow-adv-35-tft esp32-s3
Heltec HT62 heltec-ht62-esp32c3-sx1262 esp32-c3
Heltec Mesh Node 096 heltec-mesh-node-t096 nrf52840
Heltec Mesh Node T1 heltec-mesh-node-t1 nrf52840
Heltec Mesh Node T114 heltec-mesh-node-t114 nrf52840
Heltec V3 heltec-v3 esp32-s3
Heltec V4 heltec-v4 esp32-s3
Meshnology W10 meshnology_w10 esp32-s3
Meshnology W12 meshnology_w12 esp32-s3
Raspberry Pi Pico pico rp2040
Raspberry Pi Pico W picow rp2040
RAK WisMesh Pocket V3 rak_wismesh_pocket nrf52840
RAK WisMesh Pod rak_wismesh_pod nrf52840
RAK WisMesh Repeater Mini V2 rak_wismesh_repeater_mini nrf52840
RAK WisMesh Tag rak_wismeshtag nrf52840
RAK WisBlock 11200 rak11200 esp32
RAK WisBlock 11310 rak11310 rp2040
RAK3312 rak3312 esp32-s3
RAK WisBlock 4631 rak4631 nrf52840
Seeed SenseCAP Mesh-Tracker-X1 seeed_mesh_tracker_X1 nrf52840
Seeed Wio Tracker L1 seeed_wio_tracker_L1 nrf52840
Seeed Xiao NRF52840 Kit seeed_xiao_nrf52840_kit nrf52840
Seeed Xiao ESP32-S3 seeed-xiao-s3 esp32-s3
Station G2 station-g2 esp32-s3
Station G3 station-g3 esp32-s3
LILYGO T-Deck t-deck-tft esp32-s3
LILYGO T-Echo t-echo nrf52840
LILYGO T-Echo Plus t-echo-plus nrf52840
LILYGO T-Impulse Plus t-impulse-plus nrf52840
LilyGo T3-C6 tlora-c6 esp32-c6
Seeed SenseCAP T1000-E tracker-t1000-e nrf52840

Build artifacts expire on 2026-08-28. Updated for 62e6e3c.

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 915e1a19-d0bc-4a74-8677-b9e7f187461b

📥 Commits

Reviewing files that changed from the base of the PR and between 3f3e186 and 62e6e3c.

📒 Files selected for processing (2)
  • src/mesh/NodeDB.cpp
  • src/mesh/Router.cpp
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/mesh/NodeDB.cpp
  • src/mesh/Router.cpp

📝 Walkthrough

Walkthrough

The changes broaden known-XEdDSA-signer checks for identity and receive-policy handling, reject encrypted UDP packets with excessive hop fields, and propagate Curve25519 encryption failures as routing errors.

Changes

Packet security guards

Layer / File(s) Summary
Known XEdDSA signer policy
src/mesh/NodeDB.cpp, src/modules/NodeInfoModule.cpp, src/mesh/Router.cpp
Unsigned identity and broadcast handling now uses known signer state across storage tiers, while Balanced receive-policy rejection also covers licensed origins.
UDP hop validation
src/mesh/udp/UdpMulticastHandler.h
Encrypted UDP packets with hop_limit or hop_start above HOP_MAX are dropped before router enqueueing.
PKI encryption error handling
src/mesh/Router.cpp
Curve25519 encryption failures now log a warning and return meshtastic_Routing_Error_PKI_FAILED.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested labels: enhancement

Suggested reviewers: jp-bennett, thebentern

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description summarizes the changes, but it omits the required attestations/testing checklist from the template. Add the template's attestations section with testing and regression checkboxes, and keep the existing change summary.
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately captures the PR's main security hardening theme.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch security-block-a

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/mesh/NodeDB.cpp`:
- Around line 3507-3511: Condense the comment immediately above the node
identity check to no more than two lines while preserving that unsigned updates
cannot change known signer identities and that isKnownXeddsaSigner checks the
warm tier before rehydration. Keep the condition and surrounding behavior
unchanged.

In `@src/mesh/Router.cpp`:
- Around line 684-686: Update the rejection diagnostic associated with the
licensed-unicast condition in the Router.cpp handling around isKnownXeddsaSigner
so it reports a generic “packet” drop instead of calling every rejection a
“broadcast” drop. Keep the existing policy condition and behavior unchanged.

In `@src/mesh/udp/UdpMulticastHandler.h`:
- Around line 82-86: Update the invalid hop-count warning in UdpMulticastHandler
to format both byte-valued fields, mp.hop_limit and mp.hop_start, using the
required 0x%x format while preserving the existing drop behavior and message
context.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 1684ddc0-93e9-4591-b9a9-635bdee32f50

📥 Commits

Reviewing files that changed from the base of the PR and between 50a37b3 and 3f3e186.

📒 Files selected for processing (4)
  • src/mesh/NodeDB.cpp
  • src/mesh/Router.cpp
  • src/mesh/udp/UdpMulticastHandler.h
  • src/modules/NodeInfoModule.cpp

Comment thread src/mesh/NodeDB.cpp Outdated
Comment thread src/mesh/Router.cpp
Comment thread src/mesh/udp/UdpMulticastHandler.h
Condense the updateUser rationale to two lines and stop calling the
Balanced-mode drop a broadcast now that licensed unicasts reach it.
@thebentern
thebentern added this pull request to the merge queue Jul 29, 2026
Merged via the queue into develop with commit df6e67f Jul 29, 2026
101 checks passed
thebentern pushed a commit that referenced this pull request Jul 29, 2026
* Include warm-tier signers in the identity update gate

* Fail the send when PKI encryption fails

* Require signatures on licensed unicasts

* Include warm-tier signers in the NodeInfo downgrade drop

* Clamp hop fields on UDP multicast ingress

* Address review comments on signing hardening

Condense the updateUser rationale to two lines and stop calling the
Balanced-mode drop a broadcast now that licensed unicasts reach it.

(cherry picked from commit df6e67f)
@caveman99
caveman99 deleted the security-block-a branch July 30, 2026 06:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Pull request that fixes bugs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants