Skip to content

security: Persistent Replay Protection & HMAC Hardening#2274

Merged
Scottcjn merged 1 commit intoScottcjn:mainfrom
MichaelSovereign:security/replay-hardening-v2
Apr 17, 2026
Merged

security: Persistent Replay Protection & HMAC Hardening#2274
Scottcjn merged 1 commit intoScottcjn:mainfrom
MichaelSovereign:security/replay-hardening-v2

Conversation

@MichaelSovereign
Copy link
Copy Markdown
Contributor

Implements persistent seen_messages tracking in SQLite to prevent restart-replay attacks (Fixes #2271). Also hardens HMAC signature to include msg_id and ttl fields, preventing metadata tampering (Fixes #2272). Wallet: ad7p5x9PBydhyTw8Ddquaw5j4JKgsQoaxGCvMt2cNak

@github-actions github-actions Bot added BCOS-L1 Beacon Certified Open Source tier BCOS-L1 (required for non-doc PRs) node Node server related size/M PR: 51-200 lines labels Apr 16, 2026
Copy link
Copy Markdown

@fengqiankun6-sudo fengqiankun6-sudo left a comment

Choose a reason for hiding this comment

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

Code Review: PR #2274 — Persistent Replay Protection & HMAC Hardening

Reviewer: fengqiankun6-sudo
Bounty: #2782 (PR Review, 2 RTC)

Summary

This PR addresses two security issues in the P2P gossip layer:

  1. Issue #2271: In-memory deduplication → persistent DB-backed deduplication
  2. Issue #2272: HMAC signature binding extended to include msg_id and ttl

Assessment

Security (Issue #2272): The HMAC hardening is correct. Adding msg_id to the signed content binds the signature to a specific message ID. Adding ttl prevents TTL manipulation. The sort_keys=True ensures deterministic payload serialization.

Note: The msg_id is derived from a hash including time.time(), which is non-deterministic. Acceptable for P2P gossip use cases.

Deduplication (Issue #2271): DB-backed dedup with TTL is a solid improvement over in-memory sets. The INSERT OR IGNORE pattern handles race conditions correctly. The 1-hour pruning window is reasonable.

Graceful Degradation: The fallback to in-memory dedup on DB errors ensures the system remains operational even if SQLite fails.

Minor suggestion: time.time() in msg_id generation could theoretically collide for messages created in the same millisecond. A counter/nonce would be more robust, but acceptable for low-rate gossip.

Verdict: Approve

This is a meaningful security improvement. The PR is well-scoped and ready to merge.


Wallet: fengqiankun

@MichaelSovereign
Copy link
Copy Markdown
Contributor Author

Status Check: All CI tests have passed and the code has been verified for security integrity. Ready for final re-review and merge.

@MichaelSovereign
Copy link
Copy Markdown
Contributor Author

Thanks for the review @fengqiankun6-sudo. Re: msg_id collision, agreed. I will extend the msg_id generation in the next SDK update to include a high-resolution monotonic counter alongside the timestamp for absolute uniqueness.

@Scottcjn
Copy link
Copy Markdown
Owner

Merging — directly addresses the two novel security issues we filed (#2271 restart-replay and #2272 msg_id/ttl signing).

What's good:

Two follow-up notes (non-blocking):

  1. Rollout coordination: this changes _signed_content() on the wire. Old-version nodes will reject new-version messages and vice versa. Our 5 nodes are all on Phase 2 right now per the deploy notes — they'll need to upgrade in the same window. I'll handle the coordinated deploy.
  2. Prune frequency: DELETE FROM p2p_seen_messages WHERE ts < ? runs on every accepted message. At current volume it's fine, but worth moving to a periodic prune (every Nth message or a background task) before p2p traffic grows. Filed as follow-up, not blocking this merge.

Wallet note for @MichaelSovereign: the address ad7p5x9PBydhyTw8Ddquaw5j4JKgsQoaxGCvMt2cNak in the PR body is a Solana-format address, not an RTC wallet. For this payout I'm crediting the MichaelSovereign GitHub-handle wallet, which you can claim/rotate later. If you want an explicit RTC wallet (RTC + 40-char hex format), open an issue and I'll retarget.

Paying 75 RTC for closing two filed security issues in a single focused PR. Thank you.

@Scottcjn Scottcjn merged commit 62b410f into Scottcjn:main Apr 17, 2026
3 checks passed
atguuuia added a commit to atguuuia/Rustchain that referenced this pull request Apr 19, 2026
Fixes Scottcjn#2288
_handle_get_state was calling _signed_content with 3 args instead of 5 after PR Scottcjn#2274 extended the signature to include msg_id and ttl.

Changes:
- Generate msg_id for state response
- Set ttl=0 for state responses
- Update call to match _signed_content signature
wuxiaobinsh-gif added a commit to wuxiaobinsh-gif/Rustchain that referenced this pull request Apr 20, 2026
Fixes TypeError when STATE requested by providing msg_id and ttl arguments to _signed_content(). The function signature requires 5 args since PR Scottcjn#2274 but _handle_get_state was calling with 3.

Changes:
- Generate msg_id via sha256 hash for state response
- Pass ttl=0 for state responses
- Include msg_id and ttl in response dict for requester verification

Fixes Scottcjn#2288
@Scottcjn
Copy link
Copy Markdown
Owner

Housekeeping: stranded 15 RTC swept to your self-custody wallet

When your earlier payouts were running, I paid 15 RTC (pending_id 1244) to the Solana-format label RTCad7p5x9PBydhyTw8Ddquaw5j4JKgsQoaxGCvMt2cNak you'd originally posted. That was confirmed, not voided, at the time the #2296 payment got redirected to your new Ed25519 wallet.

An audit just surfaced that the 15 RTC would sit there permanently unreachable — the label is 46 chars (Solana-format), and signed transfers only accept proper 43-char RTC addresses, so you couldn't spend it without an admin sweep.

Sweep just executed:

  • Amount: 15 RTC
  • From: RTCad7p5x9PBydhyTw8Ddquaw5j4JKgsQoaxGCvMt2cNak (label)
  • To: RTC7b43cfb6acd1182809d9427e46bc080ca47a3f2e (your self-custody)
  • tx_hash: 36a53d7e58da9625b0279981ba4f7926
  • pending_id: 1258
  • Confirms: 24h window

Totals now consolidated on your proper wallet: 70 (#2296) + 25 (#2573) + 15 (sweep) = 110 RTC at RTC7b43cfb6….

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

BCOS-L1 Beacon Certified Open Source tier BCOS-L1 (required for non-doc PRs) node Node server related size/M PR: 51-200 lines

Projects

None yet

3 participants