Angular, Bug Bounty, Bug Hunting, JavaScript

#48 Bug Bounty v.2 — Client Side Template Injection (CSTI). Angular

Здравствуйте, дорогие друзья.

За последнее десятилетие разработка интерфейсов быстро изменилась. Большинство современных веб-приложений создаются с использованием javascript-фреймворков, таких как AngularJS, React, Vue и других. Согласно Google, “AngularJS — это интерфейсный веб-фреймворк с открытым исходным кодом на основе JavaScript, который в основном поддерживается Google и сообществом частных лиц и корпораций для решения многих проблем, возникающих при разработке одностраничных приложений”. Большинство людей считают, что эти фреймворки защищены от таких уязвимостей, как XSS, но это не так, просто его использование немного отличается.

Основы Angular

Есть несколько вещей, которые вам необходимо понимать при работе с приложениями Angular. Я кратко остановлюсь на нескольких темах, таких как шаблоны, выражения и области видимости, которые жизненно важны для понимания внедрения шаблонов на стороне клиента в Angular.

Когда вы просматриваете приложение Angular в своем браузере, вы на самом деле просматриваете шаблон. Шаблон — это фрагмент HTML, который сообщает Angular, как отображать компонент в приложении Angular. Основное преимущество шаблонов в том, что вы можете передавать данные, позволяющие вам динамически генерировать HTML-код на основе переданных ему аргументов. Пример шаблона можно найти ниже:

● <h1>Добро пожаловать {{Имя пользователя}}!</h1>

Как вы можете видеть, следующий шаблон создает тег “h1”, который приветствует текущего пользователя. “{{Имя пользователя}}” — это выражение, которое изменяется в зависимости от вашего имени пользователя. Если бы мое имя пользователя было “Timcore”, то приложение отображало бы “Добро пожаловать, Timcore!”. Это позволяет Angular динамически генерировать HTML-страницы вместо использования статических страниц, как показано ниже:

● <h1> Добро пожаловать в Timcore!</h1>

Выражения представляют собой фрагменты кода, подобные Javascript. Как и выражения Javascript, выражения Angular могут содержать литералы, операторы и переменные, как показано ниже:

● 1+1

● A+b

● User.name

● Элементы[индекс]

В отличие от выражений Javascript, которые вычисляются , выражения Angular вычисляются глобально, для объекта Scope. В основном это означает, что если вы попытаетесь вычислить “alert(1)”, это приведет к сбою, поскольку в области видимости нет функции “alert” (если вы ее не определите). Область видимости — это просто объект, и вы можете определить в нем переменные и функции, как показано ниже:

$scope.username = «Timcore»;

$scope.greetings = function() {

return ‘Welcome ‘ + $scope.username + ‘!’;

};

Client Side Template Injection (XSS)

Согласно Google, “ Client Side Template Injection, возникает, когда приложения, использующие платформу шаблонов на стороне клиента, динамически внедряют пользовательский ввод на веб-страницы”. Как вы знаете, Angular — это платформа шаблонов на стороне клиента, и вы можете внедрять пользовательский ввод в эти шаблоны. Это делает Angular идеальной мишенью для уязвимостей такого типа. Если вы не знаете и тестируете XSS на сайте Angular, вы можете попробовать что-то вроде этого:

 Если вы не знаете и тестируете XSS на сайте Angular, вы можете попробовать что-то вроде этого

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

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

Это очень популярный метод предотвращения XSS, и его достаточно для большинства приложений, но Angular отличается от него. В Angular мы можем использовать выражения, в которых не обязательно использовать специальные символы, которые кодируются PHP-функцией “htmlspecialchars”, как показано ниже:

htmlspecialchars

Как вы можете видеть выше, я использую выражение “{{1+1}}”, которое оценивается как “2”. Это очень сильный показатель того, что приложение уязвимо для внедрения шаблона на стороне клиента.

Заставлять приложение складывать два числа вместе не так уж и интересно, но что, если бы мы могли внедрить код javascript. Мы знаем, что не можем просто вставить функцию “alert(1)”, потому что эта функция не определена в объекте scope. За кадром “alert(1)“ превращается в ”$scope.alert(1)». По умолчанию объект scope содержит другой объект с именем “конструктор”, который содержит функцию, также называемую “constructor“. Эта функция может использоваться для динамической генерации и выполнения кода. Это именно то, что нам нужно для выполнения нашей полезной нагрузки XSS, как показано ниже:

● {{constructor.constructor(‘alert(1)’)()}}

{{constructor.constructor('alert(1)')()}}

Как вы можете видеть выше, наше вредоносное выражение Angular было внедрено на страницу, в результате чего приложение динамически генерировало и выполняло нашу полезную нагрузку.

Код вредоносного приложения

Для предотвращения такого рода атак в Angular 1.2 – 1.5 предусмотрена изолированная среда. Позже, в версиях 1.6 и выше, она была удалена, поскольку не обеспечивала реальной безопасности, поскольку было много обходов изолированной среды. Если приложение, которое вы тестируете, находится между версиями 1.2 –1.5 вам нужно будет найти обходной путь sandbox для этой версии, чтобы запустить полезную нагрузку XSS.

Резюме

С появлением новых технологий появляются новые уязвимости. Любая платформа шаблонов на стороне клиента, которая принимает пользовательский ввод, может быть уязвима для внедрения шаблонов на стороне клиента. Эта уязвимость в основном используется для запуска полезной нагрузки XSS. Поскольку angular использует выражения, мы часто можем обойти традиционные средства защиты от XSS, такие как кодирование пользовательского ввода. Большинство разработчиков в значительной степени полагаются на этот метод защиты, который отлично работает в большинстве приложений только не те, которые используют шаблоны и выражения на стороне клиента.

На этом все. Всем хорошего дня!

Цикл статей по Bug Bounty.