diff --git a/api/routes/erase.js b/api/routes/erase.js
index 02d46cc..afbf95c 100644
--- a/api/routes/erase.js
+++ b/api/routes/erase.js
@@ -5,6 +5,15 @@ const { sendErasureMail, PROVIDER_DATA } = require('../services/mailer');
const ALLOWED_PROVIDERS = new Set(Object.keys(PROVIDER_DATA));
+/* Elimina CRLF y chars de control — previene header injection en el cuerpo del email */
+function sanitizeField(raw, maxLen) {
+ return String(raw || '')
+ .replace(/[\r\n\t\x00-\x1F\x7F]/g, ' ') // CRLF → espacio, no rompe el texto
+ .replace(/\s{2,}/g, ' ') // colapsa espacios múltiples
+ .trim()
+ .slice(0, maxLen);
+}
+
module.exports = async (req, res) => {
try {
const { provider, email,
@@ -26,11 +35,11 @@ module.exports = async (req, res) => {
return res.status(400).json({ error: 'Email inválido' });
}
- // Límites de longitud en campos opcionales (defensa en profundidad)
- const nickname = String(rawNick || '').slice(0, 100).trim();
- const phone = String(rawPhone || '').slice(0, 30).trim();
- const address = String(rawAddr || '').slice(0, 300).trim();
- const extra = String(rawExtra || '').slice(0, 500).trim();
+ // Sanitizar campos opcionales: longitud + strip CRLF (header injection)
+ const nickname = sanitizeField(rawNick, 100);
+ const phone = sanitizeField(rawPhone, 30);
+ const address = sanitizeField(rawAddr, 300);
+ const extra = sanitizeField(rawExtra, 500);
// Hash irreversible para referencia (auditoría sin almacenar PII)
const hash = crypto
diff --git a/public/egosurfing.html b/public/egosurfing.html
index 1c395b0..c558f17 100644
--- a/public/egosurfing.html
+++ b/public/egosurfing.html
@@ -809,7 +809,7 @@ function renderResults(results) {
Ver página
- ${rtbfUrl ? `
+ ${rtbfUrl ? `
Solicitar eliminación
` : ''}