From b24d4f2340c3e7efeffbd54a55bbcd84667bf55e Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Sat, 25 Nov 2023 21:56:57 +0200 Subject: [PATCH] Add opt-in CORS bypass endpoint --- default/config.conf | 1 + server.js | 45 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/default/config.conf b/default/config.conf index 257db767e..a256fd234 100644 --- a/default/config.conf +++ b/default/config.conf @@ -11,6 +11,7 @@ const allowKeysExposure = false; // If true, private API keys could be fetched t const skipContentCheck = false; // If true, no new default content will be delivered to you. const thumbnailsQuality = 95; // Quality of thumbnails. 0-100 const disableChatBackup = false; // Disables the backup of chat logs to the /backups folder +const enableCorsProxy = false; // Enables the CORS proxy for the frontend // If true, Allows insecure settings for listen, whitelist, and authentication. // Change this setting only on "trusted networks". Do not change this value unless you are aware of the issues that can arise from changing this setting and configuring a insecure setting. diff --git a/server.js b/server.js index f5db86f8b..2106b9148 100644 --- a/server.js +++ b/server.js @@ -76,8 +76,11 @@ const cliArguments = yargs(hideBin(process.argv)) type: 'boolean', default: null, describe: 'Automatically launch SillyTavern in the browser.' - }) - .option('disableCsrf', { + }).option('corsProxy', { + type: 'boolean', + default: false, + describe: 'Enables CORS proxy', + }).option('disableCsrf', { type: 'boolean', default: false, describe: 'Disables CSRF protection' @@ -319,6 +322,44 @@ app.use(function (req, res, next) { next(); }); +if (config.enableCorsProxy === true || cliArguments.corsProxy === true) { + console.log('Enabling CORS proxy'); + + app.use('/proxy/:url', async (req, res) => { + const url = req.params.url; // get the url from the request path + + // Disallow circular requests + const serverUrl = req.protocol + '://' + req.get('host'); + if (url.startsWith(serverUrl)) { + return res.status(400).send('Circular requests are not allowed'); + } + + try { + const headers = JSON.parse(JSON.stringify(req.headers)); + delete headers['x-csrf-token']; + delete headers['host']; + delete headers['referer']; + delete headers['origin']; + delete headers['cookie']; + delete headers['sec-fetch-mode']; + delete headers['sec-fetch-site']; + delete headers['sec-fetch-dest']; + + const bodyMethods = ['POST', 'PUT', 'PATCH']; + + const response = await fetch(url, { + method: req.method, + headers: headers, + body: bodyMethods.includes(req.method) ? JSON.stringify(req.body) : undefined, + }); + + response.body.pipe(res); // pipe the response to the proxy response + + } catch (error) { + res.status(500).send('Error occurred while trying to proxy to: ' + url + ' ' + error); + } + }); +} app.use(express.static(process.cwd() + "/public", {}));