src/murmur/Messages.cpp: Restrict string sizes for Version information

Before this commit it was possible to pass more or less arbitrary sized
strings as part of the Version message. This could lead to malicious
clients sending huge strings as part of this message.
The problem arises once these Strings are displayed in the UI (e.g. once
a user selects Information from the context menu of such a malicious
client). Qt will then be so busy to render this String that it
completely freezes the UI (#4067).

This commit prevents this attack by restricting the size of the Version
strings on the server side. If a client sends strings that exceed this
size, the server will drop the original content and replace it with a
generic "[[Invalid]]".
This commit is contained in:
Robert Adam 2020-04-24 11:08:58 +02:00
parent 2321aecd78
commit 466479992d

View File

@ -1807,17 +1807,34 @@ void Server::msgContextAction(ServerUser *uSource, MumbleProto::ContextAction &m
emit contextAction(uSource, u8(msg.action()), session, id);
}
/// @param str The std::string to convert
/// @param maxSize The maximum allowed size for this string
/// @returns The given std::string converted to a QString, if its size is less
/// than or equal to the given maxSize. If it is bigger, "[[Invalid]]"
/// is returned.
QString convertWithSizeRestriction(const std::string &str, size_t maxSize) {
if (str.size() > maxSize) {
return QLatin1String("[[Invalid]]");
}
return QString::fromStdString(str);
}
void Server::msgVersion(ServerUser *uSource, MumbleProto::Version &msg) {
RATELIMIT(uSource);
if (msg.has_version())
if (msg.has_version()) {
uSource->uiVersion=msg.version();
if (msg.has_release())
uSource->qsRelease = u8(msg.release());
}
if (msg.has_release()) {
uSource->qsRelease = convertWithSizeRestriction(msg.release(), 100);
}
if (msg.has_os()) {
uSource->qsOS = u8(msg.os());
if (msg.has_os_version())
uSource->qsOSVersion = u8(msg.os_version());
uSource->qsOS = convertWithSizeRestriction(msg.os(), 40);
if (msg.has_os_version()) {
uSource->qsOSVersion = convertWithSizeRestriction(msg.os_version(), 60);
}
}
log(uSource, QString("Client version %1 (%2 %3: %4)").arg(MumbleVersion::toString(uSource->uiVersion)).arg(uSource->qsOS).arg(uSource->qsOSVersion).arg(uSource->qsRelease));