ban tor in guestbook
This commit is contained in:
parent
0c3ed4152e
commit
00703e39d1
|
@ -12,3 +12,7 @@ DB_DATABASE=homepage
|
||||||
|
|
||||||
REDIS_HOST=redis
|
REDIS_HOST=redis
|
||||||
REDIS_PORT=6379
|
REDIS_PORT=6379
|
||||||
|
|
||||||
|
# list services that are not tor-allowed
|
||||||
|
# separated by comma (,)
|
||||||
|
DISALLOW_TOR=guestbook
|
|
@ -3,5 +3,6 @@ module.exports = {
|
||||||
TimeSince: require('./timesince'),
|
TimeSince: require('./timesince'),
|
||||||
HtmlString: require('./htmlstring'),
|
HtmlString: require('./htmlstring'),
|
||||||
GPG: require('./gpg'),
|
GPG: require('./gpg'),
|
||||||
Minify: require('./minify')
|
Minify: require('./minify'),
|
||||||
|
TorChecker: require('./tor_check')
|
||||||
}
|
}
|
|
@ -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 };
|
|
@ -32,6 +32,7 @@
|
||||||
"ioredis": "^5.3.1",
|
"ioredis": "^5.3.1",
|
||||||
"js-base64": "^3.7.5",
|
"js-base64": "^3.7.5",
|
||||||
"mocha": "^10.2.0",
|
"mocha": "^10.2.0",
|
||||||
|
"node-fetch": "^3.3.1",
|
||||||
"node-gpg": "^0.2.0",
|
"node-gpg": "^0.2.0",
|
||||||
"otplib": "^12.0.1",
|
"otplib": "^12.0.1",
|
||||||
"pg": "^8.9.0",
|
"pg": "^8.9.0",
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
const Sequelize = require('../models');
|
const Sequelize = require('../models');
|
||||||
const xml = require('xml');
|
const xml = require('xml');
|
||||||
const handler = require('express-async-handler');
|
const handler = require('express-async-handler');
|
||||||
|
const Helpers = require('../helpers');
|
||||||
|
|
||||||
const send_error = async (res, error) => {
|
const send_error = async (res, error) => {
|
||||||
return res.redirect('/guestbook?error=' + encodeURIComponent(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');
|
if (!data) throw new Error('Failed to get guestbook entries');
|
||||||
|
|
||||||
|
|
||||||
res.template('guestbook.pug', {
|
res.template('guestbook.pug', {
|
||||||
current_route: req.originalUrl,
|
current_route: req.originalUrl,
|
||||||
ip: req.ip,
|
ip: req.ip,
|
||||||
|
@ -61,6 +61,14 @@ async function submit(req, res, next) {
|
||||||
if (message == '') {
|
if (message == '') {
|
||||||
errors.push('Message should not be empty!');
|
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) {
|
if (errors.length !== 0) {
|
||||||
send_error(res, "<p>" + errors.join('<br/>') + "</p>");
|
send_error(res, "<p>" + errors.join('<br/>') + "</p>");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
*
|
||||||
|
!.gitignore
|
Loading…
Reference in New Issue