fix(signal): improved security and robustness - batch 2

Medium Priority Fixes based on Copilot code review:

1. Use full SHA-256 fingerprint (64 characters)
   - Previously truncated to 32 characters (128 bits)
   - Now uses full 256-bit hash for cryptographic consistency
   - Aligns with standard security practices

2. Add bounds checking in protobuf parsing
   - Added bounds check after offset += length for length-delimited fields
   - Added bounds check for 64-bit and 32-bit fixed fields
   - Prevents reading beyond buffer bounds with malformed messages
   - Defense in depth against malformed/malicious PreKeyWhisperMessages

https://claude.ai/code/session_01SWAcNuGZQmEKyBPYkBhVHg
This commit is contained in:
Claude
2026-01-30 12:33:33 +00:00
parent 3dcdc7be69
commit 81cf601250
+10 -2
View File
@@ -78,12 +78,13 @@ export interface LibSignalRepositoryOptions {
/** /**
* Generate a SHA-256 fingerprint of an identity key * Generate a SHA-256 fingerprint of an identity key
* This is used to display to users for verification * This is used to display to users for verification
* Returns full 64-character hex string (256 bits) for cryptographic consistency
* *
* @param key - The identity key bytes * @param key - The identity key bytes
* @returns Hex string fingerprint * @returns Full SHA-256 hex string fingerprint (64 characters)
*/ */
function generateKeyFingerprint(key: Uint8Array): string { function generateKeyFingerprint(key: Uint8Array): string {
return createHash('sha256').update(key).digest('hex').substring(0, 32) return createHash('sha256').update(key).digest('hex')
} }
/** /**
@@ -175,6 +176,11 @@ function extractIdentityFromPkmsg(ciphertext: Uint8Array, logger?: ILogger): Uin
} }
offset += length offset += length
// Bounds check after skipping field
if (offset > ciphertext.length) {
logger?.debug({ offset, length: ciphertext.length }, 'Offset exceeds ciphertext bounds after length-delimited field')
break
}
} else if (wireType === 0) { } else if (wireType === 0) {
// Varint // Varint
const varintResult = readVarint(ciphertext, offset) const varintResult = readVarint(ciphertext, offset)
@@ -183,9 +189,11 @@ function extractIdentityFromPkmsg(ciphertext: Uint8Array, logger?: ILogger): Uin
} else if (wireType === 1) { } else if (wireType === 1) {
// 64-bit fixed // 64-bit fixed
offset += 8 offset += 8
if (offset > ciphertext.length) break
} else if (wireType === 5) { } else if (wireType === 5) {
// 32-bit fixed // 32-bit fixed
offset += 4 offset += 4
if (offset > ciphertext.length) break
} else { } else {
// Unknown wire type, cannot continue // Unknown wire type, cannot continue
logger?.debug({ wireType }, 'Unknown wire type in protobuf') logger?.debug({ wireType }, 'Unknown wire type in protobuf')