From b98726242549730e73c0198ade3b3c4f5b68e111 Mon Sep 17 00:00:00 2001 From: Lukas Holecek Date: Mon, 9 Oct 2023 14:10:26 +0200 Subject: [PATCH] Ignore clipboard data from password managers by default Fixes #2282, #2495 --- src/platform/dummy/dummyclipboard.cpp | 27 +++++++++++++++++++++-- src/platform/x11/x11platformclipboard.cpp | 7 +++++- src/tests/tests.cpp | 24 ++++++++++++++++++++ src/tests/tests.h | 2 ++ 4 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/platform/dummy/dummyclipboard.cpp b/src/platform/dummy/dummyclipboard.cpp index 34348e1614..761eff2ce3 100644 --- a/src/platform/dummy/dummyclipboard.cpp +++ b/src/platform/dummy/dummyclipboard.cpp @@ -6,6 +6,7 @@ #include "common/log.h" #include +#include #include QClipboard::Mode modeToQClipboardMode(ClipboardMode mode) @@ -57,8 +58,30 @@ const QMimeData *DummyClipboard::mimeData(ClipboardMode mode) const void DummyClipboard::onChanged(int mode) { - if (mode == QClipboard::Clipboard) - emit changed(ClipboardMode::Clipboard); + if (mode != QClipboard::Clipboard) + return; + + const auto data = mimeData(ClipboardMode::Clipboard); + if (!data) + return; + + // Ignore clipboard with secrets +#ifdef Q_OS_WIN + if ( data->hasFormat( + QStringLiteral("application/x-qt-windows-mime;value=\"Clipboard Viewer Ignore\"") + ) { + return; + } +#elif defined(Q_OS_MACOS) + if ( data->hasFormat(QStringLiteral("application/x-nspasteboard-concealed-type")) + return; +#elif defined(Q_OS_UNIX) + const QByteArray passwordManagerHint = data->data(QStringLiteral("x-kde-passwordManagerHint")); + if ( passwordManagerHint == QByteArrayLiteral("secret") ) + return; +#endif + + emit changed(ClipboardMode::Clipboard); } void DummyClipboard::onClipboardChanged(QClipboard::Mode mode) diff --git a/src/platform/x11/x11platformclipboard.cpp b/src/platform/x11/x11platformclipboard.cpp index 045b9caeb9..6f2fabdb65 100644 --- a/src/platform/x11/x11platformclipboard.cpp +++ b/src/platform/x11/x11platformclipboard.cpp @@ -253,7 +253,12 @@ void X11PlatformClipboard::updateClipboardData(X11PlatformClipboard::ClipboardDa } clipboardData->retry = 0; - const QByteArray newDataTimestampData = data->data(QLatin1String("TIMESTAMP")); + // Ignore clipboard with secrets + const QByteArray passwordManagerHint = data->data(QStringLiteral("x-kde-passwordManagerHint")); + if ( passwordManagerHint == QByteArrayLiteral("secret") ) + return; + + const QByteArray newDataTimestampData = data->data(QStringLiteral("TIMESTAMP")); quint32 newDataTimestamp = 0; if ( !newDataTimestampData.isEmpty() ) { QDataStream stream(newDataTimestampData); diff --git a/src/tests/tests.cpp b/src/tests/tests.cpp index 864a7ac216..a9e2235e2d 100644 --- a/src/tests/tests.cpp +++ b/src/tests/tests.cpp @@ -4393,6 +4393,30 @@ void Tests::startServerAndRunCommand() while ( run(Args("exit();sleep(10000)")) == 0 && t.sleep() ) {} } +void Tests::avoidStoringPasswords() +{ + waitFor(waitMsSetClipboard); + +#ifdef Q_OS_WIN + const QString format("application/x-qt-windows-mime;value=\"Clipboard Viewer Ignore\""); + const QByteArray value(""); +#elif defined(Q_OS_MACOS) + const QString format("application/x-nspasteboard-concealed-type"); + const QByteArray value("secret"); +#elif defined(Q_OS_UNIX) + const QString format("x-kde-passwordManagerHint"); + const QByteArray value("secret"); +#endif + + QVariantMap data; + data[format] = value; + data[mimeText] = QByteArray("secret"); + platformNativeInterface()->clipboard()->setData(ClipboardMode::Clipboard, data); + WAIT_FOR_CLIPBOARD2(value, format); + waitFor(3 * waitMsPasteClipboard); + RUN("read" << "0" << "1" << "2", "\n\n"); +} + int Tests::run( const QStringList &arguments, QByteArray *stdoutData, QByteArray *stderrData, const QByteArray &in, const QStringList &environment) diff --git a/src/tests/tests.h b/src/tests/tests.h index cc154d514b..7f68269b89 100644 --- a/src/tests/tests.h +++ b/src/tests/tests.h @@ -289,6 +289,8 @@ private slots: void startServerAndRunCommand(); + void avoidStoringPasswords(); + private: void clearServerErrors(); int run(const QStringList &arguments, QByteArray *stdoutData = nullptr,