keepassxc/tests/TestKdbx4.h
Jonathan White 72fc00695c Prevent byte-by-byte and attachment inference side channel attacks
Attack - KeeShare attachments can be inferred because of attachment de-duplication.

Solution - Prevent de-duplication of normal database entry attachments with those entry attachments synchronized/associated with a KeeShare database. This is done using the KeeShare database UUID injected into the hash calculation of the attachment prior to de-dupe. The attachments themselves are not modified in any way.

--------

Attack - Side channel byte-by-byte inference due to compression de-duplication of data between a KeeShare database and it's parent.

Solution - Generate a random array between 64 and 512 bytes, convert to hex, and store in the database custom data.

--------

Attack vector assumptions:
1. Compression is enabled
2. The attacker has access to a KeeShare database actively syncing with the victim's database
3. The victim's database is unlocked and syncing
4. The attacker can see the exact size of the victim's database after saving, and syncing, the KeeShare database

Thank you to Andrés Fábrega from Cornell University for theorizing and informing us of this attack vector.
2024-03-09 12:39:00 -05:00

72 lines
2.1 KiB
C++

/*
* Copyright (C) 2018 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEEPASSXC_TEST_KDBX4_H
#define KEEPASSXC_TEST_KDBX4_H
#include "TestKeePass2Format.h"
class TestKdbx4Argon2 : public TestKeePass2Format
{
Q_OBJECT
protected:
void initTestCaseImpl() override;
QSharedPointer<Database> readXml(QBuffer* buf, bool strictMode, bool& hasError, QString& errorString) override;
QSharedPointer<Database>
readXml(const QString& path, bool strictMode, bool& hasError, QString& errorString) override;
void writeXml(QBuffer* buf, Database* db, bool& hasError, QString& errorString) override;
void readKdbx(QIODevice* device,
QSharedPointer<const CompositeKey> key,
QSharedPointer<Database> db,
bool& hasError,
QString& errorString) override;
void writeKdbx(QIODevice* device, Database* db, bool& hasError, QString& errorString) override;
};
class TestKdbx4AesKdf : public TestKdbx4Argon2
{
Q_OBJECT
protected:
void initTestCaseImpl() override;
};
/**
* KDF-independent KDBX4 format tests.
*/
class TestKdbx4Format : public QObject
{
Q_OBJECT
private slots:
void init();
void cleanup();
void testFormat400();
void testFormat400Upgrade();
void testFormat400Upgrade_data();
void testFormat410Upgrade();
void testUpgradeMasterKeyIntegrity();
void testUpgradeMasterKeyIntegrity_data();
void testAttachmentIndexStability();
void testCustomData();
};
#endif // KEEPASSXC_TEST_KDBX4_H