mirror of
https://github.com/LightZirconite/Microsoft-Rewards-Bot.git
synced 2026-01-09 00:56:16 +00:00
security: Add Discord mention sanitization to prevent abuse
This commit is contained in:
@@ -22,6 +22,23 @@ function isRateLimited(ip) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Sanitize text to prevent Discord mention abuse
|
||||
function sanitizeDiscordText(text) {
|
||||
if (!text) return ''
|
||||
|
||||
return String(text)
|
||||
// Remove @everyone and @here mentions
|
||||
.replace(/@(everyone|here)/gi, '@\u200b$1')
|
||||
// Remove user mentions <@123456>
|
||||
.replace(/<@!?(\d+)>/g, '@user')
|
||||
// Remove role mentions <@&123456>
|
||||
.replace(/<@&(\d+)>/g, '@role')
|
||||
// Remove channel mentions <#123456>
|
||||
.replace(/<#(\d+)>/g, '#channel')
|
||||
// Limit length
|
||||
.slice(0, 2000)
|
||||
}
|
||||
|
||||
// Vercel serverless handler
|
||||
module.exports = async function handler(req, res) {
|
||||
// CORS headers
|
||||
@@ -59,22 +76,29 @@ module.exports = async function handler(req, res) {
|
||||
return res.status(400).json({ error: 'Invalid payload: missing error field' })
|
||||
}
|
||||
|
||||
// Sanitize all text fields to prevent Discord mention abuse
|
||||
const sanitizedError = sanitizeDiscordText(payload.error)
|
||||
const sanitizedStack = payload.stack ? sanitizeDiscordText(payload.stack) : null
|
||||
const sanitizedVersion = sanitizeDiscordText(payload.context?.version || 'unknown')
|
||||
const sanitizedPlatform = sanitizeDiscordText(payload.context?.platform || 'unknown')
|
||||
const sanitizedNode = sanitizeDiscordText(payload.context?.nodeVersion || 'unknown')
|
||||
|
||||
// Build Discord embed
|
||||
const embed = {
|
||||
title: '🔴 Bot Error Report',
|
||||
description: `\`\`\`\n${String(payload.error).slice(0, 1900)}\n\`\`\``,
|
||||
description: `\`\`\`\n${sanitizedError.slice(0, 1900)}\n\`\`\``,
|
||||
color: 0xdc143c,
|
||||
fields: [
|
||||
{ name: 'Version', value: String(payload.context?.version || 'unknown'), inline: true },
|
||||
{ name: 'Platform', value: String(payload.context?.platform || 'unknown'), inline: true },
|
||||
{ name: 'Node', value: String(payload.context?.nodeVersion || 'unknown'), inline: true }
|
||||
{ name: 'Version', value: sanitizedVersion, inline: true },
|
||||
{ name: 'Platform', value: sanitizedPlatform, inline: true },
|
||||
{ name: 'Node', value: sanitizedNode, inline: true }
|
||||
],
|
||||
timestamp: new Date().toISOString(),
|
||||
footer: { text: 'Community Error Reporting' }
|
||||
}
|
||||
|
||||
if (payload.stack) {
|
||||
const stackLines = String(payload.stack).split('\n').slice(0, 15).join('\n')
|
||||
if (sanitizedStack) {
|
||||
const stackLines = sanitizedStack.split('\n').slice(0, 15).join('\n')
|
||||
embed.fields.push({
|
||||
name: 'Stack Trace',
|
||||
value: `\`\`\`\n${stackLines.slice(0, 1000)}\n\`\`\``,
|
||||
|
||||
@@ -28,7 +28,12 @@ const SANITIZE_PATTERNS: Array<[RegExp, string]> = [
|
||||
[/[A-Za-z]:\\(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*/g, '[PATH_REDACTED]'],
|
||||
[/\/(?:home|Users)\/[^/\s]+(?:\/[^/\s]+)*/g, '[PATH_REDACTED]'],
|
||||
[/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/g, '[IP_REDACTED]'],
|
||||
[/\b[A-Za-z0-9_-]{20,}\b/g, '[TOKEN_REDACTED]']
|
||||
[/\b[A-Za-z0-9_-]{20,}\b/g, '[TOKEN_REDACTED]'],
|
||||
// Discord mention sanitization (prevent @everyone, @here abuse)
|
||||
[/@(everyone|here)/gi, '@\u200b$1'], // Zero-width space breaks mentions
|
||||
[/<@!?(\d+)>/g, '@user'], // User mentions
|
||||
[/<@&(\d+)>/g, '@role'], // Role mentions
|
||||
[/<#(\d+)>/g, '#channel'] // Channel mentions
|
||||
]
|
||||
|
||||
function sanitizeSensitiveText(text: string): string {
|
||||
|
||||
43
test-security.ps1
Normal file
43
test-security.ps1
Normal file
@@ -0,0 +1,43 @@
|
||||
# Test Error Reporting Security
|
||||
|
||||
Write-Host "Testing Discord mention sanitization..." -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
$apiUrl = "https://light-rewards-bot.vercel.app/api/report-error"
|
||||
|
||||
# Test avec des mentions Discord malveillantes
|
||||
$payload = @{
|
||||
error = "Test @everyone @here error with <@123456789> user mention"
|
||||
stack = "at testFunction <@&987654321> role mention`n at main <#555555555> channel"
|
||||
context = @{
|
||||
version = "3.5.6"
|
||||
platform = "win32"
|
||||
arch = "x64"
|
||||
nodeVersion = "v22.0.0"
|
||||
timestamp = [DateTime]::UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ")
|
||||
botMode = "SECURITY_TEST"
|
||||
}
|
||||
} | ConvertTo-Json -Depth 10
|
||||
|
||||
Write-Host "Payload with malicious mentions:" -ForegroundColor Yellow
|
||||
Write-Host $payload -ForegroundColor Gray
|
||||
Write-Host ""
|
||||
|
||||
try {
|
||||
$response = Invoke-RestMethod -Uri $apiUrl -Method Post -Body $payload -ContentType "application/json" -TimeoutSec 15
|
||||
|
||||
Write-Host "SUCCESS - Sanitization applied!" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
Write-Host "Check Discord - mentions should be neutralized:" -ForegroundColor Cyan
|
||||
Write-Host " @everyone -> @<zero-width>everyone" -ForegroundColor Gray
|
||||
Write-Host " @here -> @<zero-width>here" -ForegroundColor Gray
|
||||
Write-Host " <@123456789> -> @user" -ForegroundColor Gray
|
||||
Write-Host " <@&987654321> -> @role" -ForegroundColor Gray
|
||||
Write-Host " <#555555555> -> #channel" -ForegroundColor Gray
|
||||
|
||||
} catch {
|
||||
Write-Host "FAILED!" -ForegroundColor Red
|
||||
Write-Host $_.Exception.Message -ForegroundColor Red
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Reference in New Issue
Block a user