aboutsummaryrefslogtreecommitdiff
path: root/launcher
diff options
context:
space:
mode:
Diffstat (limited to 'launcher')
-rw-r--r--launcher/minecraft/OneSixVersionFormat.cpp11
-rw-r--r--launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp19
2 files changed, 25 insertions, 5 deletions
diff --git a/launcher/minecraft/OneSixVersionFormat.cpp b/launcher/minecraft/OneSixVersionFormat.cpp
index 280f6b26..888b6860 100644
--- a/launcher/minecraft/OneSixVersionFormat.cpp
+++ b/launcher/minecraft/OneSixVersionFormat.cpp
@@ -39,6 +39,8 @@
#include "minecraft/ParseUtils.h"
#include <minecraft/MojangVersionFormat.h>
+#include <QRegularExpression>
+
using namespace Json;
static void readString(const QJsonObject &root, const QString &key, QString &variable)
@@ -121,6 +123,15 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc
out->uid = root.value("fileId").toString();
}
+ const QRegularExpression valid_uid_regex{ QRegularExpression::anchoredPattern(QStringLiteral(R"([a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]+)*)")) };
+ if (!valid_uid_regex.match(out->uid).hasMatch()) {
+ qCritical() << "The component's 'uid' contains illegal characters! UID:" << out->uid;
+ out->addProblem(
+ ProblemSeverity::Error,
+ QObject::tr("The component's 'uid' contains illegal characters! This can cause security issues.")
+ );
+ }
+
out->version = root.value("version").toString();
MojangVersionFormat::readVersionProperties(root, out.get());
diff --git a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp
index 94c0bf77..6814e645 100644
--- a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp
+++ b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp
@@ -225,10 +225,19 @@ bool ModrinthCreationTask::createInstance()
m_files_job.reset(new NetJob(tr("Mod download"), APPLICATION->network()));
+ auto root_modpack_path = FS::PathCombine(m_stagingPath, ".minecraft");
+ auto root_modpack_url = QUrl::fromLocalFile(root_modpack_path);
+
for (auto file : m_files) {
- auto path = FS::PathCombine(m_stagingPath, ".minecraft", file.path);
- qDebug() << "Will try to download" << file.downloads.front() << "to" << path;
- auto dl = Net::Download::makeFile(file.downloads.dequeue(), path);
+ auto file_path = FS::PathCombine(root_modpack_path, file.path);
+ if (!root_modpack_url.isParentOf(QUrl::fromLocalFile(file_path))) {
+ // This means we somehow got out of the root folder, so abort here to prevent exploits
+ setError(tr("One of the files has a path that leads to an arbitrary location (%1). This is a security risk and isn't allowed.").arg(file.path));
+ return false;
+ }
+
+ qDebug() << "Will try to download" << file.downloads.front() << "to" << file_path;
+ auto dl = Net::Download::makeFile(file.downloads.dequeue(), file_path);
dl->addValidator(new Net::ChecksumValidator(file.hashAlgorithm, file.hash));
m_files_job->addNetAction(dl);
@@ -236,8 +245,8 @@ bool ModrinthCreationTask::createInstance()
// FIXME: This really needs to be put into a ConcurrentTask of
// MultipleOptionsTask's , once those exist :)
auto param = dl.toWeakRef();
- connect(dl.get(), &NetAction::failed, [this, &file, path, param] {
- auto ndl = Net::Download::makeFile(file.downloads.dequeue(), path);
+ connect(dl.get(), &NetAction::failed, [this, &file, file_path, param] {
+ auto ndl = Net::Download::makeFile(file.downloads.dequeue(), file_path);
ndl->addValidator(new Net::ChecksumValidator(file.hashAlgorithm, file.hash));
m_files_job->addNetAction(ndl);
if (auto shared = param.lock()) shared->succeeded();