Skip to content

fix(core): compare RPC bearer tokens in constant time#2572

Merged
senamakel merged 2 commits into
tinyhumansai:mainfrom
NgoQuocViet2001:fix/constant-time-rpc-bearer
May 25, 2026
Merged

fix(core): compare RPC bearer tokens in constant time#2572
senamakel merged 2 commits into
tinyhumansai:mainfrom
NgoQuocViet2001:fix/constant-time-rpc-bearer

Conversation

@NgoQuocViet2001
Copy link
Copy Markdown
Contributor

@NgoQuocViet2001 NgoQuocViet2001 commented May 24, 2026

Summary

  • Replaces the core RPC bearer equality check with a constant-time helper shared by header/query-token auth paths.
  • Keeps empty supplied tokens rejected before comparison.
  • Adds a regression test for prefix matches so partial tokens do not authenticate.

Problem

bearer_matches was still using direct equality, which can short-circuit on mismatch. The RPC bearer is checked for HTTP, SSE/query-token, Socket.IO, and future transports through this helper, so the comparison boundary should not leak partial-match timing.

Solution

The helper now compares byte slices in constant time by walking the longer input and folding byte and length differences into the final result. The change is scoped to src/core/auth.rs.

Submission Checklist

  • Tests added or updated (happy path + failure / edge case)
  • N/A: Diff coverage gate runs in CI; changed lines are covered by core::auth focused unit tests.
  • N/A: Coverage matrix updated — behaviour-only auth hardening.
  • N/A: No feature matrix rows touched.
  • No new external network dependencies introduced.
  • N/A: Manual smoke checklist unchanged — no user-facing flow change.
  • Linked issue closed via Closes #NNN in the ## Related section

Impact

Security hardening only. Valid bearer tokens continue to authenticate and invalid/empty/prefix tokens remain rejected; no migration or config changes.

Related


AI Authored PR Metadata (required for Codex/Linear PRs)

Linear Issue

  • Key: N/A
  • URL: N/A

Commit & Branch

  • Branch: fix/constant-time-rpc-bearer
  • Commit SHA: e7d2643e773a753eaa218dc4de4d2c8b937da295

Validation Run

  • cargo fmt --check
  • git diff --check
  • Focused tests: docker run ... CARGO_TARGET_DIR=/target cargo test --lib core::auth (16 passed)
  • Rust fmt/check: cargo fmt --check
  • Tauri fmt/check: N/A — no Tauri shell changes

Validation Blocked

  • command: N/A
  • error: N/A
  • impact: N/A

Behavior Changes

  • Intended behavior change: bearer token comparison no longer exits on the first mismatched byte.
  • User-visible effect: none.

Parity Contract

  • Legacy behavior preserved: exact tokens authenticate; empty, wrong, and prefix tokens are rejected.
  • Guard/fallback/dispatch parity checks: header and query-token paths still call the same bearer_matches helper.

Duplicate / Superseded PR Handling

Summary by CodeRabbit

  • Bug Fixes

    • Strengthened bearer token verification with constant-time equality comparison
    • Enhanced token validation to properly reject token prefix matches
  • Tests

    • Extended token validation test coverage with additional edge cases

Review Change Stack

@NgoQuocViet2001 NgoQuocViet2001 requested a review from a team May 24, 2026 17:12
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 24, 2026

📝 Walkthrough

Walkthrough

The pull request hardens bearer-token verification in src/core/auth.rs by replacing direct string equality with constant-time byte comparison. The bearer_matches helper now rejects empty tokens and uses constant_time_eq to prevent timing-based token leakage across all authorization paths.

Changes

Bearer Token Timing-Attack Hardening

Layer / File(s) Summary
Constant-time bearer token comparison
src/core/auth.rs
bearer_matches is reimplemented to reject empty supplied tokens and compare against the expected token using constant-time byte-wise equality, replacing direct string equality. Documentation is updated to reflect constant-time semantics. A new unit test verifies that prefix matches are correctly rejected.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

working

Poem

🐰 A rabbit hops through code so tight,
Where tokens dance in constant light,
No timing leaks shall steal the day,
When bytes are matched the constant way,
Security hops, then bounds away!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: switching RPC bearer token comparison to constant-time, which directly addresses the security hardening objective outlined in the PR and linked issue.
Linked Issues check ✅ Passed The PR successfully implements constant-time bearer token comparison as specified in issue #2569's objective #3, replacing the vulnerable equality check with a constant-time helper.
Out of Scope Changes check ✅ Passed All changes are scoped to src/core/auth.rs and focused on the constant-time bearer token comparison objective; no unrelated modifications are present.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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 and usage tips.

@coderabbitai coderabbitai Bot added the working A PR that is being worked on by the team. label May 24, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/core/auth.rs (1)

238-260: ⚡ Quick win

Reuse the existing constant-time comparator instead of carrying a second copy.

src/openhuman/security/pairing.rs:255-276 already implements the same max-length constant-time compare contract. Keeping two copies of a security-sensitive primitive makes future fixes easy to land in one path and miss in the other. Please route bearer_matches through the shared helper or extract one common utility for both call sites.

🤖 Prompt for 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.

In `@src/core/auth.rs` around lines 238 - 260, The bearer_matches implementation
duplicates a constant-time comparator; replace its internal constant_time_eq
with the single shared comparator used in the pairing/security module (i.e.,
call the existing constant-time compare function from that module instead of
defining a new constant_time_eq), or extract a common utility function and have
both bearer_matches and the pairing code call that shared helper; ensure you
preserve the non-empty check in bearer_matches and import or expose the shared
comparator symbol so no duplicate logic remains.
🤖 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.

Nitpick comments:
In `@src/core/auth.rs`:
- Around line 238-260: The bearer_matches implementation duplicates a
constant-time comparator; replace its internal constant_time_eq with the single
shared comparator used in the pairing/security module (i.e., call the existing
constant-time compare function from that module instead of defining a new
constant_time_eq), or extract a common utility function and have both
bearer_matches and the pairing code call that shared helper; ensure you preserve
the non-empty check in bearer_matches and import or expose the shared comparator
symbol so no duplicate logic remains.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c22f782a-efb5-4400-bbd5-eacf22aa6cc7

📥 Commits

Reviewing files that changed from the base of the PR and between d52abe5 and e7d2643.

📒 Files selected for processing (1)
  • src/core/auth.rs

@senamakel senamakel merged commit c88fea1 into tinyhumansai:main May 25, 2026
30 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

working A PR that is being worked on by the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants