on master help sign in
Fix 6 validation bugs in server.knot: add hex validation for federation-sourced keys and gossip events, add length validation for message IDs, remove redundant check
commit027ee68ce75c5dbc0f7b7ee1c7f8169fe382e875 authoriko <mail@iko.soy> dateThu 26 Mar 2026, 18:29 (7 months ago) parent75f4a12
1 file changed+6−3
server.knot+6−3
server.knot+6−3
@@ -378,6 +378,7 @@ serve = \req -> case req of
378378 t <- now
379379 let dedupedIds = fold (\acc mid ->
380380 if mid == "" then acc
381+ else if tooLong mid maxPubkeyLen then acc
381382 else if count acc >= maxMessageIds then acc
382383 else if count (do a <- acc; where a == mid; yield a) > 0 then acc
383384 else union acc [mid]) [] messageIds
@@ -437,7 +438,7 @@ serve = \req -> case req of
437438 let foundServer = case session of
438439 Nothing {} -> ""
439440 Just {value: _} ->
440− if pubkey == "" || tooLong pubkey maxPubkeyLen || count valid == 0
441+ if pubkey == "" || tooLong pubkey maxPubkeyLen || not (isValidHex pubkey) || count valid == 0
441442 then ""
442443 else case single (do
443444 p <- valid
@@ -575,6 +576,7 @@ serve = \req -> case req of
575576 where validRequest
576577 where not (e.server == "")
577578 where not (e.pubkey == "")
579+ where isValidHex e.pubkey
578580 where not (tooLong e.pubkey maxPubkeyLen)
579581 where not (tooLong e.server maxPubkeyLen)
580582 where not (e.server == serverHost)
@@ -618,7 +620,7 @@ serve = \req -> case req of
618620 t <- now
619621 let authorized = verifyFederationAuth authorization
620622 let validOrigin = not (originServer == "") && not (originServer == serverHost)
621− let validFields = not (toKey == "") && not (fromKey == "") && not (encryptedBlob == "") && not (messageId == "") && not (tooLong toKey maxPubkeyLen) && not (tooLong fromKey maxPubkeyLen) && not (tooLong encryptedBlob maxBlobLen) && not (tooLong messageId maxPubkeyLen)
623+ let validFields = not (toKey == "") && not (fromKey == "") && not (encryptedBlob == "") && not (messageId == "") && isValidHex toKey && isValidHex fromKey && not (tooLong toKey maxPubkeyLen) && not (tooLong fromKey maxPubkeyLen) && not (tooLong encryptedBlob maxBlobLen) && not (tooLong messageId maxPubkeyLen)
622624 let clampedTs = if timestamp > t then t else if timestamp < t - messageMaxAge then t else timestamp
623625 pruneResult <- atomic do
624626 pr <- pruneExpired t
@@ -646,10 +648,11 @@ serve = \req -> case req of
646648 let authorized = verifyFederationAuth authorization
647649 let dedupedIds = fold (\acc mid ->
648650 if mid == "" then acc
651+ else if tooLong mid maxPubkeyLen then acc
649652 else if count acc >= maxMessageIds then acc
650653 else if count (do a <- acc; where a == mid; yield a) > 0 then acc
651654 else union acc [mid]) [] messageIds
652− let validAck = authorized && originServer == serverHost && not (fromServer == "") && not (fromServer == serverHost) && not (tooLong fromServer maxPubkeyLen) && count dedupedIds <= maxMessageIds
655+ let validAck = authorized && originServer == serverHost && not (fromServer == "") && not (fromServer == serverHost) && not (tooLong fromServer maxPubkeyLen)
653656 pruneResult <- atomic do
654657 pr <- pruneExpired t
655658 messages <- *messages