Improved link validation and sanatization, in order to mitigate CVE-2025-56200 from validator.js NPM package.
This commit is contained in:
parent
6bab5b4723
commit
06f552a9ec
|
|
@ -3,8 +3,10 @@
|
||||||
"version": "0.4",
|
"version": "0.4",
|
||||||
"license": "AGPL-3.0-only",
|
"license": "AGPL-3.0-only",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@braintree/sanitize-url": "^7.1.1",
|
||||||
"altcha": "^1.0.7",
|
"altcha": "^1.0.7",
|
||||||
"altcha-lib": "^1.2.0",
|
"altcha-lib": "^1.2.0",
|
||||||
|
"argon2": "^0.44.0",
|
||||||
"bcrypt": "^5.1.1",
|
"bcrypt": "^5.1.1",
|
||||||
"bootstrap-icons": "^1.11.3",
|
"bootstrap-icons": "^1.11.3",
|
||||||
"connect-mongo": "^5.1.0",
|
"connect-mongo": "^5.1.0",
|
||||||
|
|
@ -16,7 +18,7 @@
|
||||||
"hls.js": "^1.6.2",
|
"hls.js": "^1.6.2",
|
||||||
"mongoose": "^8.4.3",
|
"mongoose": "^8.4.3",
|
||||||
"node-cron": "^3.0.3",
|
"node-cron": "^3.0.3",
|
||||||
"nodemailer": "^6.9.16",
|
"nodemailer": "^7.0.9",
|
||||||
"socket.io": "^4.8.1",
|
"socket.io": "^4.8.1",
|
||||||
"youtube-dl-exec": "^3.0.20"
|
"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/"
|
"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": {
|
"devDependencies": {
|
||||||
"nodemon": "^3.1.10",
|
"jsdoc": "^4.0.4",
|
||||||
"jsdoc": "^4.0.4"
|
"nodemon": "^3.1.10"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -120,12 +120,12 @@ class playlistHandler{
|
||||||
*/
|
*/
|
||||||
async addToPlaylistValidator(socket, url){
|
async addToPlaylistValidator(socket, url){
|
||||||
//If we where given a bad 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
|
//Attempt to fix the situation by encoding it
|
||||||
url = encodeURI(url);
|
url = encodeURI(url);
|
||||||
|
|
||||||
//If it's still bad
|
//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...
|
//Bitch, moan, complain...
|
||||||
loggerUtils.socketErrorHandler(socket, "Bad URL!", "validation");
|
loggerUtils.socketErrorHandler(socket, "Bad URL!", "validation");
|
||||||
//and ignore it!
|
//and ignore it!
|
||||||
|
|
|
||||||
|
|
@ -132,12 +132,12 @@ class queue{
|
||||||
let url = data.url;
|
let url = data.url;
|
||||||
|
|
||||||
//If we where given a bad 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
|
//Attempt to fix the situation by encoding it
|
||||||
url = encodeURI(url);
|
url = encodeURI(url);
|
||||||
|
|
||||||
//If it's still bad
|
//If it's still bad
|
||||||
if(!validator.isURL(url)){
|
if(!validator.isURL(url,{require_valid_protocol: true})){
|
||||||
//Bitch, moan, complain...
|
//Bitch, moan, complain...
|
||||||
loggerUtils.socketErrorHandler(socket, "Bad URL!", "validation");
|
loggerUtils.socketErrorHandler(socket, "Bad URL!", "validation");
|
||||||
//and ignore it!
|
//and ignore it!
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||||
|
|
||||||
//NPM Imports
|
//NPM Imports
|
||||||
const validator = require('validator');//No express here, so regular validator it is!
|
const validator = require('validator');//No express here, so regular validator it is!
|
||||||
|
const {sanitizeUrl} = require("@braintree/sanitize-url");
|
||||||
|
|
||||||
//Create link cache
|
//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
|
* 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
|
* @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
|
//Check link cache for the requested link
|
||||||
const cachedLink = module.exports.cache.get(link);
|
const cachedLink = module.exports.cache.get(link);
|
||||||
|
|
||||||
|
|
@ -44,7 +47,7 @@ module.exports.markLink = async function(link){
|
||||||
var type = "malformedLink"
|
var type = "malformedLink"
|
||||||
|
|
||||||
//Make sure we have an actual, factual URL
|
//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
|
//The URL is valid, so this is at least a dead link
|
||||||
type = 'deadLink';
|
type = 'deadLink';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,7 @@ module.exports.errorMiddleware = function(err, req, res, next){
|
||||||
* @param {Error} err - error to dump to file
|
* @param {Error} err - error to dump to file
|
||||||
* @param {Date} date - Date of error, defaults to now
|
* @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{
|
try{
|
||||||
//Crash directory
|
//Crash directory
|
||||||
const dir = `./log/crash/${subDir}`
|
const dir = `./log/crash/${subDir}`
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||||
//NPM Imports
|
//NPM Imports
|
||||||
//const url = require("node:url");
|
//const url = require("node:url");
|
||||||
const validator = require('validator');//No express here, so regular validator it is!
|
const validator = require('validator');//No express here, so regular validator it is!
|
||||||
|
const {sanitizeUrl} = require("@braintree/sanitize-url");
|
||||||
|
|
||||||
//local import
|
//local import
|
||||||
const iaUtil = require('./internetArchiveUtils');
|
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.
|
* 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
|
* 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
|
* @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
|
//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
|
//If not toss the fucker out
|
||||||
return {
|
return {
|
||||||
type: null,
|
type: null,
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||||
|
|
||||||
//NPM Imports
|
//NPM Imports
|
||||||
const { checkSchema } = require('express-validator');
|
const { checkSchema } = require('express-validator');
|
||||||
|
const {sanitizeUrl} = require("@braintree/sanitize-url");
|
||||||
|
|
||||||
//local imports
|
//local imports
|
||||||
const {isRank} = require('./permissionsValidator');
|
const {isRank} = require('./permissionsValidator');
|
||||||
|
|
@ -99,11 +100,15 @@ module.exports.img = function(field = 'img'){
|
||||||
isURL: {
|
isURL: {
|
||||||
options: {
|
options: {
|
||||||
require_tld: false,
|
require_tld: false,
|
||||||
require_host: false
|
require_host: false,
|
||||||
|
require_valid_protocol: true
|
||||||
},
|
},
|
||||||
errorMessage: "Invalid URL."
|
errorMessage: "Invalid URL."
|
||||||
},
|
},
|
||||||
trim: true
|
trim: true,
|
||||||
|
customSanitizer: {
|
||||||
|
options: sanitizeUrl
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,11 @@ module.exports.settingsMap = function(){
|
||||||
},
|
},
|
||||||
'settingsMap.streamURL': {
|
'settingsMap.streamURL': {
|
||||||
optional: true,
|
optional: true,
|
||||||
isURL: true,
|
isURL: {
|
||||||
|
options:{
|
||||||
|
require_valid_protocol: true
|
||||||
|
}
|
||||||
|
},
|
||||||
errorMessage: "Invalid Stream URL"
|
errorMessage: "Invalid Stream URL"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,8 @@ module.exports.link = function(field = 'link'){
|
||||||
isURL: {
|
isURL: {
|
||||||
options: {
|
options: {
|
||||||
require_tld: false,
|
require_tld: false,
|
||||||
require_host: false
|
require_host: false,
|
||||||
|
require_valid_protocol: true
|
||||||
},
|
},
|
||||||
errorMessage: "Invalid URL."
|
errorMessage: "Invalid URL."
|
||||||
},
|
},
|
||||||
|
|
@ -76,7 +77,7 @@ module.exports.manualLink = function(input){
|
||||||
const clean = validator.trim(input)
|
const clean = validator.trim(input)
|
||||||
|
|
||||||
//If we have a URL return the trimmed input
|
//If we have a URL return the trimmed input
|
||||||
if(validator.isURL(clean)){
|
if(validator.isURL(clean,{require_valid_protocol: true})){
|
||||||
return clean;
|
return clean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue