From f244a43771f6ebf40218b83b9f46dba6b940d7de Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Mon, 29 Dec 2025 16:20:17 +0200 Subject: [PATCH] Security Fix 1: IDOR in setCreateTranslation. Non-admin could change Custom Translation. Thanks to Joshua Rogers of joshua.hu, Twitter MegaManSec. --- client/components/settings/translationBody.js | 2 +- models/translation.js | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/client/components/settings/translationBody.js b/client/components/settings/translationBody.js index c9a5c71ad..dcd1075fa 100644 --- a/client/components/settings/translationBody.js +++ b/client/components/settings/translationBody.js @@ -208,7 +208,7 @@ Template.newTranslationPopup.events({ Template.settingsTranslationPopup.events({ 'click #deleteButton'(event) { event.preventDefault(); - Translation.remove(this.translationId); + Meteor.call('deleteTranslation', this.translationId); Popup.back(); } }); diff --git a/models/translation.js b/models/translation.js index b473ff2b7..4f69829d1 100644 --- a/models/translation.js +++ b/models/translation.js @@ -98,6 +98,10 @@ if (Meteor.isServer) { check(text, String); check(translationText, String); + if (!ReactiveCache.getCurrentUser()?.isAdmin) { + throw new Meteor.Error('not-authorized'); + } + const nTexts = ReactiveCache.getTranslations({ language, text }).length; if (nTexts > 0) { throw new Meteor.Error('text-already-taken'); @@ -112,10 +116,24 @@ if (Meteor.isServer) { setTranslationText(translation, translationText) { check(translation, Object); check(translationText, String); + + if (!ReactiveCache.getCurrentUser()?.isAdmin) { + throw new Meteor.Error('not-authorized'); + } + Translation.update(translation, { $set: { translationText: translationText }, }); }, + deleteTranslation(translationId) { + check(translationId, String); + + if (!ReactiveCache.getCurrentUser()?.isAdmin) { + throw new Meteor.Error('not-authorized'); + } + + Translation.remove(translationId); + }, }); }