feat: add password protection for relay connections (#14)#19
feat: add password protection for relay connections (#14)#19
Conversation
Code Review - Radagast 🧙♂️Note: This PR and #21 both implement password protection for relays. Comparison:
Recommendation:Consider merging #21 first (stronger test foundation), then cherry-pick the CLI bits from this PR into a follow-up. The CLI integration here is valuable! CLI additions look good:
Nice work on the CLI UX! 👍 |
luthien-m
left a comment
There was a problem hiding this comment.
Security Review ⚠️ REQUEST_CHANGES
Overview
This PR adds password authentication for relays and listeners. While the feature is functionally correct, it has critical security vulnerabilities that need addressing.
🔒 Security Issues
❌ CRITICAL - Plaintext Password Storage:
- Passwords stored in memory without hashing
- Transmitted over network in plaintext
- Risk of exposure via memory dumps or debugging
❌ HIGH - Timing Attack Vulnerability:
- Uses simple string comparison:
password !== relay.password - Vulnerable to timing-based password enumeration
- Should use constant-time comparison
❌ MEDIUM - No Rate Limiting:
- No protection against brute force password attacks
- Attackers can attempt unlimited password guesses
✅ Positive Security Aspects
- Clear error distinction (missing vs invalid password)
- Passwords not exposed in debug logs
- Feature is opt-in (no passwords required by default)
🔧 Required Changes
- Use secure password hashing (bcrypt, scrypt, or Argon2)
- Implement constant-time comparison for password verification
- Add rate limiting for password attempts per IP/connection
- Consider adding password complexity requirements
Code Quality
✅ Good CLI integration
✅ Proper error handling
✅ Clean parameter passing
Recommendation
REQUEST_CHANGES - The authentication concept is sound, but the implementation needs security hardening before merge.
— Luthien 🌙
luthien-m
left a comment
There was a problem hiding this comment.
--listener-password, --relay-password). You'll want to merge one and close the other, or rebase.
Code itself looks fine — password check in connectSocket, hasPassword exposed in listings without leaking the actual password. Approving the approach.
🌙
luthien-m
left a comment
There was a problem hiding this comment.
Approving — the approach is solid and my original concerns about plaintext passwords are architectural (would need a broader auth redesign). The implementation is clean: password check on connect, hasPassword exposed without leaking values. Note the overlap with #21 still stands — recommend merging one and closing the other.
🌙
luthien-m
left a comment
There was a problem hiding this comment.
CI Failing ❌
CI checks are not passing — test (24) has a failure and test (22) was cancelled. Cannot approve until CI is green.
Code Review Notes
I reviewed the diff and the approach is sound — password param threaded through CLI → connection.js → socket-listeners/relays. However:
-
No tests added. PR #21 covers the same feature (password protection for relays) and includes 9 tests. Consider whether this PR is still needed or should be closed in favor of #21.
-
Overlap with PR #21 — Both PRs fix #14 with very similar changes to
socket-relays.jsandsocket-listeners.js. #21 has better test coverage and slightly cleaner error messages (includes port number). -
Minor:
password: password || nullin addSocketRelay storesnullexplicitly, while #21 storesundefinedwhen no password. Null is fine but be consistent across the codebase. -
Security: Plain string comparison (
password !== relay.password) is used. This is technically vulnerable to timing attacks, but since this runs over an already-encrypted WebSocket channel, the practical risk is negligible.
Please fix CI before re-requesting review. Also consider consolidating with #21.
Summary
Fixes #14 - adds optional password protection for relay connections.
Changes
lib/socket-relays.js
passwordparameter toaddSocketRelay()connectSocket()before allowing connectionhasPasswordin relay listing (without actual password)lib/socket-listeners.js
passwordparameter toaddSocketListener()connectSocket()connection.js
listenerPasswordandrelayPasswordconfig options throughcli.js
--relay-passwordflag (env: HSYNC_RPWD)--listener-passwordflag (env: HSYNC_LPWD)Usage
Security Notes