Разделы портала

Онлайн-тренинги

.
XML-инъекция для начинающих
05.08.2021 00:00

Автор: Хан Тоан Лим (Han Toan Lim)
Оригинал статьи
Перевод: Ольга Алифанова

Допустим, я отправляю своего ребенка в магазин со списком покупок. Затем я забираю все купленное и сдачу. Как мне узнать, что все прошло как следует?

Если на какой-то предмет была скидка, я получу назад больше денег. Или же мою карту лояльности задействовали ради бесплатных конфет.

Наилучшим способом будет посмотреть на чек, на деньги и на купленные предметы. В этом вся суть аудита.

Основы XML

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

Представим себе воображаемую небольшую компанию.

Серая Пицца Паста – итальянский ресторан, перерабатывающий пиццы в пасту. Чтобы выделиться, паста у нас серая по какой-то причине. Сначала это было шуткой, а теперь это бизнес.

Большая порция пасты стоит три евро. Что такое порция? Если это ложка, можно ли положить сверху побольше пасты? Каким инструментом это измерить? Как определить правильное количество пасты?

Мистер Грей хочет выложить ряд пасты на прилавок, но где у него будет начальная и конечная точка? Как их обозначить?

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

Согласно Википедии, XML – eXtensible Markup Language – это язык разметки, определяющий набор правил кодирования документов в формате, который может прочитать как человек, так и машина.

В XML горку пасты можно описать так:

<heap>pasta</heap>

<heap> - это открывающий тег. Можно назвать его стартовой точкой.

  • Он начинается со знака < - меньше, чем.
  • Heap – это описание того, что собой представляет тег.
  • > - знак "больше, чем" – завершает тег.

</heap> - это закрывающий тег. Можно назвать его конечной точкой. Он выглядит почти так же, как и открывающий, но перед heap добавлен прямой слэш /.

Итак, все, что между <heap> и </heap>, содержится в горке. Это называется элементом XML. <heap>pasta</heap> - это горка пасты.

Любое ли имя тега допустимо?

На самом деле нет, имена должны быть определены XML-схемой. В большинстве случаев XML-файл можно прочитать, используя здравый смысл или знания в доменной области. Это знания о продукте или сервисе, о которых идет речь.

Очень важно указывать закрывающий тег.

<heap>pasta chocolate milk

будет сконвертировано в горку пасты, шоколада и молока. Даже я не могу себе это представить.

Возможно, мистер Грей имел в виду горку пасты, горку шоколада, и кружку молока.

Это будет выглядеть так:

<heap>pasta</heap>
<heap>chocolate</heap>
<cup>milk</cup>

Это может представить даже ребенок.

Столкновение с XML

История ниже основана на реальных событиях. Все отсылки к реальным компаниям изменены.

В ходе регрессионного теста меня попросили просмотреть лог аудита. Я открыл VIP Cinema и купил билет на "Монстры навсегда", чипсы и колу.

Мой следующий шаг – это просмотр лога аудита. Я открыл файл и увидел английский язык, это было легко понять. Там был мой билет в кино, моя закуска и мой напиток.

Я с любопытством проскроллил ниже. Вторая часть файла содержала XML – расширяемый язык разметки. И тут я превратился в огромный вопросительный знак.

<item>
<qty>1</qty>
<name>potato chips</name>
<remarks></remarks>
</item>
<item>
<qty>1</qty>
<name>cola</name>
<remarks></remarks>
</item>

Я, как минимум, распознал купленное мной. Я заказал 1 колу. Количество – 1, то есть qty – это количество. То есть количество показано между <qty> и </qty>.

Теперь у меня был аудит-лог, где первая часть была на английском, а вторая на XML. Выглядело это так, как будто XML трансформирован в английский язык для аудита. Если аудитор прочитает это, он поймет, что произошло.

Я решил протестировать свое предположение о переводе XML на нормальный английский.

Информация о вложенности XML-элементов

С горками пасты есть проблема. Это здорово выглядит, но люди хотели бы получить коробку или пакет с пастой. Минималист мистер Грей решил паковать пасту в серые бумажные коробки. Серый цвет был выбран по очевидным причинам.

<box>pasta</box>

Это довольно загадочный XML-код. Что содержит коробка? Каков вес ее содержимого? Каковы ингредиенты?

Это можно записать так:

<box>pasta</box>
<weight>230 gram</weight>
<ingredients>flour, salt, water, cheese, tomato sauce, pepperoni</ingredients>

Я, взглянув на полку, ожидаю увидеть там коробку, вес и ингредиенты. Однако на полке лежит только коробка.

В XML можно вкладывать элементы в другие элементы. К примеру, на коробке указано название продукта, вес и ингредиенты.

<box>

<name>pasta</name>

<weight>230 gram</weight>

<ingredients>flour, salt, water, cheese, tomato sauce, pepperoni</ingredients>

</box>

SQL-инъекция

Проснулся мой внутренний исследовательский тестировщик. Я посмотрел на код и увидел там <remarks>. Ремарки используются для дополнительной информации, содержащей комментарии пользователя.

Я хотел получить свою Колу в специальном стакане, написав "стакан с синим мохнатым принтом" в примечаниях.

SQL – Structured Query Language – это язык, который часто используется для изменения данных. Мой заказ будет выглядеть как "Компьютер, добавь 1 билет на Монстры Навсегда, 1 чипсы, и 1 колу к моему заказу".

Ремарки также могут использовать хакеры, чтобы делать что-то нехорошее. Я вспомнил об SQL-инъекции. Хакер может добавить в примечания такой комментарий:

"Компьютер, добавь 1 лимонад к моему заказу". По прибытии в кинотеатр я получу бесплатный лимонад. Это суть SQL-инъекции.

SQL – это такой же язык, как и XML, поэтому инъекция должна быть возможна и в XML.

Информация о добавлении кода

<item>
<qty>1</qty>
<name>cola</name>
<remarks></remarks>
</item>

Если бы я ввел "XML code" в поле примечаний, код стал бы выглядеть так:

<item>
<qty>1</qty>
<name>cola</name>
<remarks>XML code</remarks>
</item>

Теперь я использовал известный мне XML-код для добавления в поле примечаний. Этот кусочек кода имеет правильную структуру.

<item>
<qty>2</qty>
<name>potato chips</name>
<remarks></remarks>
</item>

Если я добавлю XML-код для покупки чипсов в примечания для колы, то получу что-то вроде этого:

<item>
<qty>1</qty>
<name>cola</name>
<remarks>
<item>
<qty>2</qty>
<name>potato chips</name>
<remarks></remarks>
</item>
</remarks>
</item>

Программа будет пытаться сопоставить открывающие теги с закрывающими.

Если найден закрывающий тег, его сопоставят с соответствующим открывающим тегом перед ним. Простой пример:

<qty>1</qty>

</qty> - это закрывающий тег. Первый открывающий тег – это <qty>. qty или количество – это 1, потому что 1 находится между <qty> и </qty>.

Настало время сопоставить <item> правильному </item>.

<item>
<qty>1</qty>
<name>cola</name>
<remarks>
<item>
<qty>2</qty>
<name>potato chips</name>
<remarks></remarks>
</item>
</remarks>
</item>

В коде два элемента: элемент о коле и элемент о чипсах. Попробую объяснить, что это значит: у 1 колы есть примечания, содержащие 2 порции чипсов. Выглядит многообещающе. Посмотрим внимательнее на раздел ремарок в элементе колы:

<remarks>
<item>
<qty>2</qty>
<name>potato chips</name>
<remarks></remarks>
</item>
</remarks>

Возможно ли, что элемент ремарок содержит вложенный элемент предмета? Скорее всего, нет. В большинстве случаев это воспримется как плохой синтаксис, и XML-код не будет обработан. Поле примечаний должно содержать текст, а не вложенные элементы XML.

О создании правильного кода

Эту часть статьи я добавил для иллюстрации хода моих мыслей – в ходе теста это заняло несколько секунд. Мне понадобилось время, чтобы разобраться, как писать XML-код.

Для своего теста я хотел изменить XML-код. Мне нужно было получить вот такой код в логе

<item>
<qty>1</qty>
<name>cola</name>
<remarks>
</remarks>
</item>
<item>
<qty>1</qty>
<name>lemonade</name>
<remarks>
</remarks>
</item>

Первая попытка

Поле примечаний может содержать текст. Первая строчка в поле примечаний будет </remarks>. Я отметил это строкой:

<!—Начало добавленного кода -->

Это XML-комментарий с текстом "Начало добавленного кода". Программа, обрабатывающая XML-код, будет игнорировать эту строчку. Комментарии очень полезны разработчикам и тестировщикам.

<item>
<qty>1</qty>
<name>cola</name>
<remarks>
<!—Начало добавленного кода -->
</remarks>
</item>
<item>
<qty>1</qty>
<name>lemonade</name>
<remarks>
</remarks>
</item>

Настало время проб и ошибок. Мне нужно было выбрать кусочек кода – я выбрал строчку перед начальным тегом remarks. Я отметил ее строкой <!—Конец добавленного кода -->. Это тоже XML-комментарий.

<item>
<qty>1</qty>
<name>cola</name>
<remarks>
<!—Начало добавленного кода -->
</remarks>
</item>
<item>
<qty>1</qty>
<name>lemonade</name>
<!—Конец добавленного кода -->
<remarks>
</remarks>
</item>

Я хотел добавить в поле примечаний вот такой текст:

<!—Начало добавленного кода -->
</remarks>
</item>
<item>
<qty>1</qty>
<name>lemonade</name>
<!—Конец добавленного кода -->
</item>

В свою очередь это должно привести вот к такому коду:

<item>
<qty>1</qty>
<name>cola</name>
<remarks>
<!—Начало добавленного кода -->
</remarks>
</item>
<item>
<qty>1</qty>
<name>lemonade</name>
<!—Конец добавленного кода -->
<remarks>
</remarks>
</item>

Но сгенерированный код получился другим:

<item>
<qty>1</qty>
<name>cola</name>
<remarks>
<!—Начало добавленного кода -->
</remarks>
</item>
<item>
<qty>1</qty>
<name>lemonade</name>
<!—Конец добавленного кода -->
</remarks>
</item>

Я заметил, что <remarks> под строкой <!—Конец добавленного кода --> не содержится в сгенерированном коде. Я насчитал только 1 тег <remarks> вместо двух таких открывающих тегов.

На этот момент в коде была только одна правильная пара <remarks> - </remarks>. Это неправильно. В хорошем XML-коде количество открывающих тегов равно количеству закрывающих.

Вторая попытка

Дальнейшие пробы и ошибки. Я выбрал строку до строки с закрывающим тегом remarks.

<item>
<qty>1</qty>
<name>cola</name>
<remarks>
<!—Начало добавленного кода -->
</remarks>
</item>
<item>
<qty>1</qty>
<name>lemonade</name>
<remarks>
<!—Конец добавленного кода -->
</remarks>
</item>

Простой способ определить правильность XML-кода – это подсчитать, содержит ли он равное количество закрывающих и открывающих тегов.

<!—Начало добавленного кода -->
</remarks>
</item>
<item>
<qty>1</qty>
<name>lemonade</name>
<remarks>
<!—Конец добавленного кода -->

Если у вас есть время, то существуют и другие способы получить код.

XML-инъекция в действии

Из-за сцены пустыни в "Монстры Навсегда" посетители часто заказывают дополнительные напитки. У меня был верный XML-код для этого.

<!—Начало добавленного кода -->
</remarks>
</item>
<item>
<qty>1</qty>
<name>lemonade</name>
<remarks>
<!—Конец добавленного кода -->

Чтобы продемонстрировать использование этого кода, я добавил XML-комментарий с "Начало добавленного кода" и <!—Конец добавленного кода -->.

Я поместил этот код в поле примечаний моего заказа колы, и приложение выдало вот такой XML-код.

<item>
<qty>1</qty>
<name>cola</name>
<remarks>
<!—Начало добавленного кода -->
</remarks>
</item>
<item>
<qty>1</qty>
<name>lemonade</name>
<remarks>
<!—Начало добавленного кода -->
</remarks>
</item>

Эта XML-инъекция привела к вот такому тексту на английском:

1 кола

1 лимонад

Я был очень доволен своим успехом в манипуляции данными с первой попытки. По цене 1 колы я получил колу и лимонад, согласно логу аудита. Два напитка по цене одного.

В кино я получу только колу. Это единственный напиток в моем заказе. Упомянутый в примечаниях лимонад не включен в заказ, но находится в логе аудита.

В чем проблема?

В этом случае кто-то получит лимонад бесплатно. Напиток уже включен в лог.

Что произойдет, если в заказ добавить дорогую коллекционную золотую кружку? Кто-то унесет ее домой бесплатно. Одна кружка по цене ничего!

Как предотвратить XML-инъекцию

Как у тестировщика, у меня есть два решения.

  1. Ограничить количество символов в поле примечаний. В этом случае опасный XML-код обрежется или вообще будет предотвращен.
  2. Провести тренинг для сотрудников кинотеатра. Если они обнаружат странный текст в поле примечаний – то с шансами это атака хакера.

Разработчики высказались строже: запретить использование символов < и > в поле примечаний.

Заключение

Данные – это не то, как они хранятся, а то, как они используются. XML-инъекция добавляет XML-код, дающий системе неверную информацию. Это можно использовать во вред.

Обсудить в форуме