rate limiting and api security enhancements
This commit is contained in:
80
lib/validate-input.ts
Normal file
80
lib/validate-input.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
export function sanitizeUrl(url: string): string {
|
||||
return url
|
||||
.trim()
|
||||
.replace(/[<>'"]/g, '') // Remove potential XSS characters
|
||||
.substring(0, 2048) // Limit length
|
||||
}
|
||||
|
||||
export function validateEmail(email: string): boolean {
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
||||
return emailRegex.test(email) && email.length <= 254
|
||||
}
|
||||
|
||||
export function validateUrl(url: string): boolean {
|
||||
try {
|
||||
const sanitized = sanitizeUrl(url)
|
||||
if (!sanitized) return false
|
||||
|
||||
// Add protocol if missing
|
||||
let testUrl = sanitized
|
||||
if (!testUrl.startsWith('http://') && !testUrl.startsWith('https://')) {
|
||||
testUrl = 'https://' + testUrl
|
||||
}
|
||||
|
||||
const urlObj = new URL(testUrl)
|
||||
|
||||
// Check for suspicious patterns
|
||||
const suspiciousPatterns = [
|
||||
/javascript:/i,
|
||||
/data:/i,
|
||||
/vbscript:/i,
|
||||
/file:/i,
|
||||
/about:/i
|
||||
]
|
||||
|
||||
return !suspiciousPatterns.some(pattern => pattern.test(testUrl))
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export function validateRiskLevel(level: any): boolean {
|
||||
const num = parseInt(level)
|
||||
return !isNaN(num) && num >= 1 && num <= 5
|
||||
}
|
||||
|
||||
export function escapeSql(input: string): string {
|
||||
return input.replace(/'/g, "''")
|
||||
}
|
||||
|
||||
export interface ValidationResult {
|
||||
valid: boolean
|
||||
errors: string[]
|
||||
}
|
||||
|
||||
export function validateReportData(data: any): ValidationResult {
|
||||
const errors: string[] = []
|
||||
|
||||
if (!data.source_url || typeof data.source_url !== 'string') {
|
||||
errors.push('Source URL is required')
|
||||
} else if (!validateUrl(data.source_url)) {
|
||||
errors.push('Invalid URL format')
|
||||
}
|
||||
|
||||
if (data.reporter_email && !validateEmail(data.reporter_email)) {
|
||||
errors.push('Invalid email format')
|
||||
}
|
||||
|
||||
if (!data.categories || !Array.isArray(data.categories) || data.categories.length === 0) {
|
||||
errors.push('At least one category is required')
|
||||
}
|
||||
|
||||
if (data.description && typeof data.description === 'string' && data.description.length > 1000) {
|
||||
errors.push('Description too long (max 1000 characters)')
|
||||
}
|
||||
|
||||
return {
|
||||
valid: errors.length === 0,
|
||||
errors
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user