Security Mitigations — Summary
Every vulnerability identified in the vulnerable codebase has been fixed in the secured version. This page provides a consolidated reference.
Vulnerability-to-Fix Mapping
| # | Vulnerability | CWE | OWASP | Attack Class | Fix |
|---|
| 1 | Unsafe Deserialization | CWE-502 | A08:2021 | Attacker1_Deserialization | ObjectInputFilter whitelist + SerializationValidator |
| 2 | Remote Class Injection | CWE-470 | A08:2021 | Attacker2_RemoteCodebase | useCodebaseOnly=true |
| 3 | Plaintext Transport | CWE-319 | A02:2021 | Attacker3_Eavesdrop | Mutual TLS on every RMI connection |
| 4 | Missing Authentication | CWE-306 | A07:2021 | Attacker4_UnauthorizedAccess | requireAuth(token) on every operation |
| 5 | Replay Attack | CWE-294 | A08:2021 | Attacker5_ReplayAttack | Nonce + timestamp validation per write |
Defense-in-Depth Stack
An attacker must pass all five layers. If any one fails, the request is rejected.
Side-by-Side: Vulnerable vs Secured
Vulnerability 1 — Deserialization
| Vulnerable | Secured |
|---|
| Code | super(0) — plain UnicastRemoteObject | super(0, csf, ssf) — mTLS sockets |
| Filter | No ObjectInputFilter | jdk.serialFilter + SerializationValidator |
| Result | Attacker sends EvilPayload → RCE | Attacker's bytes rejected before readObject() |
Vulnerability 2 — Remote Codebase
| Vulnerable | Secured |
|---|
| Property | useCodebaseOnly=false | useCodebaseOnly=true |
| Result | Server downloads malicious class from attacker's HTTP server | Remote codebase URLs ignored |
Vulnerability 3 — Encryption
| Vulnerable | Secured |
|---|
| Transport | Plain TCP | Mutual TLS |
| Credentials | Sent in cleartext | Encrypted |
| Client auth | None | Client must present valid certificate |
| Result | tcpdump reveals passwords | tcpdump shows only ciphertext |
Vulnerability 4 — Authentication
| Vulnerable | Secured |
|---|
| Token | Parameter present but NEVER checked | requireAuth(token) called first in every method |
| Passwords | Stored as plaintext | PBKDF2WithHmacSHA256, 260k iterations, per-user salt |
| Comparison | String.equals() (timing leak) | MessageDigest.isEqual() (constant-time) |
| Result | Any client can do anything | Invalid token → UNAUTHORIZED |
Vulnerability 5 — Replay
| Vulnerable | Secured |
|---|
| Nonce | Not present | UUID.randomUUID() per operation |
| Timestamp | Not present | System.currentTimeMillis() per operation |
| Validation | None | Nonce uniqueness + timestamp freshness (5-min window) |
| Result | Replay silently corrupts data | Replay → REPLAY_REJECTED |
Code Location Reference
| What | Secure Version | Vulnerable Version |
|---|
| Serialization filter | util/SerializationValidator.java | (not present) |
| mTLS config | util/TLSConfig.java, ReplicaNode.java:constructor | (not present) |
| Auth check | ReplicaNode.java:requireAuth() | (isValidToken exists but unused) |
| Password hashing | auth/PasswordUtils.java | (plaintext in UserStore) |
| Nonce store | util/NonceStore.java | (not present) |
| useCodebaseOnly | ReplicaNode.java:main() | ReplicaNode.java:main() (set to false) |
Academic References
Each fix maps to established security standards:
- ObjectInputFilter: Oracle JDK documentation — "Java Serialization Filtering"
- useCodebaseOnly: Oracle RMI documentation — "RMI over SSL"
- Mutual TLS: IETF RFC 8446 — "TLS 1.3"
- PBKDF2: IETF RFC 8018 — "PKCS #5: Password-Based Cryptography"
- Nonce + Timestamp: OWASP — "Replay Attack Prevention Cheat Sheet"
Next: → Setup & Build