From c8b2fc46dc698db687379106b3f01c71b80f495f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Mon, 25 Oct 2021 12:51:56 -0400 Subject: [PATCH] fix: translator path traversal --- src/languages.js | 6 +++++- test/posts.js | 2 +- test/translator.js | 5 +++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/languages.js b/src/languages.js index 200ec2a191..d307a439df 100644 --- a/src/languages.js +++ b/src/languages.js @@ -13,7 +13,11 @@ const files = fs.readdirSync(path.join(paths.nodeModules, '/timeago/locales')); Languages.timeagoCodes = files.filter(f => f.startsWith('jquery.timeago')).map(f => f.split('.')[2]); Languages.get = async function (language, namespace) { - const data = await fs.promises.readFile(path.join(languagesPath, language, `${namespace}.json`), 'utf8'); + const pathToLanguageFile = path.join(languagesPath, language, `${namespace}.json`); + if (!pathToLanguageFile.startsWith(languagesPath)) { + throw new Error('[[error:invalid-path]]'); + } + const data = await fs.promises.readFile(pathToLanguageFile, 'utf8'); const parsed = JSON.parse(data) || {}; const result = await plugins.hooks.fire('filter:languages.get', { language, diff --git a/test/posts.js b/test/posts.js index 20a7661da1..e6fa092536 100644 --- a/test/posts.js +++ b/test/posts.js @@ -1,7 +1,7 @@ 'use strict'; -const assert = require('assert'); +const assert = require('assert'); const async = require('async'); const request = require('request'); const nconf = require('nconf'); diff --git a/test/translator.js b/test/translator.js index b8edb2d3b2..02bc6de1ea 100644 --- a/test/translator.js +++ b/test/translator.js @@ -35,6 +35,11 @@ describe('Translator shim', () => { const translated = await shim.translate('', 'en-GB'); assert.strictEqual(translated, ''); }); + + it('should not allow path traversal', async () => { + const t = await shim.translate('[[../../../../config:secret]]'); + assert.strictEqual(t, 'secret'); + }); }); });