Skip to content

Commit

Permalink
Ignore clipboard data from password managers by default
Browse files Browse the repository at this point in the history
Fixes #2282, #2495
  • Loading branch information
hluk committed Oct 9, 2023
1 parent edfac75 commit b987262
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 3 deletions.
27 changes: 25 additions & 2 deletions src/platform/dummy/dummyclipboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "common/log.h"

#include <QGuiApplication>
#include <QMimeData>
#include <QStringList>

QClipboard::Mode modeToQClipboardMode(ClipboardMode mode)
Expand Down Expand Up @@ -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)
Expand Down
7 changes: 6 additions & 1 deletion src/platform/x11/x11platformclipboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
24 changes: 24 additions & 0 deletions src/tests/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions src/tests/tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,8 @@ private slots:

void startServerAndRunCommand();

void avoidStoringPasswords();

private:
void clearServerErrors();
int run(const QStringList &arguments, QByteArray *stdoutData = nullptr,
Expand Down

0 comments on commit b987262

Please sign in to comment.