mirror of
https://mau.dev/mautrix/go.git
synced 2026-03-14 14:25:53 +01:00
crypto: Allow decrypting message content without event id or ts
Replay attack prevention shouldn't store empty event id or ts to database if we're decrypting without them. This may happen if we are looking into a future delayed event for example as it doesn't yet have those. We still prevent doing that if we already know them meaning we have gotten the actual event through sync as that's also when a delayed event would move from scheduled to finalised and then it also contains those fields.
This commit is contained in:
parent
ab4a7852d6
commit
080ad4c0a0
3 changed files with 28 additions and 1 deletions
|
|
@ -664,6 +664,20 @@ func (store *SQLCryptoStore) IsOutboundGroupSessionShared(ctx context.Context, u
|
|||
// ValidateMessageIndex returns whether the given event information match the ones stored in the database
|
||||
// for the given sender key, session ID and index. If the index hasn't been stored, this will store it.
|
||||
func (store *SQLCryptoStore) ValidateMessageIndex(ctx context.Context, senderKey id.SenderKey, sessionID id.SessionID, eventID id.EventID, index uint, timestamp int64) (bool, error) {
|
||||
if eventID == "" && timestamp == 0 {
|
||||
var notOK bool
|
||||
const validateEmptyQuery = `
|
||||
SELECT EXISTS(SELECT 1 FROM crypto_message_index WHERE sender_key=$1 AND session_id=$2 AND "index"=$3)
|
||||
`
|
||||
err := store.DB.QueryRow(ctx, validateEmptyQuery, senderKey, sessionID, index).Scan(¬OK)
|
||||
if notOK {
|
||||
zerolog.Ctx(ctx).Debug().
|
||||
Uint("message_index", index).
|
||||
Msg("Rejecting event without event ID and timestamp due to already knowing them")
|
||||
}
|
||||
return !notOK, err
|
||||
}
|
||||
|
||||
const validateQuery = `
|
||||
INSERT INTO crypto_message_index (sender_key, session_id, "index", event_id, timestamp)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
|
|
|
|||
|
|
@ -525,6 +525,9 @@ func (gs *MemoryStore) ValidateMessageIndex(_ context.Context, senderKey id.Send
|
|||
}
|
||||
val, ok := gs.MessageIndices[key]
|
||||
if !ok {
|
||||
if eventID == "" && timestamp == 0 {
|
||||
return true, nil
|
||||
}
|
||||
gs.MessageIndices[key] = messageIndexValue{
|
||||
EventID: eventID,
|
||||
Timestamp: timestamp,
|
||||
|
|
|
|||
|
|
@ -75,8 +75,13 @@ func TestValidateMessageIndex(t *testing.T) {
|
|||
t.Run(storeName, func(t *testing.T) {
|
||||
acc := NewOlmAccount()
|
||||
|
||||
// Validating without event ID and timestamp before we have them should work
|
||||
ok, err := store.ValidateMessageIndex(context.TODO(), acc.IdentityKey(), "sess1", "", 0, 0)
|
||||
require.NoError(t, err, "Error validating message index")
|
||||
assert.True(t, ok, "First message validation should be valid")
|
||||
|
||||
// First message should validate successfully
|
||||
ok, err := store.ValidateMessageIndex(context.TODO(), acc.IdentityKey(), "sess1", "event1", 0, 1000)
|
||||
ok, err = store.ValidateMessageIndex(context.TODO(), acc.IdentityKey(), "sess1", "event1", 0, 1000)
|
||||
require.NoError(t, err, "Error validating message index")
|
||||
assert.True(t, ok, "First message validation should be valid")
|
||||
|
||||
|
|
@ -94,6 +99,11 @@ func TestValidateMessageIndex(t *testing.T) {
|
|||
ok, err = store.ValidateMessageIndex(context.TODO(), acc.IdentityKey(), "sess1", "event1", 0, 1000)
|
||||
require.NoError(t, err, "Error validating message index")
|
||||
assert.True(t, ok, "First message validation should be valid")
|
||||
|
||||
// Validating without event ID and timestamp must fail if we already know them
|
||||
ok, err = store.ValidateMessageIndex(context.TODO(), acc.IdentityKey(), "sess1", "", 0, 0)
|
||||
require.NoError(t, err, "Error validating message index")
|
||||
assert.False(t, ok, "First message validation should be invalid")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue