0 added
0 removed
Original
2026-01-01
Modified
2026-02-26
1
<p>Проблемы с безопасностью могут привести к утечке данных пользователей или даже к полному уничтожению сайта. Исследования показывают, что большинство сайтов имеют проблемы с безопасностью и уязвимостью к атакам. Время от времени случаются громкие взломы и утечки данных сотен тысяч и миллионов пользователей.</p>
1
<p>Проблемы с безопасностью могут привести к утечке данных пользователей или даже к полному уничтожению сайта. Исследования показывают, что большинство сайтов имеют проблемы с безопасностью и уязвимостью к атакам. Время от времени случаются громкие взломы и утечки данных сотен тысяч и миллионов пользователей.</p>
2
<p>Безопасность веб-приложений - важная тема, которой мы уделим весь этот урок.</p>
2
<p>Безопасность веб-приложений - важная тема, которой мы уделим весь этот урок.</p>
3
<h2>Главное правило безопасности</h2>
3
<h2>Главное правило безопасности</h2>
4
<p>Оно звучит так:</p>
4
<p>Оно звучит так:</p>
5
<blockquote><p>Никогда не доверяйте пользователям</p>
5
<blockquote><p>Никогда не доверяйте пользователям</p>
6
</blockquote><p>В первую очередь, это правило касается данных, которые пользователи вводят на сайте. Предположим, что у нас есть страница профиля пользователя, где выводится его ник, взятый из адресной строки:</p>
6
</blockquote><p>В первую очередь, это правило касается данных, которые пользователи вводят на сайте. Предположим, что у нас есть страница профиля пользователя, где выводится его ник, взятый из адресной строки:</p>
7
<p>Когда код реализует эту функциональность, он рассчитывает, что в адресе используются только допустимые имена. А теперь попробуем открыть такой адрес:</p>
7
<p>Когда код реализует эту функциональность, он рассчитывает, что в адресе используются только допустимые имена. А теперь попробуем открыть такой адрес:</p>
8
<p>Если мы доверимся данным от пользователей и откроем такой адрес, случится вот это:</p>
8
<p>Если мы доверимся данным от пользователей и откроем такой адрес, случится вот это:</p>
9
<p>В этом адресе<a>закодирован</a>JavaScript-код, который в оригинале выглядит так:</p>
9
<p>В этом адресе<a>закодирован</a>JavaScript-код, который в оригинале выглядит так:</p>
10
<p>Проблема в том, что код не отобразился, но попал в HTML страницы и выполнился. Так произошло, потому что для браузера такой JavaScript-код выглядит как часть страницы.</p>
10
<p>Проблема в том, что код не отобразился, но попал в HTML страницы и выполнился. Так произошло, потому что для браузера такой JavaScript-код выглядит как часть страницы.</p>
11
<p>Если открыть получившийся HTML, то он будет выглядеть так:</p>
11
<p>Если открыть получившийся HTML, то он будет выглядеть так:</p>
12
<p>Именно так происходит XSS-атака (<a>межсайтовый скриптинг</a>). На страницу внедряется вредоносный код, который выполняется в браузере пользователя и отправляет информацию о пользователе на сервер злоумышленника. XSS - это одна из самых распространенных атак. Очень много подобных уязвимостей есть даже на сайтах больших компаний.</p>
12
<p>Именно так происходит XSS-атака (<a>межсайтовый скриптинг</a>). На страницу внедряется вредоносный код, который выполняется в браузере пользователя и отправляет информацию о пользователе на сервер злоумышленника. XSS - это одна из самых распространенных атак. Очень много подобных уязвимостей есть даже на сайтах больших компаний.</p>
13
<p>Специфика подобных атак в том, что вредоносный код может использовать авторизацию пользователя в веб-системе. Так злоумышленник может получить расширенный доступ к системе или логины и пароли пользователей. Если в исходном коде встречается конструкция <текст>, то браузер автоматически считает ее тегом.</p>
13
<p>Специфика подобных атак в том, что вредоносный код может использовать авторизацию пользователя в веб-системе. Так злоумышленник может получить расширенный доступ к системе или логины и пароли пользователей. Если в исходном коде встречается конструкция <текст>, то браузер автоматически считает ее тегом.</p>
14
<p>Вернемся к коду из начала урока:</p>
14
<p>Вернемся к коду из начала урока:</p>
15
<p>Здесь мы выводим слаг без какой-либо предварительной обработки. В таком случае браузер пытается интерпретировать как HTML все, что похоже на HTML. Любой пользователь может внедрить на сайт исполняемый JavaScript-код без нашего ведома. Другими словами, мы проявили доверие к пользовательским данным и создали уязвимость.</p>
15
<p>Здесь мы выводим слаг без какой-либо предварительной обработки. В таком случае браузер пытается интерпретировать как HTML все, что похоже на HTML. Любой пользователь может внедрить на сайт исполняемый JavaScript-код без нашего ведома. Другими словами, мы проявили доверие к пользовательским данным и создали уязвимость.</p>
16
<p>Чтобы закрыть ее, нужно использовать не сами теги, а HTML-эквиваленты символов. Тогда код выше начнет выглядеть так:</p>
16
<p>Чтобы закрыть ее, нужно использовать не сами теги, а HTML-эквиваленты символов. Тогда код выше начнет выглядеть так:</p>
17
<p>Здесь мы заменили:</p>
17
<p>Здесь мы заменили:</p>
18
<ul><li>< на &lt;</li>
18
<ul><li>< на &lt;</li>
19
<li>> на &gt;</li>
19
<li>> на &gt;</li>
20
</ul><p>Это не экранирование, а именно замена спецсимволов на их HTML-эквиваленты. Если открыть браузер, то там мы увидим правильное отображение:</p>
20
</ul><p>Это не экранирование, а именно замена спецсимволов на их HTML-эквиваленты. Если открыть браузер, то там мы увидим правильное отображение:</p>
21
<p>Замена символов на спецсимволы выполняется с помощью<a>commons-text</a>и других специальных библиотек. Один из вариантов выглядит так:</p>
21
<p>Замена символов на спецсимволы выполняется с помощью<a>commons-text</a>и других специальных библиотек. Один из вариантов выглядит так:</p>
22
<p>Метод StringEscapeUtils.escapeHtml4() принимает на вход HTML и заменяет в нем все спецсимволы на их HTML-эквиваленты. Остальные символы остаются без изменений.</p>
22
<p>Метод StringEscapeUtils.escapeHtml4() принимает на вход HTML и заменяет в нем все спецсимволы на их HTML-эквиваленты. Остальные символы остаются без изменений.</p>
23
<p>Через такую обработку нужно пропускать любые данные, которые мы выводим. Исключение составляют лишь ситуации, в которых мы точно знаем, что в данных есть HTML и мы его хотим отобразить. К таким данным могут относиться статьи в блоге, потому что они содержат HTML-часть. Например, так работает блог Хекслета.</p>
23
<p>Через такую обработку нужно пропускать любые данные, которые мы выводим. Исключение составляют лишь ситуации, в которых мы точно знаем, что в данных есть HTML и мы его хотим отобразить. К таким данным могут относиться статьи в блоге, потому что они содержат HTML-часть. Например, так работает блог Хекслета.</p>
24
<p>Но даже внутрь безопасного HTML можно добавить вредоносный JavaScript-код. Вряд ли подобным будут заниматься сотрудники компании, но это могут сделать внешние авторы. Попробуем устранить эту уязвимость. В этом поможет механизм, который вырезает из HTML все <script> и другие опасные теги.</p>
24
<p>Но даже внутрь безопасного HTML можно добавить вредоносный JavaScript-код. Вряд ли подобным будут заниматься сотрудники компании, но это могут сделать внешние авторы. Попробуем устранить эту уязвимость. В этом поможет механизм, который вырезает из HTML все <script> и другие опасные теги.</p>
25
<p>Рассмотрим пример с библиотекой<a>java-html-sanitizer</a>:</p>
25
<p>Рассмотрим пример с библиотекой<a>java-html-sanitizer</a>:</p>
26
<p>Главная проблема этих подходов в том, что об этом нужно постоянно думать. На практике разработчики часто забывают обрабатывать данные, и мы получаем уязвимые сайты. Автоматическое преобразование решило бы эту проблему.</p>
26
<p>Главная проблема этих подходов в том, что об этом нужно постоянно думать. На практике разработчики часто забывают обрабатывать данные, и мы получаем уязвимые сайты. Автоматическое преобразование решило бы эту проблему.</p>
27
<p>Безопасность по умолчанию - это ключевой подход в создании надежных приложений. Один из способов ее обеспечить - использовать JTE или другие качественные шаблонизаторы. Они обрабатывают все данные внутри своих шаблонов и автоматически защищают от XSS-атак.</p>
27
<p>Безопасность по умолчанию - это ключевой подход в создании надежных приложений. Один из способов ее обеспечить - использовать JTE или другие качественные шаблонизаторы. Они обрабатывают все данные внутри своих шаблонов и автоматически защищают от XSS-атак.</p>