При разработке приложений на Inferno важно обеспечить безопасность и корректность данных, поступающих от пользователей. Санитизация пользовательского ввода предотвращает XSS-атаки, SQL-инъекции, повреждение состояния приложения и другие потенциальные уязвимости. Inferno, как высокопроизводительный UI-фреймворк, предоставляет инструменты для безопасного рендеринга, но ответственность за очистку данных лежит на разработчике.
Избегание прямого использования
dangerouslySetInnerHTML
dangerouslySetInnerHTML позволяет вставлять HTML-контент
напрямую в DOM. Любой пользовательский ввод, переданный без фильтрации,
становится потенциальной угрозой. Даже если требуется вставка HTML,
нужно предварительно выполнять строгую санитизацию.
import { render } from 'inferno';
import sanitizeHtml from 'sanitize-html';
const rawInput = '<img src=x oner ror=alert(1) />';
const cleanInput = sanitizeHtml(rawInput);
render(<div dangerouslySetInnerHTML={{ __html: cleanInput }} />, document.getElementById('app'));Использование JSX-выражений вместо HTML-строк Inferno автоматически экранирует все строки, передаваемые как содержимое элементов:
const userInput = '<script>alert("xss")</script>';
render(<div>{userInput}</div>, document.getElementById('app'));
В этом примере браузер отобразит строку как текст, а не выполнит её как скрипт.
Для очистки и фильтрации пользовательского ввода применяются следующие подходы:
Библиотеки для очистки HTML
sanitize-html — позволяет настраивать допустимые теги и
атрибуты.DOMPurify — обеспечивает строгую фильтрацию HTML и
работает в браузере и на сервере.Регулярные выражения для фильтрации строк Для простых случаев можно использовать регулярные выражения для удаления потенциально опасных символов:
const sanitizeInput = (input) => input.replace(/<[^>]*>?/gm, '');
const safeString = sanitizeInput(userInput);Серверная валидация и фильтрация Даже если фронтенд выполняет санитизацию, сервер должен повторять проверку данных. Это исключает обход защитных механизмов через прямые запросы к API.
В Inferno компоненты могут получать пользовательский ввод через пропсы и состояния. Важно фильтровать данные перед их установкой в состояние:
import { Component } from 'inferno';
class Comment extends Component {
constructor(props) {
super(props);
this.state = { text: '' };
}
handleChange = (e) => {
const sanitized = e.target.value.replace(/<[^>]*>?/gm, '');
this.setState({ text: sanitized });
};
render() {
return <input value={this.state.text} onIn put={this.handleChange} />;
}
}
Здесь ввод пользователя фильтруется на лету, что предотвращает внесение опасного контента в состояние компонента.
Динамические значения для атрибутов, таких как href или
src, требуют дополнительной проверки. Опасны протоколы
jav * ascript:, data: и нестандартные схемы.
const safeUrl = (url) => {
if (/^(https?:)?\/\//.test(url)) return url;
return '#';
};
render(<a href={safeUrl(userInput)}>Ссылка</a>, document.getElementById('app'));
Эти принципы позволяют создавать производительные и безопасные приложения на Inferno, минимизируя риск атак через пользовательский ввод.