Санитизация пользовательского ввода

Санитизация пользовательского ввода — это процесс очистки данных, введённых пользователем, для предотвращения потенциально опасных действий, таких как XSS-атаки, внедрение SQL-кода или нарушение логики приложения. В JavaScript санитизация особенно актуальна при работе с DOM, AJAX-запросами и динамическим контентом.

Ключевые задачи санитизации:

  • Удаление или экранирование HTML-тегов и скриптов.
  • Ограничение формата и длины ввода.
  • Преобразование специальных символов в безопасные аналоги.
  • Валидация типов данных (числа, строки, email, URL и т.д.).

Экранирование HTML

Для предотвращения XSS важно преобразовывать специальные символы HTML в безопасные сущности. Наиболее часто экранируемыми символами являются:

Символ Экранирование
& &
< <
> >

Пример функции экранирования в Jav * aScript:

function escapeHTML(str) {
  return str.replace(/[&<>"']/g, function(match) {
    const escape = {
      '&': '&amp;',
      '<': '&lt;',
      '>': '&gt;',
      '"': '&quot;',
      "'": '&#39;'
    };
    return escape[match];
  });
}

const userInput = '<script>alert("XSS")</script>';
const safeInput = escapeHTML(userInput);
console.log(safeInput); // &lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;

Валидация типов данных

Важная часть санитизации — проверка типа данных. Например, если ожидается число, входные данные нужно явно преобразовать и проверить:

function sanitizeNumber(input) {
  const num = Number(input);
  if (isNaN(num)) throw new Error('Некорректное число');
  return num;
}

const userAge = sanitizeNumber('25'); // 25

Для строк можно использовать регулярные выражения для фильтрации нежелательных символов:

function sanitizeString(input) {
  return input.replace(/[^a-zA-Z0-9\s.,!?-]/g, '');
}

const cleanString = sanitizeString("Привет! <script>alert('XSS')</script>");
// Результат: "Привет! alertXSS"

Санитизация email и URL

Для проверки email применяются стандартные регулярные выражения:

function sanitizeEmail(email) {
  const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  if (!regex.test(email)) throw new Error('Некорректный email');
  return email;
}

Для URL проверка включает протокол и домен:

function sanitizeURL(url) {
  try {
    const parsed = new URL(url);
    return parsed.href;
  } catch {
    throw new Error('Некорректный URL');
  }
}

Использование готовых библиотек

Для сложных случаев рекомендуется использовать проверенные библиотеки:

  • DOMPurify — надёжная библиотека для очистки HTML от скриптов.
  • validator.js — набор функций для проверки и очистки строк, email, URL и чисел.

Пример использования DOMPurify:

import DOMPurify from 'dompurify';

const unsafeHTML = '<img src=x oner ror=alert(1)//>';
const safeHTML = DOMPurify.sanitize(unsafeHTML);
document.getElementById('content').innerHTML = safeHTML;

Ограничение длины и формата ввода

Санитизация включает контроль размера данных, чтобы избежать атак типа buffer overflow или излишней нагрузки на сервер:

function truncateInput(input, maxLength) {
  return input.length > maxLength ? input.slice(0, maxLength) : input;
}

const safeText = truncateInput("Очень длинный текст...", 50);

Санитизация при работе с JSON и API

При передаче данных на сервер важно проверять типы и значения:

function sanitizeJSON(data, schema) {
  const sanitized = {};
  for (const key in schema) {
    if (schema[key] === 'string') {
      sanitized[key] = sanitizeString(data[key] || '');
    } else if (schema[key] === 'number') {
      sanitized[key] = sanitizeNumber(data[key] || 0);
    }
  }
  return sanitized;
}

const userData = { name: "<script>", age: "30" };
const schema = { name: 'string', age: 'number' };
const cleanData = sanitizeJSON(userData, schema);

Рекомендации по интеграции санитизации

  • Всегда очищать данные до их вставки в DOM.
  • Проверять и фильтровать данные как на клиенте, так и на сервере.
  • Использовать регулярные выражения и библиотеки только для известных форматов.
  • Экранировать все специальные символы, особенно при работе с HTML и SQL.
  • Ограничивать длину и формат ввода для предотвращения потенциальных уязвимостей.

Систематическое применение этих методов минимизирует риск внедрения вредоносного кода и сохраняет целостность приложения.