From f4604bbf797673b089367ec6af42723084b17181 Mon Sep 17 00:00:00 2001 From: flow Date: Sat, 28 May 2022 09:19:53 -0300 Subject: [PATCH 1/5] change: update whitelisted hosts in Modrinth modpacks --- launcher/InstanceImportTask.cpp | 11 ++++++++--- .../modplatform/modrinth/ModrinthPackManifest.cpp | 4 ---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/launcher/InstanceImportTask.cpp b/launcher/InstanceImportTask.cpp index 68a497cc..e3f54aeb 100644 --- a/launcher/InstanceImportTask.cpp +++ b/launcher/InstanceImportTask.cpp @@ -641,10 +641,15 @@ void InstanceImportTask::processModrinth() file.hashAlgorithm = hashAlgorithm; // Do not use requireUrl, which uses StrictMode, instead use QUrl's default TolerantMode // (as Modrinth seems to incorrectly handle spaces) + file.download = Json::requireString(Json::ensureArray(modInfo, "downloads").first(), "Download URL for " + file.path); - if (!file.download.isValid() || !Modrinth::validateDownloadUrl(file.download)) { - throw JSONValidationError("Download URL for " + file.path + " is not a correctly formatted URL"); - } + + if(!file.download.isValid()) + throw JSONValidationError(tr("Download URL for %1 is not a correctly formatted URL").arg(file.path)); + else if(!Modrinth::validateDownloadUrl(file.download)) + throw JSONValidationError( + tr("Download URL for %1 is from a non-whitelisted by Modrinth domain: %2").arg(file.path, file.download.host())); + files.push_back(file); } diff --git a/launcher/modplatform/modrinth/ModrinthPackManifest.cpp b/launcher/modplatform/modrinth/ModrinthPackManifest.cpp index f1ad39ce..b1c4fbcd 100644 --- a/launcher/modplatform/modrinth/ModrinthPackManifest.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackManifest.cpp @@ -98,10 +98,6 @@ auto validateDownloadUrl(QUrl url) -> bool auto domain = url.host(); if(domain == "cdn.modrinth.com") return true; - if(domain == "edge.forgecdn.net") - return true; - if(domain == "media.forgecdn.net") - return true; if(domain == "github.com") return true; if(domain == "raw.githubusercontent.com") From 1698554024d8fb7646a7a725e354a960ee19b568 Mon Sep 17 00:00:00 2001 From: flow Date: Sat, 28 May 2022 14:12:00 -0300 Subject: [PATCH 2/5] debug: add non-translated debug logging for 'non-whitelisted url' fails --- launcher/InstanceImportTask.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/launcher/InstanceImportTask.cpp b/launcher/InstanceImportTask.cpp index e3f54aeb..f166088f 100644 --- a/launcher/InstanceImportTask.cpp +++ b/launcher/InstanceImportTask.cpp @@ -644,11 +644,15 @@ void InstanceImportTask::processModrinth() file.download = Json::requireString(Json::ensureArray(modInfo, "downloads").first(), "Download URL for " + file.path); - if(!file.download.isValid()) + if (!file.download.isValid()) { + qDebug() << QString("Download URL (%1) for %2 is not a correctly formatted URL").arg(file.download.toString(), file.path); throw JSONValidationError(tr("Download URL for %1 is not a correctly formatted URL").arg(file.path)); - else if(!Modrinth::validateDownloadUrl(file.download)) + } + else if (!Modrinth::validateDownloadUrl(file.download)) { + qDebug() << QString("Download URL (%1) for %2 is from a non-whitelisted by Modrinth domain").arg(file.download.toString(), file.path); throw JSONValidationError( tr("Download URL for %1 is from a non-whitelisted by Modrinth domain: %2").arg(file.path, file.download.host())); + } files.push_back(file); } From b5e00027d1a16744ae9287b1262e7f6405bd9d5d Mon Sep 17 00:00:00 2001 From: flow Date: Sat, 28 May 2022 14:16:05 -0300 Subject: [PATCH 3/5] change: add 'gitlab.com' to whitelisted Modrinth modpack urls --- launcher/modplatform/modrinth/ModrinthPackManifest.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/launcher/modplatform/modrinth/ModrinthPackManifest.cpp b/launcher/modplatform/modrinth/ModrinthPackManifest.cpp index b1c4fbcd..8b379480 100644 --- a/launcher/modplatform/modrinth/ModrinthPackManifest.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackManifest.cpp @@ -102,6 +102,8 @@ auto validateDownloadUrl(QUrl url) -> bool return true; if(domain == "raw.githubusercontent.com") return true; + if(domain == "gitlab.com") + return true; return false; } From abd240468e362231ce8cbc23573faea9a0e657f4 Mon Sep 17 00:00:00 2001 From: Lenny McLennington Date: Sat, 28 May 2022 19:54:00 +0100 Subject: [PATCH 4/5] clean up validateDownloadUrl --- .../modrinth/ModrinthPackManifest.cpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/launcher/modplatform/modrinth/ModrinthPackManifest.cpp b/launcher/modplatform/modrinth/ModrinthPackManifest.cpp index 8b379480..33116231 100644 --- a/launcher/modplatform/modrinth/ModrinthPackManifest.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackManifest.cpp @@ -42,6 +42,8 @@ #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" +#include + static ModrinthAPI api; namespace Modrinth { @@ -95,17 +97,15 @@ void loadIndexedVersions(Modpack& pack, QJsonDocument& doc) auto validateDownloadUrl(QUrl url) -> bool { - auto domain = url.host(); - if(domain == "cdn.modrinth.com") - return true; - if(domain == "github.com") - return true; - if(domain == "raw.githubusercontent.com") - return true; - if(domain == "gitlab.com") - return true; + static QSet domainWhitelist{ + "cdn.modrinth.com", + "github.com", + "raw.githubusercontent.com", + "gitlab.com" + }; - return false; + auto domain = url.host(); + return domainWhitelist.contains(domain); } auto loadIndexedVersion(QJsonObject &obj) -> ModpackVersion From f0ec165d42fb694f8027fb32f8c6d0867f286ced Mon Sep 17 00:00:00 2001 From: flow Date: Sat, 28 May 2022 18:04:16 -0300 Subject: [PATCH 5/5] feat: add warning of non-whitelisted URLs instead of a hard fail Based on people's votes on Discord :^) --- launcher/InstanceImportTask.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/launcher/InstanceImportTask.cpp b/launcher/InstanceImportTask.cpp index f166088f..0b97430e 100644 --- a/launcher/InstanceImportTask.cpp +++ b/launcher/InstanceImportTask.cpp @@ -585,6 +585,7 @@ void InstanceImportTask::processMultiMC() void InstanceImportTask::processModrinth() { std::vector files; + std::vector non_whitelisted_files; QString minecraftVersion, fabricVersion, quiltVersion, forgeVersion; try { QString indexPath = FS::PathCombine(m_stagingPath, "modrinth.index.json"); @@ -650,13 +651,29 @@ void InstanceImportTask::processModrinth() } else if (!Modrinth::validateDownloadUrl(file.download)) { qDebug() << QString("Download URL (%1) for %2 is from a non-whitelisted by Modrinth domain").arg(file.download.toString(), file.path); - throw JSONValidationError( - tr("Download URL for %1 is from a non-whitelisted by Modrinth domain: %2").arg(file.path, file.download.host())); + non_whitelisted_files.push_back(file); } files.push_back(file); } + if (!non_whitelisted_files.empty()) { + QString text; + for (const auto& file : non_whitelisted_files) { + text += tr("Filepath: %1
URL: %2
").arg(file.path, file.download.toString()); + } + + auto message_dialog = new ScrollMessageBox(m_parent, tr("Non-whitelisted mods found"), + tr("The following mods have URLs that are not whitelisted by Modrinth.\n" + "Proceed with caution!"), + text); + message_dialog->setModal(true); + if (message_dialog->exec() == QDialog::Rejected) { + emitFailed("Aborted"); + return; + } + } + auto dependencies = Json::requireObject(obj, "dependencies", "modrinth.index.json"); for (auto it = dependencies.begin(), end = dependencies.end(); it != end; ++it) { QString name = it.key();