From 00703e39d1a4d1107e3e2254f25741b8c0be4e67 Mon Sep 17 00:00:00 2001 From: b1ek Date: Thu, 20 Apr 2023 16:40:47 +1000 Subject: [PATCH] ban tor in guestbook --- .env.example | 6 ++++- helpers/index.js | 3 ++- helpers/tor_check.js | 52 ++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + routes/guestbook.js | 10 ++++++++- store/.gitignore | 2 ++ 6 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 helpers/tor_check.js create mode 100644 store/.gitignore diff --git a/.env.example b/.env.example index feb425c..fd4368a 100644 --- a/.env.example +++ b/.env.example @@ -11,4 +11,8 @@ DB_USERNAME=homepage DB_DATABASE=homepage REDIS_HOST=redis -REDIS_PORT=6379 \ No newline at end of file +REDIS_PORT=6379 + +# list services that are not tor-allowed +# separated by comma (,) +DISALLOW_TOR=guestbook \ No newline at end of file diff --git a/helpers/index.js b/helpers/index.js index 7ee93fd..5f35e5f 100644 --- a/helpers/index.js +++ b/helpers/index.js @@ -3,5 +3,6 @@ module.exports = { TimeSince: require('./timesince'), HtmlString: require('./htmlstring'), GPG: require('./gpg'), - Minify: require('./minify') + Minify: require('./minify'), + TorChecker: require('./tor_check') } \ No newline at end of file diff --git a/helpers/tor_check.js b/helpers/tor_check.js new file mode 100644 index 0000000..9e2c807 --- /dev/null +++ b/helpers/tor_check.js @@ -0,0 +1,52 @@ +const fs = require('fs'); + +// fucking es6 +const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args)); + +let exits_list; +let is_job_running; + +if (exits_list == undefined) { + if (!fs.existsSync('store/torexits.json')) { + refreshList(); + } else { + exits_list = JSON.parse(fs.readFileSync('store/torexits.json', {encoding: 'utf-8'})); + } +} + +function isOutdated() { + // list expires in 4 hours + return Date.now() - exits_list.last_update > 1000 * 60 * 60 * 4; +} + +async function check(ip) { + if (!exits_list) { + await refreshList(); + } + return exits_list.ips.indexOf(ip) !== -1; +} + +async function refreshList() { + let data = { + last_update: Date.now(), + ips: undefined + }; + + let raw_list = await (await fetch('https://check.torproject.org/torbulkexitlist')).text(); + let ips = raw_list.replace('\r', '').split('\n'); + exits_list = { + last_update: Date.now(), + ips + }; + + fs.writeFileSync('store/torexits.json', JSON.stringify(exits_list, undefined, process.env.APP_DEBUG ? ' ' : undefined)); +} + +async function run_refresh_job() { + if (isOutdated()) { + refreshList(); + } + setTimeout(run_refresh_job, 1000 * 60 * 30); +} + +module.exports = { check, isOutdated }; \ No newline at end of file diff --git a/package.json b/package.json index 6fd5504..8ec7c66 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "ioredis": "^5.3.1", "js-base64": "^3.7.5", "mocha": "^10.2.0", + "node-fetch": "^3.3.1", "node-gpg": "^0.2.0", "otplib": "^12.0.1", "pg": "^8.9.0", diff --git a/routes/guestbook.js b/routes/guestbook.js index dc79688..4bec7cf 100644 --- a/routes/guestbook.js +++ b/routes/guestbook.js @@ -1,6 +1,7 @@ const Sequelize = require('../models'); const xml = require('xml'); const handler = require('express-async-handler'); +const Helpers = require('../helpers'); const send_error = async (res, error) => { return res.redirect('/guestbook?error=' + encodeURIComponent(error)); @@ -21,7 +22,6 @@ async function guestbook(req, res, next) { }); if (!data) throw new Error('Failed to get guestbook entries'); - res.template('guestbook.pug', { current_route: req.originalUrl, ip: req.ip, @@ -61,6 +61,14 @@ async function submit(req, res, next) { if (message == '') { errors.push('Message should not be empty!'); } + + if (process.env.DISALLOW_TOR.split(',').indexOf('guestbook') !== -1) { + let ip4 = req.ip.startsWith('::ffff:') ? req.ip.replace(/^::ffff:/, '') : req.ip; + if (await Helpers.TorChecker.check(ip4)) { + errors.push('Using tor is not allowed: IP ' + ip4 + ' is listed as a tor exit'); + } + } + if (errors.length !== 0) { send_error(res, "

" + errors.join('
') + "

"); return; diff --git a/store/.gitignore b/store/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/store/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file