create a more safe KONSOLE_DBUS_ACTIVATION_COOKIE cookie

check with that for the dbus activation

ensure we not leak this env var to dbus
This commit is contained in:
Christoph Cullmann
2025-08-17 17:51:32 +02:00
parent f2c1259ba7
commit 658cdc3fa2
2 changed files with 31 additions and 5 deletions

View File

@@ -20,10 +20,12 @@
// Qt
#include <QApplication>
#include <QByteArray>
#include <QColor>
#include <QDir>
#include <QFile>
#include <QKeyEvent>
#include <QRandomGenerator>
#include <QThread>
// KDE
@@ -87,8 +89,20 @@ static bool show_disallow_certain_dbus_methods_message = true;
static const int ZMODEM_BUFFER_SIZE = 1048576; // 1 Mb
// compute a securely random cookie used for activationToken
static QString computeRandomCookie()
{
// get good random data
quint32 array[8];
QRandomGenerator::global()->fillRange(array);
// convert to string usable for env var KONSOLE_DBUS_ACTIVATION_COOKIE
return QString::fromUtf8(QByteArray(reinterpret_cast<const char *>(array), sizeof(array)).toBase64());
}
Session::Session(QObject *parent)
: QObject(parent)
, m_activationCookie(computeRandomCookie())
{
_uniqueIdentifier = QUuid::createUuid();
@@ -562,18 +576,24 @@ void Session::run()
addEnvironmentEntry(QStringLiteral("WINDOWID=%1").arg(QString::number(windowId())));
// env vars we shall not expose e.g. over dbus
QStringList secretEnv;
#if HAVE_DBUS
const QString dbusService = QDBusConnection::sessionBus().baseService();
addEnvironmentEntry(QStringLiteral("KONSOLE_DBUS_SERVICE=%1").arg(dbusService));
const QString dbusObject = QStringLiteral("/Sessions/%1").arg(QString::number(_sessionId));
addEnvironmentEntry(QStringLiteral("KONSOLE_DBUS_SESSION=%1").arg(dbusObject));
// secret cookie to trigger activationToken via dbus
secretEnv << QStringLiteral("KONSOLE_DBUS_ACTIVATION_COOKIE=%1").arg(m_activationCookie);
#endif
#ifndef Q_OS_WIN
const auto originalEnvironment = _shellProcess->environment();
_shellProcess->setProgram(exec);
_shellProcess->setEnvironment(originalEnvironment + _environment);
_shellProcess->setEnvironment(originalEnvironment + _environment + secretEnv);
const auto context = KSandbox::makeHostContext(*_shellProcess);
arguments = postProcessArgs(context.arguments, arguments);
_shellProcess->setEnvironment(originalEnvironment);
@@ -2168,11 +2188,11 @@ void Session::runCommandFromLayout(const QString &command) const
_emulation->sendText(command + QLatin1Char('\n'));
}
QString Session::activationToken(const QString &shellSessionIdForRequest) const
QString Session::activationToken(const QString &cookieForRequest) const
{
// safety check, only work if the caller knows our id
// they will read it from the SHELL_SESSION_ID env var inside this session
if (shellSessionIdForRequest != shellSessionId()) {
if (cookieForRequest != m_activationCookie) {
return {};
}

View File

@@ -740,11 +740,11 @@ public Q_SLOTS:
/**
* DBus slot to get an XDG activation token.
* Will check if the passed shellSessionId is the current one for safety.
* Will check if the passed cookieForRequest is the m_activationCookie one for safety.
* Will try to generate a token and pass it back.
* Can only be called from DBus, will answer delayed.
*/
Q_SCRIPTABLE QString activationToken(const QString &shellSessionIdForRequest) const;
Q_SCRIPTABLE QString activationToken(const QString &cookieForRequest) const;
Q_SIGNALS:
@@ -978,6 +978,12 @@ private:
QString _currentHostName;
bool _selectMode = false;
/**
* secret cookie for activationToken, shall be only exposed to shell
* environment as KONSOLE_DBUS_ACTIVATION_COOKIE
*/
const QString m_activationCookie;
};
}