Предотвращение XSS в пользовательском вводе URL - PullRequest
0 голосов
/ 04 февраля 2020

У меня есть приложение с полем ввода, которое позволяет пользователю отправить URL-адрес, который будет отображаться в виде ссылки на странице (в SPA, написанном в React).

Я бы хотел Пользователь может отправлять как относительные, так и абсолютные URL-адреса. Например (все перечисленное ниже должно быть точным вводом):

https://stackoverflow.com
stackoverflow.com
http://example.com
localhost:1234
localhost
...

Я пытаюсь предотвратить атаки XSS. Так что, когда пользователь отправляет javascript:alert('hacked') во входном URL-адресе, это не должно работать.

Я думал о том, чтобы сделать это, просто добавив префикс ввода к http:// (если его нет в вход) уже. Таким образом, конечный результат будет http://javascript:alert('hacked')

На стороне сервера я использую ASP. NET Core, и у меня есть модель, которая выглядит примерно так:

using System.ComponentModel.DataAnnotations;

namespace MyApp.Models {
    public class LinkModel {
        [Required]
        public string Title { get; set; }

        [Url]
        public string Url { get; set; }
    }
}

Обратите внимание на атрибут Url, когда я проверяю - http://javascript:alert('hacked'), он "действителен". Что заставляет меня верить, что это нормально, и это не вектор атаки XSS. Я также проверил его в Chrome и Firefox, и он кажется "безопасным".

Так ли это? Я что-то пропустил? Добавляет http:// к входу перед передачей его на сервер, чтобы предотвратить атаки XSS. Пожалуйста, дайте мне знать, если я смогу уточнить.

1 Ответ

1 голос
/ 05 февраля 2020

Если вы принимаете URL-адрес от пользователя, вам нужно знать о нескольких вещах. Вы упомянули вектор javascript:. Существуют также data: URL-адреса (например, data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=, которые выдают предупреждение «Здравствуй».) По моему мнению, вам необходимо проанализировать URL-адрес и убедиться, что схема / протокол находятся в белом списке ( например, https и http). Этот белый список будет зависеть от ваших потребностей. Возможно, вы хотите, чтобы люди могли использовать ссылки mailto: или slack:, но вам необходимо знать о видах атак или злоупотреблений, которые могут иметься в каждом протоколе. Просто добавление http довольно странно и может привести к появлению дыры. Например, http://test@http://example.com может передать имя пользователя http и пароль //test хосту example.com с использованием basi c HTTP-аутентификация . Я сомневаюсь, что это будет работать в современных браузерах, но это возможно.

Для чего бы это ни стоило, http://javascript:alert(1) никогда не следует интерпретировать как javascript. Я предполагаю, что браузер интерпретирует javascript как хост (как stackoverflow.com является хостом). Но если в сети есть компьютер с именем javascript, это приведет к появлению страницы с ошибкой. Если вы правильно реализуете белый список, вам не нужно беспокоиться о подобных вещах.

Далее, вам нужно убедиться, что вы правильно экранируете / кодируете URL при его отображении. Примерно так: <a href="escape(url)">name</a> вам нужно убедиться, что пользователь не может поместить " в свой URL и выйти из атрибута html. Рассмотрим что-то вроде system.web.security.antixss.antixssencoder.urlencode .

Вам также необходимо знать, что пользователь все еще может ссылаться на действительный сайт https, который является вредоносным. Примером может служить фишинговый сайт, похожий на ваш, или, может быть, просто какой-то сайт с загрузками вредоносных программ. Многие сайты создают всплывающее окно с предупреждением о том, что пользователь покидает сайт. Это может быть то, что вы хотите сделать, но это действительно зависит. Я не уверен, насколько они полезны, но если вы беспокоитесь о том, что пользователи могут быть обмануты, стоит подумать.

Наконец, пользователь может ссылаться на существующую страницу на вашем сайте и все равно быть злонамеренным - например, CSRF . Вы должны быть осторожны, чтобы не допустить такого рода страниц. Представьте, что кто-то ссылается на https://example.com/account/delete, а затем ничего не подозревающий пользователь удаляет свою учетную запись.

edit: лично я не стал бы позволять пользователям вводить URL-адреса без схемы, так как это означает, что вы должны будете принять http. Я бы подтвердил на стороне клиента, что это URL (включая протокол), а затем проверил, находится ли он в белом списке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...