CodeQL fix: limit parameter sizes

This commit is contained in:
mikiher 2025-10-15 18:54:29 +03:00
parent 888190a6be
commit 3f6162f53c
2 changed files with 19 additions and 6 deletions

View File

@ -385,6 +385,11 @@ class BookFinder {
if (!title) return books if (!title) return books
// Truncate excessively long inputs to prevent ReDoS attacks
const MAX_INPUT_LENGTH = 500
title = title.substring(0, MAX_INPUT_LENGTH)
author = author?.substring(0, MAX_INPUT_LENGTH) || author
const isTitleAsin = isValidASIN(title.toUpperCase()) const isTitleAsin = isValidASIN(title.toUpperCase())
let actualTitleQuery = title let actualTitleQuery = title
@ -402,7 +407,7 @@ class BookFinder {
let authorCandidates = new BookFinder.AuthorCandidates(cleanAuthor, this.audnexus) let authorCandidates = new BookFinder.AuthorCandidates(cleanAuthor, this.audnexus)
// Remove underscores and parentheses with their contents, and replace with a separator // Remove underscores and parentheses with their contents, and replace with a separator
// Use negated character classes to prevent ReDoS vulnerability // Use negated character classes to prevent ReDoS vulnerability (input length validated at entry point)
const cleanTitle = title.replace(/\[[^\]]*\]|\([^)]*\)|{[^}]*}|_/g, ' - ') const cleanTitle = title.replace(/\[[^\]]*\]|\([^)]*\)|{[^}]*}|_/g, ' - ')
// Split title into hypen-separated parts // Split title into hypen-separated parts
const titleParts = cleanTitle.split(/ - | -|- /) const titleParts = cleanTitle.split(/ - | -|- /)
@ -669,7 +674,7 @@ function cleanTitleForCompares(title, keepSubtitle = false) {
let stripped = keepSubtitle ? title : stripSubtitle(title) let stripped = keepSubtitle ? title : stripSubtitle(title)
// Remove text in paranthesis (i.e. "Ender's Game (Ender's Saga)" becomes "Ender's Game") // Remove text in paranthesis (i.e. "Ender's Game (Ender's Saga)" becomes "Ender's Game")
// Use a safe two-pass approach to prevent ReDoS vulnerability // Use negated character class to prevent ReDoS vulnerability (input length validated at entry point)
let cleaned = stripped.replace(/\([^)]*\)/g, '') // Remove parenthetical content let cleaned = stripped.replace(/\([^)]*\)/g, '') // Remove parenthetical content
cleaned = cleaned.replace(/\s+/g, ' ').trim() // Clean up any resulting multiple spaces cleaned = cleaned.replace(/\s+/g, ' ').trim() // Clean up any resulting multiple spaces

View File

@ -286,13 +286,21 @@ module.exports.timestampToSeconds = (timestamp) => {
* *
* @param {any} value - Query parameter value * @param {any} value - Query parameter value
* @param {string} defaultValue - Default value if undefined/null * @param {string} defaultValue - Default value if undefined/null
* @returns {string|null} String value or null if invalid (array) * @param {number} maxLength - Optional maximum length (defaults to 10000 to prevent ReDoS attacks)
* @returns {string|null} String value or null if invalid (array or too long)
*/ */
module.exports.getQueryParamAsString = (value, defaultValue = '') => { module.exports.getQueryParamAsString = (value, defaultValue = '', maxLength = 1000) => {
// Explicitly reject arrays to prevent type confusion // Explicitly reject arrays to prevent type confusion
if (Array.isArray(value)) { if (Array.isArray(value)) {
return null return null
} }
// Return default for undefined/null, otherwise return the value // Return default for undefined/null
return value == null ? defaultValue : value if (value == null) {
return defaultValue
}
// Reject excessively long strings to prevent ReDoS attacks
if (typeof value === 'string' && value.length > maxLength) {
return null
}
return value
} }