diff --git a/package.json b/package.json index 0c49972..86045a3 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,10 @@ "version": "0.4", "license": "AGPL-3.0-only", "dependencies": { + "@braintree/sanitize-url": "^7.1.1", "altcha": "^1.0.7", "altcha-lib": "^1.2.0", + "argon2": "^0.44.0", "bcrypt": "^5.1.1", "bootstrap-icons": "^1.11.3", "connect-mongo": "^5.1.0", @@ -16,7 +18,7 @@ "hls.js": "^1.6.2", "mongoose": "^8.4.3", "node-cron": "^3.0.3", - "nodemailer": "^6.9.16", + "nodemailer": "^7.0.9", "socket.io": "^4.8.1", "youtube-dl-exec": "^3.0.20" }, @@ -26,7 +28,7 @@ "build": "node node_modules/jsdoc/jsdoc.js --verbose -r src/ -R README.md -d www/doc/server/ && node node_modules/jsdoc/jsdoc.js --verbose -r www/js/channel -r README.md -d www/doc/client/" }, "devDependencies": { - "nodemon": "^3.1.10", - "jsdoc": "^4.0.4" + "jsdoc": "^4.0.4", + "nodemon": "^3.1.10" } } diff --git a/src/app/channel/media/playlistHandler.js b/src/app/channel/media/playlistHandler.js index 9345590..70b8c2b 100644 --- a/src/app/channel/media/playlistHandler.js +++ b/src/app/channel/media/playlistHandler.js @@ -120,12 +120,12 @@ class playlistHandler{ */ async addToPlaylistValidator(socket, url){ //If we where given a bad URL - if(typeof url != 'string' || !validator.isURL(url)){ + if(typeof url != 'string' || !validator.isURL(url,{require_valid_protocol: true})){ //Attempt to fix the situation by encoding it url = encodeURI(url); //If it's still bad - if(typeof url != 'string' || !validator.isURL(url)){ + if(typeof url != 'string' || !validator.isURL(url,{require_valid_protocol: true})){ //Bitch, moan, complain... loggerUtils.socketErrorHandler(socket, "Bad URL!", "validation"); //and ignore it! diff --git a/src/app/channel/media/queue.js b/src/app/channel/media/queue.js index 7866783..9f68021 100644 --- a/src/app/channel/media/queue.js +++ b/src/app/channel/media/queue.js @@ -132,12 +132,12 @@ class queue{ let url = data.url; //If we where given a bad URL - if(!validator.isURL(url)){ + if(!validator.isURL(url,{require_valid_protocol: true})){ //Attempt to fix the situation by encoding it url = encodeURI(url); //If it's still bad - if(!validator.isURL(url)){ + if(!validator.isURL(url,{require_valid_protocol: true})){ //Bitch, moan, complain... loggerUtils.socketErrorHandler(socket, "Bad URL!", "validation"); //and ignore it! diff --git a/src/utils/linkUtils.js b/src/utils/linkUtils.js index 6452db1..9e85870 100644 --- a/src/utils/linkUtils.js +++ b/src/utils/linkUtils.js @@ -16,6 +16,7 @@ along with this program. If not, see .*/ //NPM Imports const validator = require('validator');//No express here, so regular validator it is! +const {sanitizeUrl} = require("@braintree/sanitize-url"); //Create link cache /** @@ -25,10 +26,12 @@ module.exports.cache = new Map(); /** * Validates links and returns a marked link object that can be returned to the client to format/embed accordingly - * @param {String} link - URL to Validate + * @param {String} dirtyLink - URL to Validate * @returns {Object} Marked link object */ -module.exports.markLink = async function(link){ +module.exports.markLink = async function(dirtyLink){ + const link = sanitizeUrl(dirtyLink); + //Check link cache for the requested link const cachedLink = module.exports.cache.get(link); @@ -44,7 +47,7 @@ module.exports.markLink = async function(link){ var type = "malformedLink" //Make sure we have an actual, factual URL - if(validator.isURL(link)){ + if(validator.isURL(link,{require_valid_protocol: true, protocols: ['http', 'https']})){ //The URL is valid, so this is at least a dead link type = 'deadLink'; diff --git a/src/utils/loggerUtils.js b/src/utils/loggerUtils.js index b3e30c3..3e9c0aa 100644 --- a/src/utils/loggerUtils.js +++ b/src/utils/loggerUtils.js @@ -173,7 +173,7 @@ module.exports.errorMiddleware = function(err, req, res, next){ * @param {Error} err - error to dump to file * @param {Date} date - Date of error, defaults to now */ -module.exports.dumpError = async function(err, date = new Date(), subDir){ +module.exports.dumpError = async function(err, date = new Date(), subDir = ''){ try{ //Crash directory const dir = `./log/crash/${subDir}` diff --git a/src/utils/media/yanker.js b/src/utils/media/yanker.js index f16640d..8072712 100644 --- a/src/utils/media/yanker.js +++ b/src/utils/media/yanker.js @@ -17,6 +17,7 @@ along with this program. If not, see .*/ //NPM Imports //const url = require("node:url"); const validator = require('validator');//No express here, so regular validator it is! +const {sanitizeUrl} = require("@braintree/sanitize-url"); //local import const iaUtil = require('./internetArchiveUtils'); @@ -96,12 +97,15 @@ module.exports.refreshRawLink = async function(mediaObj){ * Still this has some improvements like url pre-checks and the fact that it's handled serverside, recuing possibility of bad requests. * Some of the regex expressions for certain services have also been improved, such as youtube, and the fore.st-unique archive.org * - * @param {String} url - URL to determine media type of + * @param {String} dirtyURL - URL to determine media type of * @returns {Object} containing URL type and clipped ID string */ -module.exports.getMediaType = async function(url){ +module.exports.getMediaType = async function(dirtyURL){ + //Sanatize our URL + const url = sanitizeUrl(dirtyURL); + //Check if we have a valid url, encode it on the fly in case it's too humie-friendly - if(!validator.isURL(encodeURI(url))){ + if(!validator.isURL(encodeURI(url,{require_valid_protocol: true}))){ //If not toss the fucker out return { type: null, diff --git a/src/validators/accountValidator.js b/src/validators/accountValidator.js index 38f08b7..aa1d942 100644 --- a/src/validators/accountValidator.js +++ b/src/validators/accountValidator.js @@ -16,6 +16,7 @@ along with this program. If not, see .*/ //NPM Imports const { checkSchema } = require('express-validator'); +const {sanitizeUrl} = require("@braintree/sanitize-url"); //local imports const {isRank} = require('./permissionsValidator'); @@ -99,11 +100,15 @@ module.exports.img = function(field = 'img'){ isURL: { options: { require_tld: false, - require_host: false + require_host: false, + require_valid_protocol: true }, errorMessage: "Invalid URL." }, - trim: true + trim: true, + customSanitizer: { + options: sanitizeUrl + } } }); } diff --git a/src/validators/channelValidator.js b/src/validators/channelValidator.js index 60c9170..350dd87 100644 --- a/src/validators/channelValidator.js +++ b/src/validators/channelValidator.js @@ -83,7 +83,11 @@ module.exports.settingsMap = function(){ }, 'settingsMap.streamURL': { optional: true, - isURL: true, + isURL: { + options:{ + require_valid_protocol: true + } + }, errorMessage: "Invalid Stream URL" } }) diff --git a/src/validators/emoteValidator.js b/src/validators/emoteValidator.js index 3c4ee74..6416516 100644 --- a/src/validators/emoteValidator.js +++ b/src/validators/emoteValidator.js @@ -48,7 +48,8 @@ module.exports.link = function(field = 'link'){ isURL: { options: { require_tld: false, - require_host: false + require_host: false, + require_valid_protocol: true }, errorMessage: "Invalid URL." }, @@ -76,7 +77,7 @@ module.exports.manualLink = function(input){ const clean = validator.trim(input) //If we have a URL return the trimmed input - if(validator.isURL(clean)){ + if(validator.isURL(clean,{require_valid_protocol: true})){ return clean; }