tldr dnsbl and bypass sucks cock

indiachan-spamvector
Thomas Lynch 2 years ago
parent 6798cb843e
commit 7b784283f8
  1. 14
      controllers/forms.js
  2. 6
      controllers/forms/index.js
  3. 118
      helpers/checks/blockbypass.js
  4. 14
      helpers/checks/dnsbl.js

@ -20,7 +20,7 @@ const express = require('express')
, useSession = require(__dirname+'/../helpers/usesession.js') , useSession = require(__dirname+'/../helpers/usesession.js')
, sessionRefresh = require(__dirname+'/../helpers/sessionrefresh.js') , sessionRefresh = require(__dirname+'/../helpers/sessionrefresh.js')
, dnsblCheck = require(__dirname+'/../helpers/checks/dnsbl.js') , dnsblCheck = require(__dirname+'/../helpers/checks/dnsbl.js')
, blockBypassCheck = require(__dirname+'/../helpers/checks/blockbypass.js') , blockBypass = require(__dirname+'/../helpers/checks/blockbypass.js')
, fileMiddlewares = require(__dirname+'/../helpers/filemiddlewares.js') , fileMiddlewares = require(__dirname+'/../helpers/filemiddlewares.js')
//controllers //controllers
, { deleteBoardController, editBansController, appealController, globalActionController, , { deleteBoardController, editBansController, appealController, globalActionController,
@ -30,14 +30,14 @@ const express = require('express')
resignController, deleteAccountController, loginController, registerController, changePasswordController, resignController, deleteAccountController, loginController, registerController, changePasswordController,
deleteAccountsController, editAccountController, globalSettingsController, createBoardController, makePostController, deleteAccountsController, editAccountController, globalSettingsController, createBoardController, makePostController,
addStaffController, deleteStaffController, editStaffController, editCustomPageController, editPostController, addStaffController, deleteStaffController, editStaffController, editCustomPageController, editPostController,
editRoleController, newCaptcha, blockBypass, logout, deleteSessionsController } = require(__dirname+'/forms/index.js'); editRoleController, newCaptchaForm, blockBypassForm, logoutForm, deleteSessionsController } = require(__dirname+'/forms/index.js');
//make new post //make new post
router.post('/board/:board/post', geoAndTor, fileMiddlewares.postsEarly, torPreBypassCheck, processIp, useSession, sessionRefresh, Boards.exists, calcPerms, banCheck, fileMiddlewares.posts, router.post('/board/:board/post', geoAndTor, fileMiddlewares.postsEarly, torPreBypassCheck, processIp, useSession, sessionRefresh, Boards.exists, calcPerms, banCheck, fileMiddlewares.posts,
makePostController.paramConverter, verifyCaptcha, numFiles, blockBypassCheck, dnsblCheck, imageHashes, makePostController.controller); makePostController.paramConverter, verifyCaptcha, numFiles, blockBypass.middleware, dnsblCheck, imageHashes, makePostController.controller);
router.post('/board/:board/modpost', geoAndTor, fileMiddlewares.postsEarly, torPreBypassCheck, processIp, useSession, sessionRefresh, Boards.exists, calcPerms, banCheck, isLoggedIn, router.post('/board/:board/modpost', geoAndTor, fileMiddlewares.postsEarly, torPreBypassCheck, processIp, useSession, sessionRefresh, Boards.exists, calcPerms, banCheck, isLoggedIn,
hasPerms.one(Permissions.MANAGE_BOARD_GENERAL), fileMiddlewares.posts, makePostController.paramConverter, csrf, numFiles, blockBypassCheck, dnsblCheck, makePostController.controller); //mod post has token instead of captcha hasPerms.one(Permissions.MANAGE_BOARD_GENERAL), fileMiddlewares.posts, makePostController.paramConverter, csrf, numFiles, blockBypass.middleware, dnsblCheck, makePostController.controller); //mod post has token instead of captcha
//post actions //post actions
router.post('/board/:board/actions', geoAndTor, torPreBypassCheck, processIp, useSession, sessionRefresh, Boards.exists, calcPerms, banCheck, actionController.paramConverter, verifyCaptcha, actionController.controller); //public, with captcha router.post('/board/:board/actions', geoAndTor, torPreBypassCheck, processIp, useSession, sessionRefresh, Boards.exists, calcPerms, banCheck, actionController.paramConverter, verifyCaptcha, actionController.controller); //public, with captcha
@ -114,7 +114,7 @@ router.post('/create', geoAndTor, torPreBypassCheck, processIp, useSession, sess
//accounts //accounts
router.post('/login', useSession, loginController.paramConverter, loginController.controller); router.post('/login', useSession, loginController.paramConverter, loginController.controller);
router.post('/logout', useSession, logout); router.post('/logout', useSession, logoutForm);
router.post('/register', geoAndTor, torPreBypassCheck, processIp, useSession, sessionRefresh, verifyCaptcha, calcPerms, registerController.paramConverter, registerController.controller); router.post('/register', geoAndTor, torPreBypassCheck, processIp, useSession, sessionRefresh, verifyCaptcha, calcPerms, registerController.paramConverter, registerController.controller);
router.post('/changepassword', geoAndTor, torPreBypassCheck, processIp, useSession, sessionRefresh, verifyCaptcha, changePasswordController.paramConverter, changePasswordController.controller); router.post('/changepassword', geoAndTor, torPreBypassCheck, processIp, useSession, sessionRefresh, verifyCaptcha, changePasswordController.paramConverter, changePasswordController.controller);
router.post('/resign', useSession, sessionRefresh, csrf, calcPerms, isLoggedIn, resignController.paramConverter, resignController.controller); router.post('/resign', useSession, sessionRefresh, csrf, calcPerms, isLoggedIn, resignController.paramConverter, resignController.controller);
@ -122,9 +122,9 @@ router.post('/deleteaccount', useSession, sessionRefresh, csrf, calcPerms, isLog
router.post('/deletesessions', useSession, sessionRefresh, csrf, calcPerms, isLoggedIn, deleteSessionsController.paramConverter, deleteSessionsController.controller); router.post('/deletesessions', useSession, sessionRefresh, csrf, calcPerms, isLoggedIn, deleteSessionsController.paramConverter, deleteSessionsController.controller);
//removes captcha cookie, for refreshing for noscript users //removes captcha cookie, for refreshing for noscript users
router.post('/newcaptcha', newCaptcha); router.post('/newcaptcha', newCaptchaForm);
//solve captcha for block bypass //solve captcha for block bypass
router.post('/blockbypass', geoAndTor, processIp, verifyCaptcha, blockBypass); router.post('/blockbypass', geoAndTor, processIp, verifyCaptcha, blockBypassForm);
module.exports = router; module.exports = router;

@ -39,8 +39,8 @@ module.exports = {
editRoleController: require(__dirname+'/editrole.js'), editRoleController: require(__dirname+'/editrole.js'),
//these dont have a "real" controller //these dont have a "real" controller
newCaptcha: require(__dirname+'/../../models/forms/newcaptcha.js'), newCaptchaForm: require(__dirname+'/../../models/forms/newcaptcha.js'),
blockBypass: require(__dirname+'/../../models/forms/blockbypass.js'), blockBypassForm: require(__dirname+'/../../models/forms/blockbypass.js'),
logout: require(__dirname+'/../../models/forms/logout.js'), logoutForm: require(__dirname+'/../../models/forms/logout.js'),
}; };

@ -7,73 +7,81 @@ const { Bypass } = require(__dirname+'/../../db/')
, dynamicResponse = require(__dirname+'/../dynamic.js') , dynamicResponse = require(__dirname+'/../dynamic.js')
, production = process.env.NODE_ENV === 'production'; , production = process.env.NODE_ENV === 'production';
module.exports = async (req, res, next) => { module.exports = {
const { secureCookies, blockBypass } = config.get; check: async (req, res, next) => {
if (res.locals.preFetchedBypassId //if they already have a bypass const { secureCookies, blockBypass } = config.get;
|| (!blockBypass.enabled //or if block bypass isnt enabled
&& (!blockBypass.forceAnonymizers //and we dont force it for anonymizer //check if blockbypass exists and right length
|| !res.locals.anonymizer))) { //or they arent on an anonymizer const bypassId = req.signedCookies.bypassid;
return next(); if (!res.locals.solvedCaptcha && (!bypassId || bypassId.length !== 24)) {
} deleteTempFiles(req).catch(e => console.error);
return dynamicResponse(req, res, 403, 'message', {
'title': 'Forbidden',
'message': 'Please complete a block bypass to continue',
'frame': '/bypass_minimal.html',
'link': {
'href': '/bypass.html',
'text': 'Get block bypass',
},
});
}
//try to get bypass from db and make sure uses < maxUses
let bypass;
if (bypassId && bypassId.length === 24) {
try {
const bypassMongoId = ObjectId(bypassId);
bypass = await Bypass.checkBypass(bypassMongoId, res.locals.anonymizer);
res.locals.blockBypass = true;
} catch (err) {
return next(err);
}
}
if (bypass //if they have a valid bypass
&& (bypass.uses < blockBypass.expireAfterUses //and its not overused
|| (res.locals.anonymizer
&& !blockBypass.forceAnonymizers))) { //OR its not forced for anonymizers
return next();
}
if (res.locals.solvedCaptcha) {
//they dont have a valid bypass, but just solved board captcha, so give them a new one
const newBypass = await Bypass.getBypass(res.locals.anonymizer);
const newBypassId = newBypass.insertedId;
res.locals.blockBypass = true;
res.cookie('bypassid', newBypassId.toString(), {
'maxAge': blockBypass.expireAfterTime,
'secure': production && secureCookies && (req.headers['x-forwarded-proto'] === 'https'),
'sameSite': 'strict',
'signed': true
});
return next();
}
//check if blockbypass exists and right length
const bypassId = req.signedCookies.bypassid;
if (!res.locals.solvedCaptcha && (!bypassId || bypassId.length !== 24)) {
deleteTempFiles(req).catch(e => console.error); deleteTempFiles(req).catch(e => console.error);
return dynamicResponse(req, res, 403, 'message', { return dynamicResponse(req, res, 403, 'message', {
'title': 'Forbidden', 'title': 'Forbidden',
'message': 'Please complete a block bypass to continue', 'message': 'Block bypass expired or exceeded max uses',
'frame': '/bypass_minimal.html', 'frame': '/bypass_minimal.html',
'link': { 'link': {
'href': '/bypass.html', 'href': '/bypass.html',
'text': 'Get block bypass', 'text': 'Get block bypass',
}, },
}); });
}
//try to get bypass from db and make sure uses < maxUses
let bypass;
if (bypassId && bypassId.length === 24) {
try {
const bypassMongoId = ObjectId(bypassId);
bypass = await Bypass.checkBypass(bypassMongoId, res.locals.anonymizer);
res.locals.blockBypass = true;
} catch (err) {
return next(err);
}
}
if (bypass //if they have a valid bypass },
&& (bypass.uses < blockBypass.expireAfterUses //and its not overused
|| (res.locals.anonymizer
&& !blockBypass.forceAnonymizers))) { //OR its not forced for anonymizers
return next();
}
if (res.locals.solvedCaptcha) { middleware: async (req, res, next) => {
//they dont have a valid bypass, but just solved board captcha, so give them a new one const { blockBypass } = config.get;
const newBypass = await Bypass.getBypass(res.locals.anonymizer); if (res.locals.preFetchedBypassId //if they already have a bypass
const newBypassId = newBypass.insertedId; || (!blockBypass.enabled //or if block bypass isnt enabled
res.locals.blockBypass = true; && (!blockBypass.forceAnonymizers //and we dont force it for anonymizer
res.cookie('bypassid', newBypassId.toString(), { || !res.locals.anonymizer))) { //or they arent on an anonymizer
'maxAge': blockBypass.expireAfterTime, return next();
'secure': production && secureCookies && (req.headers['x-forwarded-proto'] === 'https'), }
'sameSite': 'strict', return module.exports.check(req, res, next);
'signed': true },
});
return next();
}
deleteTempFiles(req).catch(e => console.error);
return dynamicResponse(req, res, 403, 'message', {
'title': 'Forbidden',
'message': 'Block bypass expired or exceeded max uses',
'frame': '/bypass_minimal.html',
'link': {
'href': '/bypass.html',
'text': 'Get block bypass',
},
});
} }

@ -1,6 +1,7 @@
'use strict'; 'use strict';
const cache = require(__dirname+'/../../redis.js') const cache = require(__dirname+'/../../redis.js')
, { check: blockBypassCheck } = require(__dirname+'/blockbypass.js')
, dynamicResponse = require(__dirname+'/../dynamic.js') , dynamicResponse = require(__dirname+'/../dynamic.js')
, deleteTempFiles = require(__dirname+'/../files/deletetempfiles.js') , deleteTempFiles = require(__dirname+'/../files/deletetempfiles.js')
, config = require(__dirname+'/../../config.js') , config = require(__dirname+'/../../config.js')
@ -9,9 +10,16 @@ const cache = require(__dirname+'/../../redis.js')
module.exports = async (req, res, next) => { module.exports = async (req, res, next) => {
const { ipHeader, dnsbl, blockBypass } = config.get; const { ipHeader, dnsbl, blockBypass } = config.get;
if (dnsbl.enabled && dnsbl.blacklists.length > 0 //if dnsbl enabled and has more than 0 blacklists if (dnsbl.enabled && dnsbl.blacklists.length > 0 //if dnsbl enabled and has more than 0 blacklists
&& !res.locals.anonymizer //anonymizers cant be dnsbl'd && !res.locals.anonymizer) { //anonymizers cant be dnsbl'd
&& (!res.locals.blockBypass || !blockBypass.bypassDnsbl)) { //and there is no valid block bypass, or they do not bypass dnsbl if (blockBypass.bypassDnsbl) {
if (!res.locals.blockBypass) {
return blockBypassCheck(req, res, next);
}
return next(); //already solved
}
//otherwise, bad block bypass or dnsbl cant be bypassed
const ip = req.headers[ipHeader] || req.connection.remoteAddress; const ip = req.headers[ipHeader] || req.connection.remoteAddress;
let isBlacklisted = await cache.get(`blacklisted:${ip}`); let isBlacklisted = await cache.get(`blacklisted:${ip}`);
if (isBlacklisted === null) { //not cached if (isBlacklisted === null) { //not cached
@ -23,7 +31,7 @@ module.exports = async (req, res, next) => {
deleteTempFiles(req).catch(e => console.error); deleteTempFiles(req).catch(e => console.error);
return dynamicResponse(req, res, 403, 'message', { return dynamicResponse(req, res, 403, 'message', {
'title': 'Forbidden', 'title': 'Forbidden',
'message': `Your request was blocked because your IP address is listed on a blacklist.${blockBypass.bypassDnsbl ? ' You can solve a "block bypass" to temporarily circumvent blacklisting.' : ''}`, 'message': `Your request was blocked because your IP address is listed on a blacklist.`,
'redirect': req.headers.referer || '/', 'redirect': req.headers.referer || '/',
'link': blockBypass.bypassDnsbl ? { text: 'Solve block bypass', href: '/bypass.html' } : null, 'link': blockBypass.bypassDnsbl ? { text: 'Solve block bypass', href: '/bypass.html' } : null,
}); });

Loading…
Cancel
Save