# Стенограмма дня 2: подробная редактированная версия

> **Назначение:** материал для самостоятельного изучения и подготовки занятий.
>
> **Дата:** 12 августа 2026 года.
>
> **Программа:** АО «Лаборатория Касперского» — «Образовательная лаборатория Kaspersky Academy | Безопасность приложений».
>
> Это авторская нормализованная редакция автоматической расшифровки: устная речь приведена к читаемому виду, но смысл, порядок тем, вопросы и обсуждения сохранены. Документ не является дословным стенографическим протоколом.
>
> Роли говорящих (**Ведущий**, **Спикер**, **Участник**) восстановлены по содержанию: исходная расшифровка не различала голоса. Личные имена намеренно не приводятся. Временные метки локальны для каждого фрагмента и в новом фрагменте начинаются заново.
>
> Метка *[неразборчиво]* и пометки в квадратных скобках сохранены там, где содержание нельзя восстановить уверенно. Технические приёмы изложены на уровне механики и мер защиты, без пошаговых боевых инструкций.

## Фрагмент 1

*Веб-часть второго дня: OWASP A07–A10, лабораторные работы и открытое обсуждение ИИ-инструментов.*

### 00:00:00–00:01:39 — Критерии оценки лабораторной работы и шаблон преподавателя

**Ведущий.** Цель этого блока — сформулировать критерии для оценки. То есть на что вы будете в первую очередь обращать внимание при проверке задания, которое выполняет студент. Далее критерий можно немного детализировать и каждому критерию назначить какой-то [вес]. Чем выше этот критерий расположен относительно образовательной цели, тем выше должен быть и его [вес].

**Ведущий.** Заключительный пункт шаблона направлен на то, чтобы студенты не воспринимали лабораторную работу просто как учебное задание. Чтобы у них частично происходил перенос учебной ситуации в реальные задачи. Здесь важно просто для себя, как для преподавателя, отметить, как вы сможете объяснить студенту, где в реальной работе встречаются те задачи, которые встречаются в данной лабораторной работе.

**Ведущий.** И на что следует обращать внимание. Надеюсь, что сейчас работа с шаблоном стала более понятной. Будет отлично, если в рамках лабораторных блоков у вас получится выполнять эти две задачи параллельно: заполнять шаблон и решать саму лабораторную работу.

**Ведущий.** Когда я передам слово коллеге, он продолжит рассказывать дальше, и также будут лабораторные работы.

**Ведущий.** Там была папочка — подразумевается, что туда нужно что-то положить.

### 00:01:40–00:02:53 — Приветствие и план второго дня

**Спикер.** Всем ещё раз добрый день, кого не видел. Давайте: сегодня у нас будет финальная презентация по мобильной части `[возможно: MASVS]`, а прежде мы перейдём уже к веб-приложениям — их будем тоже разбирать. Соответственно, сегодня будем обсуждать четыре финальных пункта.

**Спикер.** Ну, давайте прежде всего начнём с обсуждения. Может, у кого-то появились вопросы с предыдущего дня и мысли по поводу тренинга? Что-то оказалось непонятно? Хорошо бы это спросить.

**Спикер.** Если нет, то давайте продолжать в таком случае.

**Спикер.** Формат, я думаю, все помните: мы разбираем каждую категорию на примерах.

### 00:02:54–00:04:56 — `A07`: ошибки идентификации и аутентификации

**Спикер.** Угроза, которую сообщество OWASP проранжировало [седьмым] номером, называется «ошибки идентификации и аутентификации». Это, опять же, свободный перевод. Категория подсказывает нам любого рода неправильное, некорректное поведение приложения в процессах авторизации, идентификации, аутентификации и так далее. То есть весь этот пункт можно охарактеризовать так: он покрывает любые процессы, связанные с тем, как пользователь входит в приложение…

**Спикер.** …и выходит из него. То есть восстанавливает пароли, задаёт новые пароли, меняет пароли, подтверждает доступы. Также сюда входит разного рода управление токенами.

**Спикер.** Работа с сессиями. Немного про `[возможно: CSRF]`. Соответственно, это такой общий пункт про идентификацию. Поверхность атаки — то, что мы с вами сейчас обозначили: вход, регистрация и так далее, сброс пароля, функции вроде «запомнить меня», добавление доверенного устройства. Токены — опять же, JSON Web Token (`JWT`), который мы уже разбирали на лабораторной работе.

### 00:04:57–00:06:40 — Некорректные допущения разработчика: пароли, веб-интерфейс и API

**Спикер.** Все вещи, связанные с некорректной обработкой допущений. Какие допущения у нас есть? Разработчики предполагают, что пользователи задают уникальные пароли; что веб-интерфейс, веб-приложение не даёт сделать перебор. Например, логин и пароль. Что есть в веб-интерфейсе? Может быть такая ситуация, что при некорректной попытке ввода пароля вам отвечают: «Подождите десять секунд и попробуйте снова».

**Спикер.** А в API, например, никаких лимитов может не быть, и тогда перебор можно сделать без веб-интерфейса.

**Спикер.** Ну и управление сессией. Опять же допущение: сессия защищённая, она выдаёт какой-то безопасный и неподбираемый идентификатор сессии, который вряд ли можно подобрать напрямую. Но при этом мы не учитываем особенности того, как мы этой сессией управляем. Но об этом чуть позже.

### 00:06:41–00:08:36 — Credential stuffing: утечки баз и повторное использование паролей

**Спикер.** Чем на самом деле пользуются атакующие? Они пытаются угонять аккаунты и забирать пользовательские сессии. Вы знаете, что периодически происходят так называемые сливы персональных данных. Они включают в себя пары «логин — пароль», и эти пары обычно продаются где-нибудь в интернете. Их покупают, перепродают. Это в целом такой бизнес, который, к сожалению, существует. И атакующие работают с ним примерно так: забирают эти базы…

**Спикер.** …и, как правило, в этих базах есть электронная почта, какой-нибудь логин и какой-нибудь пароль.

**Спикер.** Пользователи, как правило, в большинстве своём не используют парольные менеджеры и не генерируют отдельные пароли для разных сайтов. У них один пароль на всё — то есть один логин и один пароль. Соответственно, эти пары берут и начинают пробивать ими широкий круг сайтов. И это не редкая ситуация, когда что-то срабатывает.

### 00:08:37–00:11:17 — Парольная политика и многофакторная аутентификация

**Спикер.** Что мы как разработчики можем с этим сделать? В нашем приложении мы, конечно, можем порекомендовать пользователям: пожалуйста, используйте стойкие пароли и так далее. Более эффективно сделать программное ограничение: ваш пароль должен быть [определённой длины], должна быть цифра, разные регистры. Я говорю условно.

**Спикер.** И больше всего на возможность подбора влияет именно [длина], а не те символы, которые есть в пароле. Хотя это, конечно, второй приоритет.

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

**Спикер.** Что она включает в себя? Есть три фактора, вам они известны, я думаю: что-то, что вы знаете; что-то, что вы имеете; и что-то, чем вы являетесь. Пароль — это фактор знания: вы знаете пароль. То, что вы имеете, — это любого рода физическое устройство, с помощью которого, имея это устройство, вы можете…

**Спикер.** …подтвердить, что вы являетесь собой. Что это может быть? Аппаратные токены — это подтверждение. Сайт показывает: пожалуйста, вот цифра, введите ту же самую цифру. Push-уведомление, SMS-подтверждение, подтверждение звонком — это второй фактор. Третий фактор — то, чем вы являетесь; как правило, сейчас у нас это тоже есть.

### 00:11:18–00:13:13 — Биометрия как фактор и где хранятся биометрические данные

**Спикер.** Больше это встречается в мобильных приложениях. Но мобильное приложение всё-таки позиционируется скорее как фактор владения: мы имеем наш девайс и можем через него авторизоваться, в том числе биометрией — прикладываем палец, сканируем лицо на девайсе.

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

**Спикер.** Если говорить про биометрию в чистом виде, то это именно подтверждение по биометрическому признаку: по радужной оболочке глаза, например, по отпечатку пальца или по лицу. И там, в том числе, бывает так, что какой-то ресурс хранит биометрические данные непосредственно у себя. А вообще многофакторная аутентификация — это самый основной…

**Спикер.** …способ решить главную проблему и обезопасить [учётные записи].

### 00:13:14–00:14:42 — Ограничение частоты запросов и другие дополнительные меры

**Спикер.** Если говорить про дополнительные вещи, к ним можно отнести ограничение частоты запросов. Определили лимит — столько-то запросов разрешаем; затем период охлаждения, и так далее. Это усложняет перебор.

**Спикер.** Если это привязывается к IP-адресу, к устройству, к `User-Agent` или к каким-то ещё признакам, например к методу запроса, то это тоже может в целом ограничить подобный процесс.

**Спикер.** Ну и для совсем серьёзных случаев — парольный менеджер: приложение тогда проверяет, не задают ли пароль, который уже встречался раньше. [Формулировка распознана не полностью.]

**Спикер.** Ну вот, соответственно, это один из вариантов. Пойдём дальше.

### 00:14:43–00:16:57 — Полный перебор, password spraying и словари паролей

**Спикер.** Password spraying — тоже разновидность перебора, на самом деле, но более [точечная]. Как выглядит перебор: это последовательный, полный перебор. Попытка подобрать пароль может занимать очень большое количество времени, особенно если пароль стойкий. Поэтому им практически не пользуются. Это крайне сложно, и ресурсов у большинства не хватает.

**Спикер.** [Фрагмент о том, кому по силам полный перебор, распознан не полностью.] Есть механизмы [ускорения]. Если говорить про password spraying…

**Спикер.** …то берут самые популярные пароли на каком-то ресурсе. В этом случае, допустим, когда есть список учётных записей или адресов электронной почты, а паролей нет, берут условно несколько самых распространённых паролей и смотрят по всем аккаунтам. Бывают ситуации, когда многие пользователи берут слабые пароли.

**Спикер.** Такие пароли наиболее часто используются в интернете, и их множество. Пожалуйста, посмотрите — поищите словари, word lists, для перебора…

**Спикер.** …они есть на любой вкус, вплоть до подборок самых популярных паролей.

**Спикер.** Поэтому да, это тоже распространённая вещь. Здесь защита, на самом деле, та же самая.

### 00:16:58–00:19:36 — Сброс пароля и восстановление доступа

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

**Спикер.** Скажем, самое плохое начинается с того, что для сброса пароля нам, как правило, предоставляется какой-то токен. А сервер, допустим, этот токен не особо перепроверяет: проверяет только его наличие, не сравнивает его с ожидаемым и так далее. Второе — токен…

**Спикер.** …действует бесконечно. Пароль сбросил один раз, потом ещё раз и ещё раз. Или токены довольно простые и предсказуемые. То есть любого рода неправильная обработка токенов восстановления доступа становится причиной того, что доступ к учётной записи можно получить.

**Спикер.** Особенность стоит отметить. Сейчас с этим уже сталкиваемся меньше, а раньше очень много было…

**Спикер.** …каких-то подходов к восстановлению вроде контрольных вопросов: «девичья фамилия вашей матери», извините, и тому подобное. Раньше, наверное, лет пять-десять назад, это было прямо повсеместно. Соответственно, базовая информация о человеке из открытых источников — грубо говоря, человек указывает, где он работает, и так далее — во многих случаях давала возможность восстановить доступ к чужой учётной записи.

**Спикер.** Сейчас это, конечно, уже считается небезопасным.

### 00:19:37–00:21:26 — Как устроена сессия и её идентификатор

**Спикер.** Сессия — это ещё более хитрая атака. Как это работает? Вот заходите вы на сайт.

**Спикер.** Сайт, скажем, какого-нибудь… Я не знаю, мы с вами разбирали много примеров. Давайте пусть будет приложение для заказа еды. Вы на него зашли, вы не авторизованы. Для того чтобы вас идентифицировать, отделить от других пользователей, вам, как правило, сразу выдаётся определённый идентификатор сессии. Зайдите на любой сайт, посмотрите: там будет явно стоять кука, которая будет идентифицировать вашу сессию. Это может быть ID, может быть значение из двадцати символов — по-разному, в зависимости от того, что используется. Дальше что происходит?

**Спикер.** Вы авторизовались на сайте. Сайт для вашей сессии, для того токена, который у вас есть, поднял роль до аутентифицированного пользователя, к примеру. И вы с тем же токеном продолжаете ходить по сайту. Вот в чём здесь проблема? Может, кто-то скажет?

**Спикер.** Задай ещё вопрос, пожалуйста. Ну, допустим: до авторизации, после авторизации.

### 00:21:27–00:25:10 — Фиксация сессии: разбор с участниками

**Участник.** Получается, по факту у нас один фактор. Ну, как бы, один известный фактор — мы знаем имя пользователя. Получается, токен равен имени пользователя? Получается, это как имя сессии, условно?

**Участник.** Ну так он сам по себе же ничего не значит. Он не знает, кто вы.

**Участник.** И что было до этого. То есть живёт она, наверное, бесконечно — может, это и не важно.

**Спикер.** Получается, можно проследить, как это происходит. Мы переводим клиента на веб-сайт, который сами строим, и с него подставляем ему какой-то собственный идентификатор сессии. Вы зашли на сайт, взяли свой токен, сайт вас идентифицировал; дальше мы осуществляем обращение к какому-то другому клиенту: «Перейди на сайт». Он перешёл на сайт, и мы ему поставили свой собственный токен. Если он на этом сайте авторизовался, то мы…

**Участник.** Не должен сработать. Ну надо же авторизоваться, опять же. То есть токен мы знаем, пользователь авторизовался — хорошо. Но чтобы им ещё раз воспользоваться, надо ещё раз просто пройти аутентификацию.

**Участник.** А может быть такое, что какое-нибудь вредоносное браузерное расширение просто считывает токен? *[Середина реплики неразборчива.]* Токен актуален только для этого приложения, но расширение его считывает — и тогда использовать можно.

**Спикер.** Тоже можно, да. В чём заключается фиксация сессии, ещё раз попробую. Атакующий берёт свой заранее известный токен и подставляет его пользователю…

**Спикер.** …с этим токеном пользователь авторизуется в системе, а идентификатор не меняется. Это значит, что тот же самый токен, который атакующий предложил до авторизации, атакующий может использовать уже после неё. Грубо говоря, пользователь авторизовался — и токен стал авторизованным.

**Спикер.** Если подставить свой токен не получается, подобный этап можно сделать следующим образом. Понятно, что на компьютере есть программа, которая сама идёт на этот сайт. Она не авторизуется, но она туда идёт и получает тот идентификатор сессии. Дальше мы ждём, когда пользователь на этот сайт зайдёт и авторизуется. А токен-то мы знаем, мы его передаём куда нужно.

**Спикер.** Туда, где совершаются значимые действия: перевод денег, заказы и так далее. Ну да, даже передавать его не надо — мы изначально его подставили сами.

**Участник.** Нет, ну понятно. То есть он может использоваться не на этом компьютере, а где-то в другом месте.

**Спикер.** Конечно. В этом и проблема.

### 00:25:11–00:28:38 — Что такое токен: обсуждение и требования к нему

**Ведущий.** Слушай, знаешь, чего я не понял? Возможно, это утро. Смотри: токен — как логин, как имя пользователя. В чём разница? Он может быть равен имени пользователя, но всё равно ещё чего-то не хватает. Всё равно же надо ещё дополнительную информацию — он сам по себе не самодостаточен.

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

**Ведущий.** И всё. Для сервера — и всё, больше ничего не надо. А тогда почему он не проверяет IP-адрес? Почему, например, на «Госуслугах» не проверяет?

**Участник.** Проверки-то можно сделать, но точно так же можно прислать фото с развёрнутым паспортом.

**Спикер.** Да.

**Ведущий.** Хорошая получилась зарядка. Что у нас может быть ещё? В целом можно спросить, пока мы не убежали далеко. Я просто тут погуглил, не нашёл точного ответа, точнее — не разобрался. К самому токену предъявляются какие-то требования? Токен как сущность. Есть какие-то международные стандарты или материалы профильных проектов? Именно что такое токен — что мы считаем токеном?

**Спикер.** Это как ключ. Криптография — это как ключ. То есть он должен быть случайным, случайным значением.

**Спикер.** То есть мы в целом живём в мире токенов. Для нас это, конечно, логин и пароль, а дальше всё генерируется.

**Спикер.** И хорошая генерация случайности — приближение значения действительно к случайному. [Продолжение реплики о требованиях к генератору распознано не полностью.]

### 00:28:39–00:33:00 — Флаги cookie: `Secure`, `HttpOnly`, `SameSite`

**Участник.** Вопрос. Браузер, антивирус защищают от того, что токен считывают? Почему браузер защищает?

**Спикер.** За счёт одного из флагов куки: их выставляет браузер. *[Название флага в этом месте неразборчиво.]*

**Спикер.** Значит, вот у нас есть кука. Откройте инструменты разработчика в браузере, посмотрите раздел `Application` и так далее. Посмотрите, что там есть: там будет перечень кук и, значит, чекбоксы флагов.

**Спикер.** Первый — `Secure`. Это значит, что кука не будет передаваться по нешифрованным соединениям. То есть по обычному HTTP она не пойдёт — мы это запрещаем.

**Спикер.** Далее `HttpOnly`. Это флаг того, чтобы клиентский JavaScript, который появился на странице, не мог получить доступ к куке. Это защищает от [межсайтового выполнения сценариев].

**Спикер.** Это как последний рубеж обороны. То есть если внедрение всё-таки произошло, оно не позволит считать куку и отправить её на сторонний сайт.

**Спикер.** `SameSite` — это флаг, который больше защищает от [межсайтовой подделки запроса]. Он не позволяет куке, привязанной к определённому сайту, «гулять» и подхватываться при стороннем запросе на сайт.

**Спикер.** Например, что будет, если я поставлю то или иное значение? Значений три: `None`, `Lax` и `Strict`. Если я поставлю `SameSite=None`, то атакующий может перевести меня на какой-то фишинговый ресурс и из этого фишингового ресурса инициировать, допустим, запрос к сайту — заказать там что-нибудь.

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

**Спикер.** А если я поставлю `Lax`, то он мне разрешит часть переходов. Допустим, я скинул ссылку на какой-нибудь сервис доставки еды, я из мессенджера перешёл — там будет, условно, GET-запрос, и я смогу перейти. А если я перешёл с фишингового ресурса, то тут вопрос.

**Участник.** Вопрос в том, существуют ли в этом случае разрешённые запросы, изменяющие состояние?

**Участник.** *[Реплика неразборчива.]* Но очень интересно.

**Спикер.** Ну, при желании ответ можно проверить. Пожалуйста, можете в консоли браузера посмотреть.

### 00:33:01–00:34:38 — Время жизни сессии, ротация идентификатора и лабораторная работа по `A07`

**Спикер.** Что помимо этого? Время жизни сессии желательно должно быть коротким. При обновлении прав должна быть определённая ротация. Ну и смена идентификатора сессии при повышении привилегий — это мы уже обсудили.

**Спикер.** Так, ну да, здесь то же самое, другими словами, в общем виде. Как проверять эту функцию? Тестами: по большей части функциональными тестами и тестами безопасности. Идентификатор прямо тоже должен меняться; нужно проверять, что новый идентификатор запрашивается. Ну и, конечно, планирование проверок.

**Спикер.** Вот здесь будет лабораторная работа. В целом она несложная. Тут просто попробовать подобрать логин и пароль. А можете ли вы найти их сами? Можете попробовать погонять словари. Логин подойдёт простой — сложный не подбирайте. [Формулировка задания распознана частично.]

### 00:34:39–00:37:12 — `A08`: целостность программного обеспечения и данных, сериализация

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

**Спикер.** Даже в прошлых версиях перечня OWASP этот пункт назывался именно так — про десериализацию. Сейчас формулировка стала более общей.

**Спикер.** О чём идёт речь? Сериализация — это, например, следующее: нам нужно передать какую-то структуру данных. Именно программную структуру данных или какую-то другую структуру данных — форматов есть несколько. То есть нужно понимать, что именно нужно передать и какие бывают особенности при восстановлении.

**Спикер.** Если у нас есть необходимость передавать структуру, то у нас есть разные форматы. Если мы говорим про структуры данных конкретного языка программирования, то при восстановлении сериализованного объекта такого формата у них могут быть функции инициализации. То есть при восстановлении структуры обратно в код порой сталкиваемся с тем, что эти структуры сами вызывают свои методы.

### 00:37:13–00:40:42 — Форматы данных: `JSON`, `XML`, `YAML` и рекурсивные ссылки

**Спикер.** И этот метод может быть вызван в случае, если структура данных была перехвачена или каким-то образом изменена — допустим, если атакующий смог на неё повлиять до передачи. Каким образом могут проходить последствия? Вплоть до выполнения кода.

**Спикер.** Если мы используем структуры более текстового вида — вы знаете, `XML`, `JSON` и `YAML`, — то, если говорить про API, наиболее безопасным является просто `JSON`: в нём нет динамических конструкций.

**Спикер.** Структура `JSON` — это `JSON`-текст. Там либо правильный формат, либо неправильный формат. Если он куда-то передаётся, то парсер либо его обработает, либо споткнётся. А если споткнётся — это уже вопрос о том, как нужно правильно обрабатывать ошибку.

**Спикер.** А про другие форматы, `XML` и `YAML`: они позволяют вкладывать в себя определённые динамические структуры. И эти динамические структуры разворачиваются. То есть финальный текстовый вид формата может изменяться при его восстановлении. Часть документа может ссылаться на свой же документ — формат это позволяет.

**Спикер.** Документ, допустим, может ссылаться на себя, подтягивать себя и восстанавливать часть объекта внутри себя. При восстановлении общего объекта тоже могут быть особенности — например, резкий рост размера структуры. А вот эти форматы уже более опасны, если говорить с точки зрения восстановления.

**Спикер.** Поэтому здесь формат нужно валидировать.

**Спикер.** Да, то есть в зависимости от модели атаки. Самые опасные атаки — это передача программных структур, сериализованных средствами языка: это история, которая действительно поддерживает инициализацию данных. Это может приводить к настоящей проблеме. Текстовые форматы данных могут рекурсивно ссылаться на себя, на какие-то внешние объекты. И, по идее, объём может лавинообразно расти. Значит, у вас будет интересная лабораторная работа.

### 00:40:43–00:44:33 — Лабораторная работа по `A08`: рекурсивные ссылки и устаревшая B2B-форма

**Спикер.** *[Начало реплики неразборчиво; речь про переполнение памяти.]* Я покажу файлик — как это будет выглядеть. Сейчас переключусь на лабораторную. Эту работу в лаборатории сделали прямо очень подробно.

**Спикер.** Нужно, чтобы файл рекурсивно ссылался на себя и так далее. У вас должен быть развёрнут стенд — это должно было быть в инструкции, — чтобы он позволял выполнять такую загрузку. То есть если вот это передано в приложение, там не будет ограничений. [Формулировка критерия успешности распознана не полностью.]

**Спикер.** Сейчас я переключусь. Видно? Сейчас попробую ещё раз сделать.

**Спикер.** Смотрите: вот здесь формат данных и обрабатывается. Там есть такая формочка — она позволяет загружать файл. Вы уже с ней сталкивались, когда в задании было написано, что есть устаревший B2B-интерфейс, который позволяет выгружать форматы данных, официально уже не поддерживаемые.

**Спикер.** Значит, вы создаёте вот этот файлик с расширением `.yaml` и смотрите, что будет происходить.

**Спикер.** Переменная `a` с подчёркиванием будет содержать себя в себе. Здесь переменная `b` содержит переменную `a` — то есть каждая переменная будет иметь в себе предыдущую, и каждый элемент массива будет повторять эту же вещь. Далее переменная `c` — перечень элементов, следующий и так далее.

**Спикер.** Соответственно, парсер формата будет пытаться его развернуть, и при восстановлении может занять очень большой объём памяти, по идее.

**Спикер.** Стенд придётся перезагрузить. Критерий успешности лабораторной работы — то, что вы видите [зависание] сервера. Ну и, по идее, должно ещё выскочить уведомление о том, что мы справились с работой успешно. Вот, собственно, такая структура данных, которую вы подложите в форму, и посмотрите, как поведёт себя сервер.

### 00:44:34–00:47:30 — Защита от небезопасной обработки форматов: лимиты разбора, мониторинг и проверка целостности в пайплайне

**Спикер.** Возвращаемся к презентации.

**Спикер.** Ну, как мы с этим боремся? Безопасность прежде всего: использовать текстовые форматы.

**Спикер.** Про это я уже много говорил сам: `JSON` — безопасный формат. Далее. Если вы используете другие форматы, то, конечно, заранее нужно ограничивать их разбор. Грубо говоря, выделять ограниченное пространство на то, чтобы эти форматы разобрать. Если разбор в эти пределы не укладывается, обработку нужно прекращать. *[Окончание реплики неразборчиво.]*

**Спикер.** Ну и десериализация.

**Спикер.** Про десериализацию — это то, что я говорил: десериализация программных объектов. Конечно, лучше использовать [форматы] данных. Ну и, конечно, лимиты на размер файлов.

**Спикер.** Или можно мониторить память, или проверять, не подкладывают ли вам что-то лишнее.

**Спикер.** Ну и соответственно.

**Спикер.** Интеграция и проверка целостности артефактов на входе в пайплайн — имеется в виду конвейер сборки.

**Спикер.** Ну и проверьте, пожалуйста. Попробуйте подкидывать такие файлы.

### 00:47:31–00:49:44 — Два последних пункта списка и постоянное сканирование продакшена

**Ведущий.** Нужно убедиться, что сервер отвечает на это корректно: по логам должны быть какие-то сигналы того, что происходит что-то некорректное. Это всё по предыдущему пункту.

**Ведущий.** Два последних пункта — они уже больше про то, как писать код. Например, если студенты работают со своими лабораторными работами, эти пункты нужны для того, чтобы они поняли, как правильно писать код. Последние пункты именно про логирование и про обработку ошибок. Остальные категории списка — больше про другое.

**Ведущий.** Это очень хорошая практика разработки. Если система работает в продакшене, её постоянно пытаются сканировать, разбирать, воздействовать на неё разного рода средствами. Возьмите любой сервер, любой адрес — вы можете сразу же включить логи и посмотреть в течение какого-то времени, что там происходит. Это происходит постоянно, есть много разного рода систем, которые этим занимаются.

**Ведущий.** Постоянно. Причём постоянно и дома. *[Часть реплики неразборчива.]*

**Ведущий.** Пытаются сканировать, пробивать что-то. Это реалии современного интернета: обращения идут со стороны самых разных IP-адресов.

### 00:49:45–00:51:52 — A09: недостаточное логирование и мониторинг безопасности, сбор логов и SIEM

**Ведущий.** Итак, следующая категория — недостаточное логирование и мониторинг безопасности.

**Ведущий.** В чём здесь проблема? Разработчики неправильно логируют. Логируют не события безопасности, и это приводит к тому, что потом, к сожалению, тяжело расследовать инциденты. Система не даёт сигнала о том, что что-то происходит: переборы аккаунтов, какие-то попытки авторизации, попытки загрузки файлов разного рода. Такие вещи надо логировать.

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

**Ведущий.** Правильнее говорить — это система управления событиями и инцидентами [SIEM]. Есть определённые правила, на основании которых задаются алерты и инциденты. Специалисты службы безопасности могут дальше на это смотреть, разбираться, что с этим делать.

**Ведущий.** А если логов нет — нет и информации о том, что происходит с системой. Бывает и другое: логирование как таковое есть, но разбор логов не выстроен. *[Окончание реплики о заполнении логов запросами неразборчиво.]*

### 00:51:53–00:54:19 — Флуд логов как способ скрыть атаку, SOC и метрики

**Ведущий.** Есть и обратная сторона. Атакующий может намеренно сгенерировать огромное количество логов: массовое машинное сканирование, шум. И среди всего этого реальная атака где-то теряется, её просто не видно. Мера защиты — это, по сути, построение системы управления событиями.

**Ведущий.** Смотрите: защита логов, их хранение, наличие идентификации, правила идентификации событий. Это уже, конечно, большая отдельная тема: системы управления, сети, security operations center [SOC], команды, которые этим занимаются.

**Ведущий.** Второй момент. Допустим, есть в системе метрики. Какой показатель встречается? Действительно, про них часто забывают. Иногда метрики содержат чуть больше внутренней информации, чем нужно.

**Ведущий.** Насколько загружена система, утилизация процессора, сколько контейнеров — всё что угодно. Какой-нибудь SLA по аптайму этих самых серверов. То есть метрики — это внутренние данные. Метрики должны быть.

**Ведущий.** Здесь тоже бывают открытые метрики, которые может посмотреть кто угодно. *[Продолжение реплики неразборчиво.]*

### 00:54:20–00:55:37 — Что именно логировать: корреляционный идентификатор и запрет секретов в логах

**Ведущий.** Что логировать — это вопрос. Конечно, всё, что связано с идентификацией: по сути, любые процессы, корневые действия, любые админские действия, изменения и так далее.

**Ведущий.** От каждого запроса обязательно нужен идентификатор — первичный, сквозной. Условно: один пользователь совершил определённый перечень событий, и нужно, чтобы эти события можно было связать между собой.

**Ведущий.** И, конечно, не писать в логи персональные данные. Когда в логах пишется «такой-то пользователь с таким-то логином, с таким-то паролем, такой-то номер карты», система логов превращается в источник чувствительной информации. Такого быть не должно. По логам принцип такой: собирать минимально достаточное количество данных для того, чтобы с ними можно было работать.

### 00:55:38–00:57:24 — Лабораторная работа по A09 и переход к A10: обработка исключительных ситуаций

**Ведущий.** Ну и лабораторная работа по этой теме — точка доступа к метрикам. Посмотрите, что там интересного показывается.

**Ведущий.** И финальный пункт — неправильная обработка исключительных ситуаций. Что такое исключительная ситуация? Это разного рода управление ошибками. Менеджмент ошибок любого рода может приводить к разным последствиям, особенно если он сделан некорректно и неконсистентно по всему приложению разработчиками приложения.

**Ведущий.** Допустим, есть запросы. Например, параметров не хватает, или, наоборот, поставили что-то лишнее. И сервер начинает выдавать ошибки: сервер недоступен, лимит исчерпан и так далее. Как это может обрабатываться? Во-первых, так, как вы видели вчера: выдаётся информация о том, в каком файле что сломалось, информация о файловой системе — что произошло и что не так. Это может быть очень плохо. *[Далее упоминается отказ в обслуживании; формулировка распознана не полностью.]*

### 00:57:25–00:59:19 — A10: fail-open при авторизации и модель воздействия на приложение

**Ведущий.** Сейчас, конечно, редкость, но до сих пор встречается ситуация, когда приложение при попытке перехода куда-то пытается выполнить действие, которое выполнять не должно. *[Формулировка распознана частично.]*

**Ведущий.** И самое страшное — это когда какая-то ошибка инициируется, и приложение вместо того, чтобы отказать в выполнении определённых действий, эти действия выполняет. Например, авторизация: ошибку авторизации вызывает приложение, и вместо того чтобы сказать «предоставьте правильные данные», оно просто авторизует пользователя. Вот это самое страшное.

**Ведущий.** Модель воздействия здесь строится из трёх элементов: мы модифицируем данные, либо модифицируем время, либо модифицируем нагрузку на систему. То есть разными способами пытаемся автоматически воздействовать на приложение, чтобы вызвать сбой.

**Ведущий.** Мы с вами в целом это обсудили: исключения, прерывания, ошибки в целом — и их последствия. *[Часть реплики о языках программирования распознана не полностью.]*

### 00:59:20–01:01:28 — A10: неконсистентная обработка ошибок и примеры утечек

**Ведущий.** Ситуация, которая до сих пор встречается в разработке, — каждая ошибка обрабатывается по-разному. Смотришь код, и получается, что одна ошибка обрабатывается одним образом, другая — другим, третья — третьим. Нет общего метода, нет центральной обработки ошибок приложения.

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

**Ведущий.** Системно это, к сожалению, сейчас не всегда делается правильно. И с приходом искусственного интеллекта тоже: он старается всё сделать как можно быстрее. *[Окончание реплики неразборчиво.]* Хорошо, если это явно заказать, явно указать в задании.

**Ведущий.** Примеры. Сервер авторизации недоступен — а пользователь авторизован. Вызвали ошибку базы данных — и получили информацию о таблице, о сервере, о самой базе.

**Ведущий.** Сделали нагрузку на приложение — вызвали отказ в обслуживании. Или транзакция оплаты была прервана, а операция при этом прошла.

### 01:01:29–01:03:46 — A10: как защищаться — два уровня сообщений, транзакции, идемпотентность, таймауты, тесты

**Ведущий.** Вот эта категория такая. Как от этого защищаться? Примерно следующим образом. Если происходит ошибка, дальнейшая обработка должна запрещаться, а сообщение должно говорить ровно о том, что нужно.

**Ведущий.** Причём для разработчика сообщение — подробное, а для пользователя приложения — более общее: «отказ операции». Отдельный вопрос — транзакции. Что происходит, если транзакция прервана или если несколько транзакций выполняются одновременно на сервере? Несколько транзакций не должны непредсказуемо влиять на состояние сервера.

**Ведущий.** Таким образом, если пользователь отправил, условно, сто запросов, должна быть определённая обработка этих операций. Есть подходы, связанные с тем, что одинаковые запросы пользователя считаются одним и тем же запросом и применяются только один раз; и есть условие, что после определённого количества они отклоняются.

**Ведущий.** Дальше — таймауты для ограничения ресурсов, безопасность сообщений. И всё это нужно проверять и описывать. Тесты желательно автоматизировать, желательно всё это обрабатывать в каких-то тестовых средах и проверять заранее.

### 01:03:47–01:05:47 — Опциональная лабораторная по SSRF: подмена адреса во внешнем запросе и отличие от редиректа

**Ведущий.** Лабораторная работа здесь тоже про ошибки, но в более интересном варианте — это тест того, как ведёт себя API. На самом деле она больше относится к другому классу проблем, но вам будет интересно её проверить и посмотреть.

**Ведущий.** Речь про API, которое позволяет обратиться к внешнему ресурсу. Допустим, у вас есть какой-то сайт. Этот сайт вытаскивает определённые данные из внешних систем по параметрам, и по этому параметру он может какие-то данные подтянуть.

**Ведущий.** Например, сайт-агрегатор подтягивает данные, но параметр позволяет указать, откуда именно их брать. И если мы в этом URL укажем адрес из приватных диапазонов IP-адресов и попробуем таким образом перебирать внутреннюю инфраструктуру, он тоже будет подтягивать данные.

**Ведущий.** Похоже на редирект. Но отличие в том, что редиректа не происходит: данные подтягиваются непосредственно на страницу.

**Ведущий.** Работа опциональная. Если у вас будет время, можете посмотреть — я сейчас вкратце вам напишу, о чём она. Она стоит несколько отдельно от остальных.

### 01:05:48–01:08:56 — Лабораторная работа по SSRF: два сервиса в docker-compose и шаги выполнения

**Ведущий.** Смотрите. У вас будет вот такой код — код с обработкой запроса. Этот код нужно взять и положить в файлик `docker-compose.yml`. Docker Compose — это утилита, одна из функциональностей Docker, которая позволяет поднимать несколько контейнеров, а не один.

**Ведущий.** И будет два сервиса. Первый сервис — приложение, которое вы сможете найти по адресу `localhost:8018` *[номер порта распознан неуверенно]*. И второй — какой-то внутренний сервис, который будет доступен на порту `9000`, но уже внутри сетки Docker. То есть не факт, что он вообще проброшен наружу, — это зависит от настроек Docker.

**Ведущий.** В чём идея. Этот сайт подгружает какие-то данные с внешнего сайта: там будет адрес вида `http://example.com` *[имя домена в записи распознано неуверенно]*, и он показывает данные этого сайта. Наша задача будет заключаться в том, чтобы попробовать получить данные из внутреннего ресурса, из песочницы. Получается, песочница у нас в Docker.

**Ведущий.** То есть из публичного сервиса мы получаем доступ к внутреннему контейнеру за счёт того, что приложение не контролирует, с каких адресов оно может запрашивать информацию. Здесь можно будет подставить адрес внутреннего контейнера и попробовать посмотреть, получится ли достать секретные данные, которые находятся на внутреннем ресурсе. Там будет подсказочка.

**Ведущий.** Порядок такой. Сначала вы создаёте файл. Потом поднимаете эти два контейнера, они подгружаются. Дальше открываете первый, внешний контейнер, проверяете, что он работает: делаете запрос к внешнему ресурсу. Потом пробуете сделать запрос уже иначе. *[Название использованной утилиты неразборчиво.]*

### 01:08:57–01:12:16 — Зачем в этой работе два ресурса, завершение веб-части и время на лабораторные

**Ведущий.** И получится. Ещё раз повторяю: работа опциональная, можете её тоже попробовать использовать. На воркшопе её круто сделать, потому что для того, чтобы сделать **SSRF** *[термин восстановлен по контексту]*, нужно два ресурса: условно, один внешний, другой внутренний. Поэтому в этой лабораторной мы немножко иначе всё устроили — на два ресурса, чтобы вы прочувствовали, в чём разница, и заодно посмотрели на обработку ошибок, которую мы с вами последней обсуждали.

**Ведущий.** В целом у вас уже была виртуальная машина. Вы пробовали обратиться к точке входа, которая существует, по существующему адресу, и увидели, что обращение приводит к какой-то общей ошибке. *[Формулировка распознана частично.]*

**Ведущий.** Поэтому попробуйте это сделать. В целом это интересно ещё и студентам показать: посмотреть именно на API, которые задействуют сразу несколько серверов. Это показывает, что проблемы в приложениях иногда будут относиться не к одному приложению, а к нескольким. *[Следующая короткая реплика о последствиях неразборчива.]*

**Ведущий.** Ну и в целом всё. Мы с вами посмотрели четыре пункта, разобрали их и, можно сказать, завершили веб-часть нашего обсуждения. Следующая презентация будет уже про другое направление. Поэтому давайте сейчас попробуем поделать лабораторные работы.

**Участник.** А можно вопрос задать? *[Часть реплики неразборчива.]*

**Ведущий.** Давайте 30–40 минут. Закончить в меньшее время будет сложно.

### 01:12:17–01:14:07 — Личная база лекций, репозиторий и подготовка материалов ИИ-агентом

**Участник.** Да, мы делали седьмую, восьмую, девятую, десятую.

**Участник.** Я как раз подхожу спросить: ты готов? Давай сделаем.

**Участник.** Что тут, слайды смотришь?

**Участник.** Смотри. Тут можно листать все твои слайды.

**Участник.** Это фотографии?

**Участник.** Вот к чему лимит приводит. Прикольно. Очень круто.

**Участник.** А у меня тут лекции уже выложены, я всё это наковырял, и на свой публичный сайт тоже. По авторским правам там всё прямо написано, поэтому я ничего чужого не забираю. Вот, видишь, у меня там положения программы. У тебя за два дня — это как раз про эту программу, подумаю, может, мне тоже так будет удобно.

**Участник.** Вообще круто. То есть это типа личная база данных?

**Участник.** Это репозиторий. Он в GitHub есть, и там ты просто буквально говоришь: «вот, делай» — и он делает. Кликаю — он там всё это дело смотрит. Где-то шрифты съедут, где-то таблички уехали — он всё объясняет.

**Участник.** Я Codex направил на транскрипцию, на фотографии — он всё подготовил. Потом он предложил структуру. Мне не понравилось, он всё убрал, там мало всего осталось. Я говорю: давай прокачивай. Он такой: окей, — начал прокачивать и сделал. А потом я ещё раз проходил и улучшал.

### 01:14:08–01:16:31 — Стили работы ассистентов, взаимное ревью и генерация регламентов по ГОСТу

**Участник.** Я написал ему: вот, тут Codex сам поработал, давай сделай по-нормальному. Он: да-да, окей, давай так.

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

**Участник.** Иногда, знаешь, задачу решаешь: сначала прогоняешь её Codex'ом, потом отдаёшь ещё двум-трём китайским моделям, и все они нарожали каких-то ТЗшек, конфигураций, всего подряд. И ты ему говоришь: вот, со мной поработали, давай сделаем. Он такой: вижу, поработали, но давай сейчас сделаю нормально. И пишет: вот здесь такой недостаток, тут пропустили это и это. И ты читаешь и соглашаешься — действительно, как человек.

**Участник.** И они как люди общаются. Кто-то мудрый, а кто-то такой: «Всё, я понял, ребят, спасибо, сейчас нормально сделаю. Спасибо, что проработали». У каждого своя политика. Мне вот в этом плане Codex больше нравится.

**Участник.** Он креативно работает. Иногда быстро систематизирует. И знаешь, что он делал ещё на первых порах, где-то год назад? Мы брали ГОСТ, и я ставил задачу: возьми ГОСТ, дай мне список регламентов. А там по ГОСТу получается *[количество не распознано]* регламентов. И мне нужен профиль фирмы: условно говоря, вот столько программистов, стек такой-то, вот такой продукт. Напиши мне проект регламента, страниц на пять, на десять. Просто генерируй документ, похожий на реальность.

**Участник.** И он мне всё это делал, рождал документ. Первая страничка нормально, а дальше прямо заглушку оставляет — одно и то же, один и тот же абзац.

**Участник.** А вот у Anthropic такого нет вообще. Они знают, что дорабатывают. У них изначально всё нормально работало.

**Участник.** Они сейчас сделали отдельный продукт. Как он там называется? В ChatGPT ведь теперь приложение переключаешь сверху, да?

### 01:16:32–01:18:44 — Разделение продуктов, режим советника и голосовой ввод

**Участник.** Да, там переключение между обычной, будничной задачей и отдельно Codex — как для программирования и разработки.

**Участник.** Ну, оно всё движется. Я думаю, там сейчас пара месяцев — и всё поменяется. Потому что то, что они глючат, всем не нравится. То, что они не дорабатывают, не доводят до конца, тоже всем не нравится.

**Участник.** И даже сейчас такая мысль звучала: если вы пишете, надо ещё проверить. А у Anthropic не надо — он уже проверяет, у него это дефолтная штука. А я ещё и режим советника поставил.

**Участник.** Там есть такая команда через слеш — advisor. На *[название модели не распознано]* советника поставить нельзя, а на Опус 5-й — можно. Я обычно ставлю это на максимум, на самый вот этот волшебный режим. Круто в целом.

**Участник.** А микрофон есть?

**Участник.** Работает, я чисто удалённо.

**Участник.** Нет, я говорю в приложение, которое транскрипцию делает тоже. Микрофон у меня как стерео, а так у меня просто голосовой ввод, обычный — именно от самой операционной системы, с клавиатуры.

**Участник.** Транскрипцию делает само приложение, и текст уже уходит ему. Я ему голос — он текст. Я поправил с клавиатуры.

**Участник.** В итоге агент у тебя получает текст или голос?

**Участник.** Текст. Я знаю, что во всех этих средах есть голос по пробелу. Я сколько пробовал — у него в распознавании мой язык за какой-то другой считает. У меня пока не получилось. Ну как может просто русский нормально? В общем, если не это использовать, а десктопное приложение — там, в десктопе, у Codex обработка нормальная была. Хотя в другом клиенте...

### 01:18:45–01:21:10 — Десктоп против браузера, схлопывание сессий и отдельное окно дизайнера

**Участник.** ...по-моему, русского вообще нет.

**Участник.** Знаешь, в чём дело, почему мне сейчас не очень нравится десктопная версия? Вот когда был Опус *[версия не распознана]*, он несколько раз мне — и это тоже обсуждалось на американских форумах — схлопывал все сессии. Ты сидишь, разрабатываешь, открываешь — а сессии вообще нет. Ты один раз в архив залез, а он решил, что она закончена, и закрывает её. И меня это начинало подбешивать: возвращаешь её, открываешь заново.

**Участник.** Я сижу, мне что-то не нравится. Посмотрел альтернативный вариант *[название не распознано]* — и понял, что особой разницы нет. И даже наоборот. Ты как архитектор понимаешь: вот эта нагрузка от виндовых экзешников — она лишняя, она мешает. Модель как будто без этого грузного работает легче, как будто быстрее. И в браузере она всё это нормально делает. По функциональности как будто бы даже не хуже, чем десктопное приложение.

**Участник.** То есть я не могу сказать, что есть что-то, что в десктопе есть, а там нет. Ну, есть одно: они сейчас сделали, что в десктопе дизайнер запускается у тебя отдельным окном, и ты сидишь работаешь. Раньше дизайнер был только на сайте, а сейчас он и здесь.

**Участник.** Я обычно, когда дохожу до какого-нибудь момента — например, нужно поработать над каким-то окошком, — думаю: а как это вообще выглядит? Мне неудобно просто так что-то перетаскивать. Там просто чат, там есть проектики. И я обычно прямо говорю ему, Клоду: доходим мы до этого момента — сформулируй промпт для Claude-дизайнера, чтобы мы вот эту страничку проработали.

**Участник.** Он пишет промпт какой-то немеренный. Я туда прямо вставляю и говорю: вот, мы дошли до, не знаю, клиентских данных — давай поработай с учётом фирменного стиля, называется дизайн-проект вот этого нашего приложения. Он такой: ага. И начинает прямо менять. Видишь, на экране прямо обновляешь страничку — и он тебе всё круто выстраивает. А потом я пишу ему: сделай зип-архив.

### 01:21:11–01:24:07 — Роль «начальника», эмоциональная нагрузка, уведомления и стандартизация кода

**Участник.** Делаешь зип-архив. Я ему говорю: вот, ребята поработали, вот, твой дизайн проверю. Он такой: не, нифига, там доработали. Окей, принимает: давай почитаем, будем делать.

**Участник.** Слушай, ты прямо мастер.

**Участник.** Да ладно, мастер.

**Участник.** Нет, это правда, потому что ты сидишь как большой начальник, у тебя всё работает. С одной стороны, так. А с другой стороны, если у тебя много параллельных вещей, эмоциональная нагрузка больше. Очень устаёшь.

**Участник.** Например, у меня там экран. Надо мышь подвигать там, где он завис. Знаешь, как хитро: делаешь луп-цикл, а он в какой-то момент останавливается и говорит: вопрос — что мне делать? А ты начинаешь: мы же с тобой решили это, посмотри там, это решение уже принято.

**Участник.** Я сплю, а он пишет. Я ему такую фразу дал: «заявитель спит, сразу не отвечу», «на все вопросы ответ получен не будет». Заканчивай тестирование, приводи репозиторий в порядок. И он такой: да-да, прикрепишь там...

**Участник.** *[Реплика в сторону; техническая пауза.]* Что-то меня дёргает. Всё хорошо.

**Участник.** Я такой: заявитель спит. А что там? Я собака? Я что, сделал инструкцию, что он мне каждый раз, когда отвечает, будет писать как собаке? Он мне пишет: да-да-да, сделал. И такой: привет. Знаешь, иконочка — собачка такая. Блин, ну завалил. Интересно организовано. Ну ладно, что поделаешь.

**Участник.** И я тогда сижу — у меня всё сделано. Ну, я имею в виду, у меня здесь уже сделано. Спасибо большое.

**Участник.** Знаешь, кстати, к чему это может привести?

**Участник.** *[Начало ответа неразборчиво.]* У нас наконец-то, возможно, будет в будущем стандартный отдаваемый код. То есть не будет такого разброса и шатания, когда всем дай по задаче — и все напишут по-разному, а ты как безопасник сидишь: блин, что делать с этим зоопарком?

**Участник.** С другой стороны, я думаю, что в каждой конторе в определённый момент дешевле будет написать собственное решение. Вообще по всем категориям. И тогда заканчиваются продажи, вот и всё.

**Участник.** У меня вопрос. Понимаю, сейчас ситуация такая, что у нас... Ну, во-первых, с Америкой мы условно на год расходимся, а может, и больше, если говорить именно про разработку. То есть там уже массовое сокращение происходит.

## Фрагмент 2

*Конструктор лабораторной работы, командная работа и non-web AppSec: память, мобильные и десктопные приложения. Между постановкой задания и разбором результатов около полутора часов групповой работы, в записи которой связной речи нет.*

### 00:00:00–00:01:30 — От чего отталкиваться при проектировании лабораторной работы

**Ведущий.** Отталкиваться нужно от того, чему студент должен научиться, а не от того, какой материал хочется в работу вложить. Понятно, что материалов очень много и хочется дать всё. Но тем не менее все задания должны работать на цель. У вас студенты второго курса, и ориентироваться нужно на них. *[Часть фразы неразборчива.]*

**Ведущий.** И третье — это соответствие уровню студента и зоне ближайшего развития. То есть задание должно быть чуть сложнее того, что студент уже умеет. Иными словами, ему должно быть чуть-чуть за пределами зоны комфорта, и это «чуть-чуть» должно вызывать любопытство — выйти и узнать что-то новое. Для этого, кстати, очень важно дать студенту инструменты, чтобы он мог определить цель, к которой должен прийти, и проверить себя. *[Формулировка распознана частично.]*

**Ведущий.** Это очень простые принципы, которые мы советуем вам применять и держать в голове. А теперь перейдём к самому шаблону, который нам сегодня предстоит заполнить командами. Этот шаблон вы сможете забрать с собой — он будет только ваш.

### 00:01:31–00:02:57 — Паспорт, цель через действие и пошаговая инструкция

**Ведущий.** Пункты 1 и 2 — это паспорт и цель лабораторной работы. Здесь шаблон уже частично заполнен. *[Фрагмент неразборчив.]*

**Ведущий.** Как я уже говорила, привязывайте работу к конкретной компетенции вашей программы. И старайтесь сформулировать цель так, чтобы её потом можно было проверить.

**Ведущий.** Формулируйте цель через глагол — но не через глагол, который описывает процесс в голове студента («изучил», «понял»), а через глагол, который описывает действие, которое вы потом сможете оценить. Логика такая: раз я вижу, что студент сделал это и это, — значит, цель достигнута, можно ставить зачёт. Если формулировка сразу звучит конкретно, значит цель хорошая, её можно зафиксировать.

**Ведущий.** Дальше. После пунктов 1 и 2 — в пунктах 3–5 *[нумерация распознана неуверенно]* — мы советуем сначала заполнить инструкцию работы: к какому именно результату студент должен прийти. Пункт 6 — это пошаговая инструкция, разбитая по шагам. Если результат опирается больше чем на 8–10 шагов, работу лучше разбить на части.

### 00:02:58–00:05:02 — Доказательство результата, контекст и правила; сильный и слабый вопрос

**Ведущий.** Отдельный раздел — доказательство результата. Что именно студент должен сделать, как, какое решение он должен приложить, чтобы работа была зачтена. Здесь тоже формулируйте максимально чётко.

**Ведущий.** Затем, когда вы вернётесь к 3-му и 5-му пунктам шаблона, работу можно детализировать. Например, в разделе 3 показать контекст: что это за система, какая у студента мотивация. В разделе 4 описать правила проведения. А в разделе 5 написать конкретные команды и проверить, что всё готово.

**Ведущий.** Прежде чем мы подойдём к завершению шаблона, вы как раз начнёте в него погружаться вместе с вопросами. И не смотрите на то, что формулировки в нём достаточно широкие: этими функциями можно поиграться и сделать работу интереснее.

**Ведущий.** Здесь важно вспомнить, что есть большая разница между сильным и слабым вопросом. Вы всё это, конечно, помните, но тем не менее. На слабый вопрос студент может ответить, просто заглянув в вашу же инструкцию, которую вы сами и написали. А на сильный вопрос он ответит, только если действительно понял смысл, — и это уже совсем другая работа. Например, слабый вопрос: «Что мы только что сделали?» — достаточно посмотреть и переписать алгоритм. А сильный вопрос — это «почему?»: почему это сработало, что произойдёт, если мы поменяем компонент, где ещё может встретиться такая же проблема.

**Ведущий.** Такая же проблема может быть и здесь — например, если мы вынесем это в продакшен. *[Фрагмент неразборчив.]* То есть такие вопросы действительно делают работу другой.

### 00:05:03–00:06:54 — Задание со звёздочкой, критерии, подсказки и деление на команды

**Ведущий.** Следующий раздел шаблона *[номер распознан неуверенно]* — это, по сути, задание со звёздочкой. Мы предлагаем вам составить такое задание для ваших студентов и продумать критерии, которые будут привязаны к цели работы. В самом шаблоне мы рассказываем, какие критерии могут быть. Критерии — довольно сложная тема. Поэтому предлагаем, если у вас останется время, заодно заготовить подсказки — не те, которые подсказывают ответ, а те, которые могут быть у вас в запасе, чтобы задать студенту интересный настоящий вопрос.

**Ведущий.** После того как вы заполните пункты с 1-го по 9-й, а возможно, дойдёте и до двенадцатого — то есть когда будет готов базовый блок, — загрузите лабораторные работы: каждая команда свою. Дальше мы приступим к следующей части — взаимной оценке. Это как раз та самая возможность вместе пообщаться, обменяться обратной связью и сделать ваши лабораторные работы лучше.

**Ведущий.** Так что давайте начнём с того, что разделимся на команды. Предлагаю сделать четыре команды, как это было вчера.

**Участник.** [Обсуждается состав и названия команд; звучит название «Хакеры».] *[Реплики неразборчивы.]*

### 00:06:55–01:36:24 — Командная работа над лабораторными работами

*[Редакторская пометка: этот отрезок записи — около полутора часов — занимает работа команд над своими лабораторными работами по шаблону. Связной речи в записи нет: только фоновый шум и отдельные обрывки внутрикомандных обсуждений, которые не восстанавливаются по смыслу. Содержание этого отрезка восстановить невозможно.]*

### 01:36:25–01:38:25 — Что остаётся за рамками веба: работа с памятью

**Спикер.** Сегодня у меня будет ещё пара презентаций, потом финальная презентация коллеги. Все уже устали, но потерпите — осталось недолго. Потом будет приятная часть. *[Фрагмент неразборчив.]*

**Спикер.** В этой презентации мы рассмотрим другие классы приложений. Веб-часть мы уже разобрали, подробно рассмотрели набор OWASP. Теперь посмотрим всё, что касается не веба. Здесь не будет какого-то одного устоявшегося фреймворка или классификации, по которым можно было бы всё разложить.

**Спикер.** Пройдёмся поверхностно: просто посмотрим, что находится за рамками веба. И учитывайте, что каждый из разделов, которые мы сейчас рассмотрим, можно спокойно расширять — по многим из них можно сделать отдельную презентацию.

**Спикер.** Первое — всё, что касается работы с памятью. Это огромная тема, об одной только ней можно разговаривать несколько дней. Поэтому сейчас мы по ней быстренько пробежимся.

**Спикер.** В чём риск? Языки программирования, которые работают с памятью напрямую, имеют такое свойство. *[Окончание фразы неразборчиво.]*

### 01:38:26–01:40:24 — Прямая работа с памятью и последствия ошибок

**Спикер.** Такие языки предоставляют разработчику функционал: он может самостоятельно аллоцировать память под переменные, освобождать память из-под этих переменных, создавать указатели, присваивать указатели ячейкам памяти — то есть работать с памятью на уровне, близком к тому, как это физически и происходит.

**Спикер.** Благодаря такой возможности работы с памятью появляется огромное количество проблем, релевантных именно для этих языков. Они возникают в результате ошибок кодирования: неправильной очистки, неправильного присваивания, отсутствия контроля границ памяти, которая выделена той или иной переменной.

**Спикер.** Результатом таких ошибок могут быть очень серьёзные уязвимости. Ошибки при обработке памяти, как правило, ведут к последствиям, начиная от отказа в обслуживании и заканчивая исполнением кода, повышением привилегий и так далее. Это наиболее критичные и при этом наиболее сложные в эксплуатации уязвимости, и поэтому очень важно знать их особенности.

### 01:40:25–01:42:08 — Чем ошибки памяти отличаются от веб-уязвимостей

**Спикер.** Чем ошибки памяти отличаются от веб-уязвимостей? В вебе у нас есть запрос и ответ, мы взаимодействуем с сервером. Мы можем менять запросы к серверу, чтобы вызвать определённое — в том числе небезопасное — поведение, и сервер тем или иным образом отвечает.

**Спикер.** Что касается нативных ошибок работы с памятью, на низком уровне программирования, — здесь сам процесс разработки, безопасного кодирования, безопасного написания кода может порождать огромное количество ошибок. И если такая программа обрабатывает какие-то внешние данные и обрабатывает их не совсем корректно — написана с ошибками, без достаточного количества проверок, — мы получаем те самые результаты, о которых уже говорили: отказ в обслуживании, локальный или удалённый, исполнение кода, повышение привилегий.

**Спикер.** То есть если в вебе код может быть написан идеально, но ошибки всё равно возникают — в бизнес-логике, в архитектуре, в настройках, — то ошибки памяти это ошибки исключительно кодирования.

### 01:42:09–01:44:17 — Переполнение буфера: как это работает

**Спикер.** Давайте рассмотрим несколько вариантов. Переполнению буфера можно вообще посвятить отдельную лекцию, поэтому давайте быстро пробежимся.

**Спикер.** Что это такое и как это работает. Когда мы выделяем структуру в памяти в языках подобного типа, под каждую переменную выделяется определённое количество ячеек. *[Уточнение — где именно выделяется память — распознано неразборчиво.]*

**Спикер.** Если мы считываем в такие переменные какой-то пользовательский ввод, а для переменных уже задано ограниченное количество памяти, и при этом мы не проверяем длину ввода, — это может вызвать ситуацию переполнения. Например, переменная имеет размер 64 байта, а рядышком с ней расположены следующие переменные. Если пользователь введёт 65 байт, мы переполним эту переменную и перейдём в область следующих.

### 01:44:18–01:46:32 — Последствия переполнения: соседние переменные и подстановка команды

**Спикер.** Концептуально это и есть переполнение буфера. В чём проблема? Здесь можно сделать довольно много интересного: начиная с того, что можно перезаписывать соседние переменные, и заканчивая тем, что можно изменить ход исполнения программы.

**Спикер.** В данном случае пример подобран специально: есть переменная, в которой лежит команда, — она где-то дальше исполняется. А рядом переменная, в которую пишется пользовательский ввод. Мы ввели 64 «правильных» байта и следом записали в соседнюю переменную свою команду.

**Спикер.** Соответственно, команда, которая лежит в переменной с командой, будет исполняться дальше по ходу работы программы. И вместо какой-то безопасной команды можно подставить команду, которая, например, повысит привилегии или исполнит какой-то код в операционной системе, — и таким образом атакующий достигнет своих целей.

**Спикер.** Что ещё? Отказа в обслуживании и падения программы мы уже коснулись. Помимо этого можно перезаписать какие-то переменные и выставить, например, флаг, поменять права, в каких-то случаях добиться исполнения кода.

### 01:46:33–01:49:04 — Численное переполнение

**Спикер.** Дальше — численное переполнение. Известная проблема, точнее — целое направление атак, связанное с размерами переменной. Переменной выделяется определённое количество места под хранение значения. И когда мы записываем в неё чуть больше данных, чем она позволяет в себе разместить...

**Спикер.** Например, переменная типа «байт» хранит определённое количество элементов. Если мы добавим к ней ещё один дополнительный элемент, мы можем прийти к тому, что она выйдет за границы. Скажем, есть число 255. Арифметическая операция прибавления единицы к 255 приведёт к тому, что мы получим ноль. А вычитание единицы из нуля приведёт нас к результату 255.

**Спикер.** Соответственно, это может привести к тому, что нарушается логика работы программы, нарушается её работа в целом *[фрагмент неразборчив]*, и это может приводить к небезопасным ситуациям.

### 01:49:05–01:51:33 — Использование памяти после освобождения (use-after-free) и первые меры защиты

**Спикер.** Дальше — использование после освобождения. В чём здесь идея? В языках, где памятью управляют вручную, есть операции выделения памяти под переменную и операции освобождения этой памяти. При этом есть ещё концепция так называемых указателей на ячейки памяти — эти указатели используются в работе программы.

**Спикер.** Иногда, в результате небезопасного кодирования, происходит ситуация, когда указатель указывает на ячейку памяти, которая уже была ранее освобождена. К чему это приводит? У нас есть указатель, который указывает на якобы свободную ячейку памяти, уже не контролируемую программой. Если атакующий имеет возможность подставить в эту якобы освобождённую ячейку памяти свои значения, свои инструкции, он в общем и целом может вызвать определённые последствия для программы: начиная опять же с падения программы и заканчивая в том числе исполнением кода. Очень сильно зависит от того, как именно эта программа работает.

**Спикер.** Как мы можем с этим бороться? В целом у языка есть инструменты, которые позволяют использовать безопасные функции: проверки границ, безопасное копирование и так далее. Есть определённые стандарты безопасности языков. Для всех языков, которые работают с памятью напрямую, их обязательно нужно использовать.

### 01:51:34–01:53:54 — Безопасные функции, разделение ввода и команд, где применяются низкоуровневые языки

**Спикер.** Обязательно нужно использовать безопасные методы и функции, которые правильно работают с памятью. Важно не смешивать то, что пользователь вводит в программу, с операциями различного рода исполнения — особенно с исполнением каких-то системных команд. Это желательно максимально разделять и избегать того, чтобы пользователь мог что-то подставить.

**Спикер.** Хотя, конечно, языки, которые работают с памятью напрямую, как правило, решают именно те задачи, которые не могут решить высокоуровневые языки. Там, где используются такие языки, — это, как правило, устройства, где нужно действительно контролировать железо, где тебе важна максимальная скорость, где необходимо работать с какими-то внешними устройствами на низком уровне.

**Спикер.** Даже если говорить про сетевой трафик — там очень много разного рода парсеров и обработчиков. Раньше на этом уровне писали в том числе системные вещи. *[Фрагмент неразборчив.]* Сейчас, конечно, переходят на языки, которые сами управляют памятью.

**Спикер.** Разработчик — даже опытный — делает ошибки, об этом говорят. В целом об этом говорит и количество уязвимостей, которые сейчас находят с помощью разных решений на базе искусственного интеллекта, с помощью агентов: большинство уязвимостей действительно связано с ошибками работы с памятью. *[Окончание фразы неразборчиво.]*

### 01:53:55–01:56:18 — Безопасные языки, статические анализаторы, санитайзеры и флаги компилятора

**Спикер.** Соответственно, там, где есть возможность использовать безопасные языки — языки с собственной обработкой, с собственным управлением памятью, — это позволит избежать всех ошибок такого рода.

**Спикер.** Ну и, конечно, проверяйте код: используются статические анализаторы, проверяется безопасность.

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

**Спикер.** Ну и функции компиляторов: разного рода защитные механизмы, стековые протекторы и подобные опции *[перечисление распознано частично]*. Их в целом десятки, есть даже готовые наборы практик, которые сразу рекомендуют для компилятора. Все они так или иначе предотвращают проблемы с памятью, но работают совершенно по-разному. Кто-то ставит на стеке контрольные значения и перепроверяет их, чтобы поймать перехват управления. Кто-то рандомизирует адресное пространство. И так далее. То есть для компилятора обязательно должен быть определён набор флагов, который предотвращает ситуации, где разработчик где-то ошибся.

### 01:56:19–01:58:02 — Лабораторная работа по переполнению буфера (№ 11/12)

**Спикер.** Ну и тесты: проверка на границах массивов, проверка падений и подобные вещи.

**Спикер.** Здесь предлагается лабораторная работа, но делать мы её с вами не будем. Если вы посмотрите в самом конце материалов, там есть упражнение. Она называется одиннадцатой лабораторной, а номер рядом стоит двенадцатый — это опечатка, на номер не обращайте внимания. Это финальная лабораторная работа.

**Спикер.** Она как раз показывает вот этот механизм — в несколько надуманном виде, но тем не менее показывающий, к чему это действительно может привести. Там две переменные расположены рядышком, и приложение запрашивает ввод.

### 01:58:03–02:00:34 — Разбор уязвимого и исправленного файлов на C

**Спикер.** Вот лабораторная работа: здесь, в конце, два файлика с кодом на C. Первый файлик — уязвимый: в нём мы используем переменную `name` без проверки границы. В функции чтения ограничение не выставлено, считать можно значительно больше *[конкретное число распознано неразборчиво]*, при этом сама переменная рассчитана на 64 байта.

**Спикер.** И вот здесь вы подкидываете 65-й байт, а следом — команду для исполнения. И она в результате будет исполняться. Перевод строки там тоже выбирается соответствующим образом. Это простенькая демонстрация, чтобы показать механизм.

**Спикер.** Студенты могут использовать, например, скрипт: закидывают 64 элемента, а дальше — команду `id`. Команду можно поменять на любую другую, без разницы. Дальше она исполнится.

**Спикер.** Вот в этой части студенты и могут увидеть, как действительно произошло переполнение — переполнение из одной переменной в соседнюю. И есть исправленная версия — тоже для перепроверки. Здесь в целом то же самое, но, как вы видите, мы уже проверяем границы: не позволяем ввести больше элементов, чем заложено в переменную. Поэтому в данном случае команда уже не сработает — какая-то внешняя команда просто туда не попадёт. И на этом примере вы можете показать сам механизм.

**Спикер.** Ну и статика это отловит. Статический анализатор такую ошибку отловит — по крайней мере, должен.

### 02:00:35–02:02:20 — Вопрос об интерпретируемых языках и переход к мобильным приложениям

**Участник.** За счёт этого можно сказать, что всё, что интерпретируемое, более защищено — точнее, безопаснее, — чем компилируемое? За счёт этой прослойки в виде интерпретации можно так рассуждать? Или это неоднозначно?

**Спикер.** Там обработка памяти тоже регулируется. Вопрос в том, что язык со встроенным управлением памятью снимает по отношению к памяти целый класс ошибок. *[Формулировка распознана частично.]*

**Спикер.** А если это языки, где работа с памятью ручная, то, конечно, все эти ошибки возможны.

**Спикер.** Итак, вкратце посмотрели про память — поехали дальше. Мобильные приложения.

**Спикер.** Мобильные приложения — тоже интересная история, на самом деле. Там даже есть, можно сказать, отдельный класс угроз, релевантный для них. Давайте посмотрим, чем же они отличаются.

### 02:02:21–02:04:27 — Что хранит мобильное приложение

**Спикер.** Мобильные приложения работают на телефонах. Помимо самого приложения там имеется много собственных файлов. Мобильное приложение — это такая «картинка», которая складывает в себя перечень ресурсов, с которыми оно непосредственно работает и взаимодействует: разного рода идентификаторы, артефакты авторизации, ваши данные, кэш, какие-то картинки и так далее. Всё это находится у вас на устройстве.

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

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

### 02:04:28–02:06:15 — Модель угроз: доступ к устройству, SharedPreferences и Keystore

**Спикер.** Возьмём токен. Как и в случае с клиентскими веб-сайтами, на которые мы ходим: там всё хранится в браузере. А здесь браузера нет — приложение это, так скажем, клиентский набор экранов, который запрашивает что-то у серверов и хранит у себя на телефоне. И вопрос в том, каким образом всё это хранится: какие-то текстовые файлы, ещё что-то. Это важный вопрос, если говорить о чувствительных данных.

**Спикер.** Обычно нужно исходить из того, что у злоумышленника есть так называемый доступ к устройству — в том числе рутованный доступ. Из этого нужно формировать модель угроз и думать о том, как защищаться. То есть если кто-то получил доступ к нашему девайсу, то каким образом нам хранить токен, чтобы он не смог его забрать?

**Спикер.** Какие чувствительные данные и где хранятся: в Android для этого используется SharedPreferences — это просто хранилка «ключ — значение». А есть Keystore — это зашифрованная хранилка ключей и значений. Как правило, в хороших приложениях все чувствительные данные хранятся именно там.

### 02:06:16–02:09:05 — Шифрование данных, логи устройства, кэш и папки приложений

**Спикер.** И даже при получении доступа к устройству злоумышленник не может собрать оттуда токены или что-то ещё: они зашифрованы, и он просто не сможет их переиспользовать.

**Спикер.** Если вы когда-нибудь подключали свои девайсы к компьютеру, может быть, обращали внимание, сколько логов пишет мобильное устройство и каждое приложение в частности. Если ради интереса захотите посмотреть — попробуйте подключить телефончик и посмотреть логи, увидите, насколько там огромное количество информации. Там просто запросы, запросы: кто куда обращается, кто где логинится, какие URL. Каждое приложение там просто поток данных выдаёт.

**Спикер.** Соответственно, важно, чтобы чувствительных данных приложения в этих логах не было. Здесь ещё вопрос: это приложение пишет или система пишет? Пишут и приложение, и система — а нужно ли это? Или это случайные артефакты? В каких-то случаях из-за этого возникают проблемы. В логи так или иначе пишут все: где-то подробнее, где-то не так подробно. Как правило, если при разработке используется отладка, то пишется наиболее подробно. Часть информационных кодов так или иначе можно посмотреть. И можно увидеть, что разработчики логируют больше, чем требуется.

**Спикер.** Ну и какие-то кэшированные данные, выгрузки. У каждого приложения в мобильном телефоне, на самом деле, есть своя папочка. Если в эту папочку посмотреть, можно узнать много интересного: что каждое приложение у себя имеет, что вы туда загружаете. Порой даже не обязательно иметь доступ к самому приложению, чтобы узнать, что там будет.

**Спикер.** Мы всегда исходим из того, что на устройстве может оказаться другое, недоверенное приложение. Поэтому все свои данные, хранящиеся на устройстве, следует защищать.

### 02:09:06–02:11:22 — Deep links: механика и чрезмерное доверие

**Спикер.** Дальше — тоже специфический механизм, релевантный для мобильных приложений: диплинки. Кто с этим сталкивался?

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

**Спикер.** Да, их нужно обрабатывать. Разные приложения обрабатывают разные диплинки, по своим особенностям. Какие-то приложения могут обрабатывать диплинки, связанные с оплатой, с восстановлением пароля, с привязкой девайса. Примеры на слайде указаны: перевод чего-нибудь куда-нибудь и тому подобное.

**Спикер.** И в чём проблема? Этим диплинкам приложение порой доверяет, скажем так, безусловно. То есть перевести деньги, оплатить за что-то — таких структур может быть вообще множество. И если приложение напрямую доверяет таким вещам...

**Спикер.** Вот я нажал на «Яндекс Диск», и там огромный список веб-адресов — десятка два, наверное. И это ещё только то, что он показывает: какие адреса могут быть диплинками. А чтобы узнать сам перечень диплинков, нужно разбирать сам APK и декомпилировать его, чтобы посмотреть, какие они там вообще есть.

**Спикер.** И вот если мы доверяем этому безусловно, то можно из браузера передать в приложение параметры, и приложение выполнит действие, не проверяя авторизацию и что-то ещё. Разработчики думают, что из браузера приходят безопасные вещи и можно сразу переходить в приложение.

### 02:11:23–02:13:18 — Проверка диплинков: маршруты, параметры, авторизация

**Спикер.** А атакующие тестируют, смотрят, где именно это не проверяется: подкидывают браузеру ссылки разного рода и проверяют, куда это перекидывает и как происходит дальше. Условно: хочу что-то оплатить — то есть определённый адрес, определённый путь.

**Спикер.** Если приложение построено безопасно, то оно будет проверять, откуда это пришло, что это за операция, авторизованная это операция или нет и так далее. А приложение с другой стороны может этого не проверять. Получается, это ещё один вариант входных данных для приложения: дальше кто-то их обрабатывает, кто-то им доверяет.

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

**Спикер.** Ну и, соответственно, как это проверять: эти диплинки нужно тестировать. Какие-то диплинки должны отклоняться — например, если не было соответствующей серверной операции.

### 02:13:19–02:15:14 — Экспортированные компоненты и Activity

**Спикер.** Ну и следующий элемент — экспортированные компоненты, Activity.

**Спикер.** В приложениях есть так называемая Activity. Activity — это, по сути, один из экранов приложения. Возьмите любое приложение: картинка, которую вы видите, экран — это и называется Activity.

**Спикер.** Эти Activity могут быть внутренними: то есть только изнутри приложения можно в эти Activity что-то передать, что-то с ними сделать, кнопки нажимать и так далее. А бывают экспортированные Activity. Экспортированная — значит, что любое приложение, которое находится в системе, может обратиться к этой Activity, к этому экрану и что-то там заполнить.

**Спикер.** Такое иногда происходит: ситуация, когда что-то предзаполняется. Вы что-то потыкали в каком-то соседнем приложении, перешли в другое — и там что-то предзаполнилось. Вопрос как раз в экспортировании этих Activity.

**Спикер.** Если такие механизмы требуются, то, конечно же, нужно обязательно проверять, что приходит со стороны — кто именно передаёт данные в эти Activity. Экспортировать их вообще в целом не рекомендуется, потому что, когда мы экспортируем какие-то Activity вовне, у нас возникает, грубо говоря, ситуация выхода за границу приложения. Любое приложение на девайсе может что-то посмотреть, что-то сделать в нашем приложении. Поэтому это тоже тестируется: что можно делать, а что нельзя. И по максимуму экспорт этих Activity запрещают.

### 02:15:15–02:18:01 — WebView и связка с JavaScript

**Спикер.** Дальше. Есть у нас в приложениях так называемый элемент WebView, который позволяет открыть веб-контент в контексте именно мобильного приложения и обращаться к каким-то нативным функциям устройства через этот механизм.

**Спикер.** Если, допустим, в JavaScript сайта, который открывается в мобильном приложении, есть какая-нибудь проблема, позволяющая внедрить определённый код JavaScript, то мы можем удалённо обратиться к контексту мобильного приложения — из скрипта.

**Спикер.** А что это значит? Грубо говоря, вы внедрились в какой-то сайт, а этот сайт открывается в WebView мобильного приложения. А WebView, между прочим, помимо этого запрашивает определённые операции на устройстве: например, можно запросить какие-то файлы, можно запросить доступ к камере, к фото, ещё что-то.

**Спикер.** И если есть связка нативного кода и JavaScript и при этом есть возможность внедрения JavaScript-кода, то мы можем с помощью JavaScript вызывать определённые действия на устройстве. Они могут включать в себя, соответственно, какие-то физические элементы: включение камеры или что-то ещё. Поэтому такие вещи желательно не пересекать.

### 02:18:02–02:19:59 — Итоги по мобильным приложениям, OWASP Mobile Top 10 и тестирование

**Спикер.** Ну и как с этим бороться? Мы сейчас посмотрели высокоуровнево. В мобильном мире своя терминология, поэтому взгляд именно высокоуровневый — какие проблемы здесь есть.

**Спикер.** Что делаем: по минимуму хранить секреты на устройстве; если хранить, то шифруем; проверяем диплинки; проверяем авторизацию на сервере; убираем экспортированные Activity; убираем связки WebView и JavaScript. Вот это часть элементов. А есть OWASP Mobile Top 10 для мобильных приложений — в целом пробегитесь, он примерно об этом и говорит.

**Спикер.** Как это проверять? Во многом тесты. Здесь тесты менее эффективные — точнее, они более сложные. Чтобы протестировать мобильное приложение, нужны определённые реквизиты: просто локально сборку не посмотреть. Нужен физический девайс, нужны определённые полномочия к этому физическому девайсу и так далее. Поэтому по мере возможности это всё нужно тестировать: диплинки, всякие интенты, экспортированные компоненты — это всё нужно фаззить, проверять код, проверять настройки.

**Спикер.** Ну и мобильное приложение тоже следует воспринимать как клиентскую составляющую, как клиентское устройство. Клиентам мы по умолчанию не доверяем. Доверять нужно серверу, серверным конфигурациям, серверному состоянию, авторизации на сервере. И ориентироваться больше всего, конечно же, на них.

### 02:20:00–02:23:04 — Вопрос о живом процессе разработки; MobSF в докере

**Участник.** Можно вопрос? Есть ли возможность показать, как это работает у вас? Вот у вас есть какой-то участок разработки, который вы можете показать живьём: как разработчик сидит, получает техническое задание, и как оно потом проходит дальше — «тут у тебя функция небезопасная», «тут мы проверили», отдали тестировщикам, оно вернулось обратно, опять не подошло, и так далее. Вот сам процесс и то, какие инструменты там используются. Это доступная информация?

**Спикер.** Показать это, конечно, нужно. Действительно нужно. Это, наверное, требуется отдельно. *[Окончание реплики распознано неразборчиво.]*

**Спикер.** Со стороны безопасности, со стороны проверок могу сказать, что наиболее базовым и простым элементом для того, чтобы в общем, без глубины, посмотреть на приложение, будет инструмент MobSF. Он позволяет декомпилировать андроидовский код. Вы можете взять любое приложение и загрузить APK прямо в этот самый сервис — это опенсорсное решение. Грубо говоря, поднимаете докер-контейнер, грузите туда APK и увидите там определённые результаты.

**Спикер.** Кстати, работает ещё и с iOS-приложениями, с IPA. Он тоже пытается разобрать iOS-код и посмотреть релевантные проблемы: библиотеки приложения, экспортированные компоненты; пытается искать какие-то данные — зашитые адреса, URL, какие-то токены, секреты и так далее.

**Спикер.** Если что-то делать в этой сфере, я бы вам посоветовал посмотреть именно его: у него порядка 21 тысячи звёзд на GitHub.

**Спикер.** Да, у нас демонстрационные... получилось. *[Фрагмент неразборчив.]*

**Ведущий.** Ладно, если возможно — давайте сейчас попробуем быстренько разобраться, я выделю на это время. То есть в конце быстренько скажете, что получилось. Думаю, всем будет интересно.

### 02:23:05–02:24:20 — Динамическая типизация (1С) и виды переполнения буфера

**Участник.** Вот ещё маленький комментарий. Есть типовая уязвимость — переполнение буфера. А есть, на самом деле, ещё одна типовая уязвимость, связанная с языками типа 1С, которые используют переменные с динамической типизацией. Это когда вы передаёте значение не того типа, которого ожидает приложение. Там другая история: они обрабатывают значение исходя из того типа, который приложение получило, — то есть без проверки типа.

**Спикер.** Да, я об этом немножко говорил, как и упоминал в начале: презентация — это условно три примера из десяти. А так только при переполнении буфера существует порядка пяти видов: стековое и так далее *[перечисление распознано частично]*. И то, что вы сейчас назвали, — проверка типов — соответственно, тоже расширяет картину. Здесь действительно можно расширять: разного рода проблем очень много.

### 02:24:21–02:26:56 — Десктоп: границы доверия и механизм обновления

**Спикер.** Так, давайте про десктоп. Чем десктоп у нас отличается от всего остального? Десктопные приложения — это приложения под Windows, пакет Microsoft Office, антивирусники и так далее, разного рода приложения, музыкальные плееры.

**Спикер.** Чем отличается их безопасность? Отличается она следующим: у нас граница доверия проходит между приложениями и нашим устройством, которое мы считаем доверенным.

**Спикер.** А если мы имеем дело с многопользовательскими системами — на нашем устройстве, на сервере работает несколько человек, — то граница безопасности ещё больше уменьшается.

**Спикер.** На что здесь следует обращать внимание? В первую очередь — на механизм обновления. При наличии доступа к локальной сети есть множество способов подменять DNS-ответы и адреса и выдавать свои ресурсы за те ресурсы, к которым обращаются приложения.

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

### 02:26:57–02:28:44 — Компрометация поставщика, проверка сертификатов и подпись обновления

**Спикер.** В истории было довольно много таких ситуаций, когда компрометировали какого-нибудь поставщика, компрометировали механизмы обновления и рассылали новую версию клиентам. Клиенты успешно обновлялись, успешно устанавливали себе вирус и так далее, а злоумышленники достигали своих целей.

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

**Спикер.** То есть здесь работают три вещи: механизм шифрования, проверка легитимности сервера обновлений и проверка подписи непосредственно самого пакета обновления.

### 02:28:45–02:31:41 — Собственные обработчики протоколов и IPC: доверие к localhost

**Спикер.** Ну и дальше — механизм, в целом похожий на то, что происходит с диплинками. У некоторых приложений есть собственные обработчики протоколов, собственные правила и ассоциации. И такого рода собственные обработчики протоколов могут, например, выполнять какие-то действия без проверки легитимности этих операций: кто их инициировал, какой пользователь, имеет ли он вообще возможность такое сделать.

**Спикер.** Допустим, приложение оперирует под административным аккаунтом. А обычный пользователь может попробовать через собственный обработчик протокола передать в это приложение какие-то данные или инициировать какое-то действие. Поэтому обязательно нужно проверять авторизацию и обязательно нужно проверять, что конкретно этот обработчик позволяет делать.

**Спикер.** Дальше — IPC, inter-process communication, локальное взаимодействие между сервисами, между процессами. Что это значит? Как правило, приложение взаимодействует локально через какие-то сокеты: на Unix — через сокеты, на Windows — через каналы. Это локальный способ межсервисного взаимодействия. Часто бывает, что одно приложение имеет сразу несколько сервисов, и сервисы друг с другом обмениваются какими-то данными: они выставляют, публикуют так называемые сокеты и именованные каналы — в зависимости от операционной системы — и по ним обмениваются данными.

**Спикер.** А ситуация возникает такая: разработчики предполагают или допускают, что раз всё работает на локальном хосте и в интернет не выходит, то любое взаимодействие между сервисами заведомо можно считать безопасным. Но на самом деле, если у вас система многопользовательская и там разные привилегии — пользователь, администратор или чуть больше, — то это допущение сразу же разрушается. И любое доверие к тому, что «это localhost, значит ничего проверять не нужно», просто разбивается.

### 02:31:42–02:34:03 — Привилегии в IPC, конфигурации и секреты

**Спикер.** И какой-нибудь непривилегированный пользователь отправляет другому сервису команду на его остановку, а сервис принимает эту команду без проверки — исходя из того, что её якобы запросил администратор.

**Спикер.** Поэтому внутреннее, межсервисное взаимодействие, конечно же, должно следовать контролю доступа операционной системы и использовать его: проверять привилегии, кто может запрашивать те или иные действия, а кто не может, администратор это запрашивает или нет.

**Спикер.** Ну и там базовая история — тоже конфигурации и секреты. У нас приложения часто несут с собой какой-нибудь конфиг. И в этом конфиге могут лежать API-ключи, могут быть флаги: платные, бесплатные функциональности, которые можно включить через флаг в конфиге, политики и так далее.

**Спикер.** И если, опять же, у нас система многопользовательская, а какие-то конфигурации не имеют правильного контроля доступа или явно содержат в себе секреты просто в текстовом формате, — ну, конечно же, это проблема в случае многопользовательского устройства. Поэтому, если у нас есть несколько потенциально желающих пользоваться системой, обязательно нужно секреты прятать. Ключи должны храниться защищённым образом. *[Формулировка неразборчива.]*

**Спикер.** Конфигурация должна быть минимальной, с минимальным количеством секретов. А флаги, включение каких-то платных функций, вообще должны проверяться с сервером, а не по конфигурации. И, соответственно, нужно иметь в виду, что приложение может хранить у себя целый ряд таких данных.

### 02:34:04–02:36:35 — Как тестировать десктоп и что стоит расширять для студентов

**Спикер.** Проблематику мы в целом в каждом пункте уже разобрали. Дальше всё то же самое сведено в одну табличку — как это проверять.

**Спикер.** Как и в вебе, мы тестируем разного рода взаимодействие между сервисами, пробуем из-под обычного пользователя вызывать административные функции, вызываем разные кастомные протоколы. И проверяем, по сути, насколько там что-то можно менять.

**Спикер.** Ну, это был десктоп. Что меняется в следующем разделе *[название раздела распознано неразборчиво]* — давайте об этом на следующей лекции: она в целом об этом и будет.

**Спикер.** Соответственно, мы с вами разобрали сейчас в одной презентации сразу несколько тем: посмотрели и про память, и про другие направления безопасности *[перечисление распознано неразборчиво]*, пробежались по верхам и посмотрели, какие общие проблемы в целом есть.

**Спикер.** Если рассматривать этот раздел в качестве того, что нужно рассказать студентам, то желательно его расширять. У нас, конечно, не так много времени, чтобы на каждый раздел сделать отдельную лекцию, — за неделю это не сделать. Но так или иначе для студентов, конечно, лучше погружаться чуть более подробно.

**Спикер.** Это была предпоследняя презентация, осталась последняя. [Объявляется короткий перерыв.]

### 02:36:36–02:38:45 — Неформальный разговор в перерыве у ноутбука

*[Редакторская пометка: после объявления перерыва на записи остаётся неформальный разговор у ноутбука о работе с файлами в некотором инструменте. Реплики короткие и распознаны фрагментарно; говорящие по записи не различаются, поэтому ходы отмечены обобщённо.]*

**Участник.** Теперь я понял, зачем. Смотри, вот это — а вот это. Я сейчас посмотрел. *[Неразборчиво.]*

**Участник.** Можно вот так вот. *[Неразборчиво.]*

**Участник.** Раньше, когда я оставлял какую-либо фотографию, она у меня дублировалась. А дальше очень удобно. То есть я, когда писал, — видишь, много кода, — и вот это всё дублировалось. Сейчас не дублируется. Вот сейчас откроем здесь файлы.

**Участник.** Файлы по умолчанию. Вот этот — по умолчанию.

**Участник.** А тут получается, что в папке указаны... в папке, которая уже текущая. *[Дальнейший разговор не восстанавливается: реплики неразборчивы.]*

## Фрагмент 3

*SSDLC, роли и модели разработки, моделирование угроз и фаззинг, демонстрации, образовательные стандарты и отбор стажёров.*

### 00:00:00–00:02:30 — Что такое безопасная разработка и анализ требований

**Ведущий.** Что такое безопасная разработка? Чем безопасная разработка отличается от обычной?

**Ведущий.** Мы рассмотрим циклы разработки, этапы, модели разного рода, роли в проекте разработки и то, что безопасность во всё это приносит.

**Ведущий.** Вот схема, которую я вывел на слайд. Она включает в себя весь процесс. Если в целом: сначала выставляются требования к продукту, планируется разработка, дальше проектирование — то есть создаётся архитектура, решение разрабатывается, тестируется и развёртывается. Развёртывается — значит, где-то публикуется: либо в интернете, либо во внутренней сети, либо запаковывается для установки.

**Ведущий.** Зачем для разработки вообще используются какие-то циклы? Для того, чтобы сформировать процесс, уменьшить затраты, повысить качество, сделать процесс предсказуемым, понять сроки, понять ресурсы и привести всё это к представимому виду.

**Ведущий.** Этапов шесть. Первый — анализ требований. Что такое анализ требований? Перед разработкой любого продукта сначала выставляется определённый перечень требований. Какие требования бывают? Бывают функциональные требования и бывают нефункциональные. Функциональные — это то, как и где продукт должен действовать в каком конкретном сценарии. Нефункциональные — это его критерии качества.

**Ведущий.** Качество, производительность, отказоустойчивость, безопасность и так далее. Безопасность у нас является нефункциональным требованием к программе.

### 00:02:31–00:04:26 — Планирование, проектирование архитектуры, разработка и тестирование

**Ведущий.** Дальше начинается планирование. Сначала оценка: оцениваются затраты и ресурсы. Грубо говоря, составляется экономический план разработки, определяются сроки, и сроки декомпозируются. То есть срок закладывается на этап и декомпозируется дальше.

**Ведущий.** Затем проектирование архитектуры. Перед разработкой любого нового программного обеспечения сначала производится как минимум базовое описание: из каких компонентов оно будет состоять, какой язык программирования будет выбран, какая база данных там будет, какой сервер, где это будет хоститься в инфраструктуре, плюс-минус как она будет настроена, как это будет опубликовано или не опубликовано.

**Ведущий.** Здесь — полный перечень решений на высоком уровне о том, как всё будет выглядеть.

**Ведущий.** Разработка — следующий этап. Высокоуровнево определили, как это будет работать; разработка — это уже рабочая часть процесса, когда из архитектуры, из квадратиков, делается рабочее решение.

**Ведущий.** Разработка непосредственно связана с тестированием, и они идут бок о бок. В зависимости от модели разработки это немного может отличаться, но в общем и целом так: разработали что-то, написали юнит-тесты, сразу же протестировали, проводятся какие-нибудь автоматизированные тесты, затем ручные тесты.

### 00:04:27–00:06:38 — Развёртывание и каскадная модель Waterfall

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

**Ведущий.** Развёртывание — это любой способ введения программного обеспечения в продакшен, в рабочую среду.

**Ведущий.** Давайте поговорим про модели. Моделей много, они плюс-минус похожи, какие-то наследуют одна другую. Но в общем и целом их большое множество.

**Ведущий.** Самая простая и самая старая модель — Waterfall. Эта модель часто используется в около-государственных заказах: надо разработать нам какую-то систему — формируется техническое задание.

**Ведущий.** Сначала формулируются требования. Проектируется, собирается подрядчик, реализуется, тестируется, и финальное решение отдаётся: пожалуйста, готово. То есть это долгий процесс, довольно бюрократичный. Как правило, больше всего времени занимают первые этапы этого процесса: нужно собрать требования, нужно всё спроектировать. И проектируется всё настолько подробно, что становится понятно, что именно ожидается и что всё из этого сразу будет выполнено. Уже в головах есть финальное понимание, как это всё должно выглядеть, причём довольно детальное. Вопрос в том, что, чтобы такое стартовать, нужна довольно серьёзная подготовка.

**Ведущий.** И это занимает большое количество времени за счёт того, что процесс конечный и в нём отсутствуют этапы ретроспективного анализа.

### 00:06:39–00:09:29 — Итеративная модель на примере интернет-магазина

**Ведущий.** Про Agile давайте сделаем вот так: начнём с итеративной модели, потому что Agile — это её подмножество.

**Ведущий.** Итеративная модель — это модель, которая по сути представляет собой разработку определённой итерации. У нас есть первичное определение того, как будет выглядеть приложение. Например, мы делаем магазин соков. В первой версии мы говорим: пожалуйста, есть базовая страничка, где показывается, какие товары есть в магазине. Пользователь может зайти и посмотреть. Это делается, проверяется, тестируется.

**Ведущий.** Следующий этап: сейчас мы сделаем авторизацию в этом магазине. Пришли, сделали авторизацию, сделали карточки товара.

**Ведущий.** Дальше следующий этап: договорились, будем делать процесс заказа, поддержку корзины и так далее. И вот так, итеративно, постепенно, по квадратикам, по кусочкам, формируется готовое решение.

**Ведущий.** Минус здесь обозначен — риск неконтролируемого роста затрат и ресурсов.

**Ведущий.** Планирование итерации может немного переоценивать возможности разработчиков, их пропускную способность. Это происходит за счёт того, что итерации могут быть слишком длительными. Например, итерация может длиться месяц. За месяц очень много может поменяться: кто-то может уволиться, кто-то может заболеть. Поэтому такая модель чуть-чуть хуже управляется.

**Ведущий.** Agile — разновидность итеративной модели. Это не столько модель, сколько подход к разработке; внутри Agile есть ещё несколько подходов.

### 00:09:30–00:11:26 — Agile: двухнедельный спринт, оценка задач, ретроспектива

**Ведущий.** Чем Agile отличается от итеративной модели? Можно обозначить, наверное, следующее. В Agile не обязательно, чтобы у заказчика — того, кто хочет этот продукт разработать, — была финальная картина того, что должно получиться.

**Ведущий.** В конце у него может быть какая-то идея. Идея декомпозируется плюс-минус на промежутки. И в эти две недели происходит примерно следующее: определяется количество разработчиков, сколько у них времени, сколько задач есть. И все задачи, грубо говоря, оцениваются: эта задача займёт столько-то часов, эта задача столько-то часов займёт, столько-то стоит. Все задачи, которые влезают в эти две недели, разбиваются по разработчикам.

**Ведущий.** И в рамках своей пропускной способности в течение двух недель они разрабатывают то, что у них получается. Они уже не планируют на несколько итераций сразу — планируют именно ближайшую итерацию.

**Ведущий.** Плюсы и минусы этого подхода — в его гибкости. С одной стороны, всё может меняться, причём меняться довольно кардинально. С другой стороны, иногда за счёт этого сроки могут затягиваться.

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

### 00:11:27–00:13:01 — V-образная модель: Waterfall с приёмкой на каждом этапе

**Ведущий.** Что-то переносится, что-то выкидывается, что-то переоценивается. За две недели появляется больше понимания о том, как должно выглядеть программное обеспечение, какой должна быть архитектура, и всё подряд может меняться дальше.

**Ведущий.** V-образная модель — это такой Waterfall, только прокачанный. В чём идея? У вас есть тот же самый Waterfall: собираем требования, делаем анализ, проектирование и так далее. Только на каждом этапе у нас есть очень плотное взаимодействие с заказчиком. То есть мы собрали требования, завалидировали, проверили — всё хорошо. Заказчик проверил анализ и проектирование.

**Ведущий.** Протестировали — заказчик проверил. Разработка: так, так, так, что-то там не доработали. Значит, сказал: давайте дорабатывайте. Дорабатывается — и так далее. Заказчик подтвердил. На каждом этапе существует набор так называемого приёмочного тестирования, и мы идём по этой модели вниз, но с обязательной обратной связью.

### 00:13:02–00:14:59 — Big Bang и спиральная риск-ориентированная модель

**Ведущий.** Модель Big Bang. Это стандартная модель, здесь она приведена, скажем, для информации. Условно: собрались пять человек — давайте напишем программу. Давайте пишем. Сделали, хорошо, никакого фреймворка. В идеале это небольшая команда, готовы работать, особо не заморачиваются, просто делают.

**Ведущий.** Спиральная модель. Её особенность именно в рисках. На каждом этапе этой модели происходит оценка рисков и того, насколько эти риски митигируются и компенсируются. Это можно даже назвать риск-ориентированной разработкой.

**Ведущий.** Это для систем, для которых очень важна отказоустойчивость и безопасность: медицина, медицинские устройства, банковские приложения и подобное. Их разрабатывают исходя из требований и исходя из потенциальных рисков. У нас есть риски, и самое важное — чтобы они были закрыты. Исходя из этих рисков разрабатывается функционал: на каждом этапе определяются риски, анализируются, разрабатываются меры и тестируется, что эти риски действительно закрыты. Это долгая разработка, это сложная разработка, очень много денег.

### 00:15:00–00:17:08 — Прототипная модель и роли: заказчик, профильные эксперты, владелец продукта

**Ведущий.** Используется в критически ориентированных сферах.

**Ведущий.** Прототипная модель. Это, можно сказать, вариант, когда особо непонятно, что хочется. Тогда делается прототип. Прототип прорабатывается, согласовывается с заказчиком: похоже на то, что заказчик хочет, или нет? Похоже — значит, продолжается. Не похоже — прототип дорабатывается.

**Ведущий.** Ну и роли в проекте. Какие у нас роли? Есть заказчик. Кто у нас заказчик? Это тот, у кого кошелёк. Тот, кто хочет получить финансовый результат, какую-то выгоду или закрыть ту или иную цель. Тот, кто финансирует проект.

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

**Ведущий.** То есть специалисты конкретной области. Дальше — владелец продукта, продакт-менеджер. Это человек, который отвечает за продуктовую составляющую. Для него важно, чтобы были пользователи, чтобы функции появлялись вовремя, чтобы всё было сделано и желательно бесплатно, быстро и вчера. Он дорабатывает требования, что-то документирует, проверяет.

### 00:17:09–00:19:31 — Руководитель проекта, технический руководитель, разработчики и тестировщики

**Ведущий.** Руководитель проекта — это человек, который уже работает непосредственно с командой, проджект-менеджер. Грубо говоря, он планирует работы, контролирует результат в контексте. Он понимает, где сейчас разработка, чего не хватает, разруливает какие-то ситуации, раскидывает задачи — и вот его все ненавидят.

**Ведущий.** Технический руководитель. В ряде случаев его можно назвать аналитиком. Это человек, который требования бизнеса переводит на технический язык. Требования бизнеса, как правило, довольно размыты: должна быть система, которая что-то делает.

**Ведущий.** Технические руководители говорят: у нас должна быть система, которая продаёт. Они выделяют какие-то элементы, разделяют их так-то и так-то, совместно с архитекторами анализируют и, грубо говоря, переводят это на язык, который поймёт разработчик. Задачи дадут — там уже конкретно получится задача. Это задача технического руководителя и аналитика. Соответственно, для разработки он транслирует эти фичи разработчику на языке разработчика. То есть перевод бизнеса на технический язык.

**Ведущий.** Дальше разработчики — люди, которые пилят код. Тут понятно. Тестировщики — люди, которые проверяют, сколько разработчики что наделают: находят дефекты, говорят разработчикам, что нужно доработать, показывают им ошибки. И совместно с разработчиками доводят до того, чтобы по итогу у нас получился хороший продукт.

**Ведущий.** Ну и вот, собственно, мы подходим к жизненному циклу — к безопасной разработке. Что она приносит в обычный цикл разработки?

### 00:19:32–00:21:20 — SSDLC: что безопасность добавляет к каждому этапу

**Ведущий.** Если вернуться к этапам, то между этапами — или, можно сказать, вместе с этими этапами — появляются некоторые дополнительные элементы. Что они из себя представляют?

**Ведущий.** Между планированием и требованиями мы оцениваем риски. То есть в общем и целом оцениваются риски. Помимо функциональных требований к продукту появляются требования безопасности, которые по сути являются нефункциональными требованиями продукта.

**Ведущий.** При составлении архитектуры продукта производится также моделирование угроз, анализ поверхности атаки и так далее.

**Ведущий.** Что у нас присутствует в процессе разработки? Присутствуют инструменты: статические анализаторы, динамические анализаторы, композиционный анализ, линтинг и так далее. Полный набор security-проверок добавляется в процесс разработки.

**Ведущий.** В процесс тестирования у нас добавляются тесты безопасности, в виде, может быть, интеграционных тестов.

**Ведущий.** А на этапе эксплуатации у нас уже непосредственно процесс vulnerability management — обработка появляющихся уязвимостей и, соответственно, управление этим процессом.

**Ведущий.** Почему это важно? Потому что мы уже обсудили, что безопасная разработка — это не что-то факультативное.

### 00:21:21–00:23:21 — Фреймворки безопасной разработки, обучение, инструменты, моделирование угроз

**Ведущий.** Процессы и инструменты в целом мы с вами уже вкратце посмотрели. Всё начинается, конечно же, с обучения.

**Ведущий.** Есть несколько фреймворков безопасной разработки. Есть фреймворк от OWASP — Software Assurance Maturity Model, то есть модель зрелости. Есть и другие *[название второго фреймворка неразборчиво]*. В общем и целом они включают плюс-минус одни и те же вещи.

**Ведущий.** Всё начинается с обучения разработчиков. Это база. Если разработчики не обучены безопасности, дальше говорить не о чем. Дальше — качественные требования и код, проверка архитектуры, моделирование угроз, обязательно код-ревью, статический и динамический анализ, тесты разного рода, дополнительные проверки: проверка секретов, проверка контейнеров — проверки всего, что можно, что есть в коде. И проверка отчётов, и исправление найденного.

**Ведущий.** Инструменты мы с вами уже немножко затронули: сканеры, анализаторы разного рода, фаззеры, анализ трафика, перехватчики трафика, инструменты тестирования.

**Ведущий.** Если говорить про моделирование угроз — что оно вкратце из себя представляет? Анализируются требования безопасности и архитектура продукта, и оценивается, насколько архитектура продукта соответствует этим требованиям безопасности. Соответственно, мы имеем определённые фреймворки для того, чтобы понять это соответствие.

### 00:23:22–00:25:00 — STRIDE, CVSS и его векторы

**Ведущий.** Методологий моделирования угроз множество. Самое популярное сейчас — STRIDE. Каждая буква означает свой вид угрозы *[расшифровка букв в записи неразборчива]*. Соответственно, сценарий по каждой букве разбирается: может ли он произойти, и так далее.

**Ведущий.** Таких фреймворков множество. CVSS вы все знаете — это тоже один из фреймворков оценки уязвимости, оценки угроз. Если CVSS разобрать, у него есть определённые векторы. Вектор включает в себя влияние на целостность, конфиденциальность, доступность; удалённая атака или нет; наличие необходимых привилегий для её осуществления.

**Ведущий.** CVSS также может использоваться для приоритизации.

**Ведущий.** Динамический анализ, на самом деле, разбивают на разные термины. Если говорить про языки, которые работают с памятью, здесь больше говорят про проверку собранных бинарных файлов *[название инструмента неразборчиво]* — она проверяет наличие определённых флагов, правильность сборки приложения, его конфигурацию и так далее.

### 00:25:01–00:27:13 — Динамический анализ, скорость сканера в CI/CD и вопросы участников

**Ведущий.** То есть именно проблемы, связанные со сборкой. Если это веб, то под динамическим анализом подразумевается именно тестирование работающего приложения, соответствующие инструменты *[названия инструментов неразборчивы]*.

**Ведущий.** В общем и целом динамический анализ — это, скажем, проверка уже собранного решения. Это проверка либо уже развёрнутого веб-сервера, либо собранного приложения в консоли.

**Ведущий.** Ну и понятно, какие требования к сканеру: чтобы у нас в процессе сборки, в процессе CI/CD он работал быстро, мало потреблял, и всё было хорошо. Примеры инструментов можно посмотреть тут, на слайде. Сюда можно добавить ещё и другие.

**Ведущий.** Если говорить про работу с памятью — что они там находят и какого рода это проблемы, мы с вами уже обсуждали.

**Участник.** Можно вопрос?

**Ведущий.** Конечно.

**Участник.** У вас на корпоративном уровне закупаются платные версии вот этих сканеров?

**Ведущий.** Мы использовали, да. В целом я так скажу: каких-то особо выдающихся результатов от этого не было. Как правило, у меня не было ситуации, чтобы я прямо удивился. То есть я считаю, что имеющихся у компании версий достаточно, чтобы получать результаты.

**Участник.** А какая наиболее популярная модель при разработке?

**Ведущий.** У нас, на самом деле, по-разному используется. У нас, наверное, больше итеративная. Я бы сказал, у нас не Agile: у нас именно итерации.

### 00:27:14–00:29:45 — Фаззинг и кейс «докажи заказчику, что фаззинг не нужен»

**Ведущий.** Фаззинг-тестирование. Что у нас происходит? Мы подаём разные случайные, некорректные данные с целью выявить падение программы, неожиданное поведение. Это, опять же, по большей части для языков, которые работают с памятью самостоятельно.

**Участник.** Вопрос: можешь ли ты доказать, что проекту — а у нас C++ и C, при этом легаси десяти-, двадцатилетней давности — не нужен фаззинг? Сможешь доказать?

**Участник.** Условно, ты заказчик. Ты говоришь: я разрабатываю этот продукт, я считаю, что фаззинг не нужен. Он говорит: докажи. А ты — что ты можешь доказать, что фаззинг не нужен?

**Ведущий.** Если вопрос в том, чтобы обосновать, что я считаю, что фаззинг нужен или не нужен... То есть вопрос в том, чтобы обосновать, или нет?

**Участник.** Нет-нет, именно доказать. Или это глупая история? Просто я вас не вижу.

**Ведущий.** Хорошо.

**Участник.** Нет, просто есть опыт взаимодействия с одной организацией. Они доказали заказчику, что на проекте на C++ фаззинг не нужен. Но я был в шоке. Вот я просто мнение твоё хотел спросить: как ты считаешь?

**Ведущий.** Я не помню такого.

**Участник.** Ну, они доказали и, как бы, сэкономили прилично денег: ни специалистов, ни серверов, ничего не потребовалось.

**Ведущий.** То есть неразумная история?

**Участник.** У них были какие-то обоснования. Две страницы обоснования: обосновали, две странички зарядили. Потому что, типа, у нас требования зафиксированы, мы будем работать на закрытом контуре, подключения к интернету не будет — поэтому фаззинг не нужен. Такого рода обоснования.

**Участник.** Пользовательский ввод считался доверенным. Если пользователей много... Модель угроз просто не разрабатывали, поэтому там ничего и не было определено. *[Реплика распознана фрагментарно.]*

**Участник.** Спасибо.

### 00:29:46–00:32:15 — Что делает фаззер; итоги: SAMM и Microsoft SDL

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

**Ведущий.** Один из самых популярных фаззеров — *[название неразборчиво]*.

**Ведущий.** Завершаем презентацию, давайте попробуем сейчас подвести итоги. У нас есть процесс разработки программного обеспечения. В этот процесс разработки программного обеспечения мы встраиваем этапы безопасной разработки, которые начинаются с обучения и заканчиваются обработкой инцидентов где-нибудь в рабочей системе, разбором логов и так далее. Он включает в себя множество элементов.

**Ведущий.** Для этих шагов безопасности есть определённые модели зрелости. Я рекомендую вам посмотреть проект SAMM — Software Assurance Maturity Model.

**Ведущий.** И такой старенький, но действенный фреймворк — Microsoft SDL. Он тоже в целом корректно, интересно и качественно описывает то, как безопасная разработка встраивается в обычный процесс разработки и почему это важно.

**Ведущий.** В общем, мы с вами справились. Всех поздравляю с завершением курса по безопасности приложений. Сейчас коллега проведёт лекцию про искусственный интеллект, и на этом у нас обучение будет завершаться. Спасибо вам.

### 00:32:16–00:33:02 — Короткая пауза перед заключительной лекцией

**Ведущий.** Две минуты.

**Ведущий.** Я думаю, ты коллеге ничего не сказал.

**Ведущий.** *[Реплика распознана неразборчиво: речь идёт о том, что говорящему не нравится формулировка.]*

### 00:33:03–00:36:42 — Демонстрация: вредоносный код внутри изображения

**Участник.** А почему овечки на экране?

**Ведущий.** Это надо как-то объяснить. Сегодня во время занятий была такая задачка, и когда мы её делали, наткнулись кое на что, и мне стало интересно, как это всё работает. В итоге быстро-быстро было слеплено приложение, которое демонстрирует как раз внедрение вредоносного кода в картинку.

**Ведущий.** И вот на примере какого-нибудь чата можно посмотреть. Например, у нас есть злоумышленник и есть вторая сторона — добрая овечка. У них, допустим, есть какая-то переписка.

**Ведущий.** «СМС тебе по вечерам приходят. Спишь?» Обычное приветствие.

**Ведущий.** Он отправляет картинку — не будем говорить, что это вечернее фото.

**Ведущий.** И в этой картинке зашит код. Причём в коде зашита защита, чтобы он сам себя не заразил. Как только я сейчас открою овечку внутри своей картинки, исполнится вредоносный код, который может получить чувствительную информацию и отправить от лица доброй овечки какое-нибудь сообщение — может быть, с извлечёнными чувствительными данными. И злоумышленник получает от овечки сообщение. Этим самым показывается, что вредоносный код может прятаться даже в картинке.

**Ведущий.** Код картинки — сейчас, секундочку.

**Участник.** То есть фишка вот такой специально сгенерированной картинки, правильно понимаю? А это обычная картинка?

**Ведущий.** И она может исполняться. *[Часть реплик о том, как это выполняется в системе, неразборчива.]*

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

### 00:36:43–00:38:08 — Анонс партнёрской образовательной программы

**Участник.** А это на GitHub выложишь?

**Ведущий.** Смотрите, у нас будет небольшое мероприятие, и мы просто хотим позвать. Мы совместно с партнёрской организацией проводим небольшую обучалку, поэтому позовите ваших студентов. Оно бесплатное и доступное, но записаться надо и пройти предварительный отбор.

**Ведущий.** Отбор фильтрует: если человек не из ИТ и не проходит первоначальный этап, он туда просто не попадает.

**Ведущий.** У нас четыре направления, которые делает наша команда: промпт-инжиниринг, информационная безопасность, корпоративная защита и системное администрирование. Собственно говоря, вот, всех зову, ребята. Всё, уложился.

### 00:38:09–00:40:24 — Переход к заключительной лекции: терминология ИИ-агентов и её источник

**Участник.** А что, поиск ничего не находит в мессенджере? *[Часть реплики распознана неразборчиво.]* Проверь.

**Ведущий.** Так, и мы, получается, переходим к заключительной лекции нашей образовательной лаборатории.

**Ведущий.** Поставь «собачку» — символ `@`, а дальше без разницы, она сама ищет. Без «собачки» поиск ничего не находит.

**Спикер.** Добрый вечер. У меня как раз осталось три минуты, поэтому давайте быстро пойдём.

**Спикер.** Первое — это вопросы и ответы. Вчера в конце встречи мы немножко обсудили терминологию — ту терминологию, которую я привозил. Я показывал источники: кому-то показал, кому-то не показал. Мы там некоторое время после занятия обсуждали.

**Спикер.** В любом случае, раз вопрос был и активно обсуждали, скажу пару слов. Тот термин относительно агентов, который был приведён, — он прямо из книги. Понятно, что это не совсем учебник. И вопрос, откуда брать терминологическую цитату: всё можно использовать, можно и не использовать. Просто внутри контекста данной книги автор даёт подобное определение и говорит, каким образом он дальше использует взаимосвязь понятий — там выстроена некоторая система понятий. Но он пишет не учебник и не нормативный документ.

### 00:40:25–00:42:19 — Книга по агентам: цена, срок жизни и устаревание переводов

**Спикер.** По поводу данной книжки хотел бы упомянуть следующий аспект. Она прямо свежая вышла и стоит 2400. Вчера нашли за 2400, я брал что-то за 1300, по-моему.

**Спикер.** Книжка прямо свежак. И дело в том, что правильно нужно было бы сказать так: её стоит покупать, если вам нужно было программировать агентов вчера. Если вам нужно будет программировать агентов завтра, то она, возможно, успеет устареть. Вот такая особенность.

**Спикер.** Прикольно, что даже тот же самый чат-бот с генерацией и обращением к источникам выдаёт устаревшую информацию относительно того, как это делается.

**Спикер.** Надо сказать, что эта книжка посвящена агентам в разрезе сберовских технологий. И можно немножко сэкономить — посмотреть на сайте Сбера, там примерно то же самое. Здесь немножко больше объяснений, но особенность вот такая.

**Спикер.** Поэтому, когда я её взял, я начал использовать сразу: нет смысла её взять и положить, а потом думать — ну, сейчас я когда-нибудь возьмусь. А когда я возьмусь, там вообще уже не будет этих технологий. Может оказаться именно так. Поэтому книжка не должна лежать.

**Спикер.** С переводами та же история. Вчера я показывал некоторое количество стандартов и документов, которые вышли. На самом деле они вышли в 24-м году, переведены в 25-м, а стоит на них 26-й. Возьмём — будет 26-й год, а информация 24-го.

**Спикер.** Просто чтобы кто-нибудь не взял, потом отложил, потом достал — а нам уже сказали, что тут вот так. Вот такая история с книгой. И когда я её приносил, мне говорят: а ты что там, офигел, такую книжку взял? Я говорю: да, надо прямо сразу использовать.

### 00:42:20–00:44:33 — Определения ИИ-агента в документах OWASP и паттерн ReAct

**Спикер.** А теперь пару слов про терминологию — про сам термин, про определение агента.

**Спикер.** Документы, про которые я говорил, — материалы OWASP, посвящённые большим языковым моделям, агентным системам и прочему подобному, — приводят примерно такое же определение. И там прямо видно: авторы, которые ссылаются на агентов, открыто пишут, что взяли определение какого-то автора из статьи 2021 года. А дальше уже вопрос: какое определение конкретнее — вот это или вот это? Оно прямо вот такое.

**Спикер.** На самом деле большинство определений, которые мы встречаем применительно к агентам, примерно про одно и то же. Есть цель. Есть какая-то автономность — система что-то сама решает. И есть интерфейс взаимодействия с внешним миром, со средой. Последнее — это как раз про использование тулинга, про обращение к внешним средствам.

**Спикер.** Пока мы с вами здесь сидели, всего два часа назад Сбер выпустил свой инструмент *[название распознано неразборчиво]*. Новость только что опубликовали. Там рассказывают, как он всё делает сам: сам себя переписывает, перезаписывает что-то и прочее. Может, новость прочитать? Это прямо вот сейчас произошло.

**Участник.** Давайте.

**Спикер.** *[Короткая реплика о том, на что переключиться, распознана неразборчиво.]* Два часа назад — можно просто смотреть прямо у Сбера.

**Спикер.** Что ещё есть из области описания того, что является агентом? Это опять из того же материала OWASP по агентным системам — того, где разбираются угрозы и идентификация рисков. Там указано, что путей на самом деле множество. И там же есть описание, что вообще такое агент или агентная ИИ-система: как правило, она состоит из следующих элементов. Явно говорится про ReAct. Вот этот ReAct-паттерн: сначала идёт анализ, потом какое-то действие, потом результат возвращается.

### 00:44:34–00:46:36 — Поле цели, автономный цикл и терминологические глоссарии

**Спикер.** Результат возвращается обратно в модель, и определяется, необходимо ли дальше делать какие-то действия или цель агента уже достигнута. Здесь, например, написано что-то вроде objectives. Как правило, в современных агентах, когда мы смотрим их реализации, это называется полем цели. И когда это поле установлено, агент крутится до тех пор, пока не получит результат. В обычном режиме промежуточный результат он не отдаёт — хотя есть режим, когда он может прямо показывать, как он думает.

**Спикер.** У нас в своё время, когда формировали разного рода стандарты, обращались к разным базам — и к нашим, и не к нашим. Предположим, посмотрим на них. У них есть прямо глоссарий, посвящённый тому, какие термины используются. Они просто собрали из всех своих документов — и не только своих, там есть ссылки на разного рода документы, — и можно посмотреть аналоги касательно агента в разрезе AI, искусственного интеллекта.

**Спикер.** У них такое определение начинается со слова «программа»: это программа, а не что-то там непонятное. И дальше описывается её функционал, некоторые характеристики. То есть описание того же типа: интеракция, опять environment — среда. Опять есть такой-то блок. Наверное, это и есть основные характеристики понятия, по которым мы отделяем его от каких-то других конструкций.

**Спикер.** Глоссарий довольно неплохой, само понятие в нём присутствует. Я вытащил его прямо из документа. Откуда они его взяли — отдельный вопрос, но термин в глоссарии действительно есть. *[Часть рассуждения о том, какие позиции в глоссарии не используются, распознана неразборчиво; речь, скорее всего, о возможности пользователя взаимодействовать с системой.]*

### 00:46:37–00:50:11 — Терминологические стандарты: около 200 терминов и спор о переводе

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

**Спикер.** Этот стандарт содержит огромное количество терминов — порядка двухсот. Там прямо отдельная часть посвящена именно терминологии. И каждый термин не просто «нафигачен»: вот этот про это, а вот этот про то. Нет — большинство терминов состоит из компонентов, которые тоже описаны в этой же терминологической базе. Максимальная краткость, максимальное отражение сути и составляющих элементов, со ссылками на тот же самый стандарт.

**Спикер.** В данном случае меня интересовал вопрос: что такое архитектура безопасности в рамках задач, которые мы решаем, из каких элементов она состоит. Безопасная архитектура чего? Архитектура безопасности чего? Автомобиля. У них там всё в контексте автомобиля — это всё про автомобиль.

**Спикер.** И здесь написано: совокупность элементов, удовлетворяющих требованиям безопасности. Дальше поехали. Мы пытались сравнить редакции данного стандарта — там были и редакции 2014 года. Я просто себе со странички выгрузил.

**Спикер.** Дальше интересный момент. Смотрим стандарты, связанные с этой же темой, — 2023-й, 2024-й и 2025-й годы. И вот здесь интересный перевод. В английском варианте везде этот термин называется security architecture. А в русском переводе одна версия звучит как «архитектура безопасности», а в другой — «безопасная архитектура».

**Спикер.** Мы же любим цепляться за каждую букву, за каждое слово. «Архитектура безопасности» — это, наверное, какая-то подсистема безопасности, у неё есть описание, у неё есть архитектура. А с другой стороны, есть вообще архитектура чего-то, и она обладает свойством безопасности — «безопасная архитектура». Для нас как будто это разные понятия. Но когда делается переведённый стандарт, получается вот такая штука.

**Спикер.** Такой же самый подход в аналитике мы использовали при формировании, например, стандарта безопасной разработки. Когда набирали все эти требования: какие должны быть цели, какие свидетельства. Я даже в старых вариантах у себя нашёл, что там был ещё четвёртый элемент — подтверждающий элемент, который в своё время при разработке мы убрали. И такая визуализация позволяет посмотреть хотя бы визуально, а возможно, и автоматизированными средствами проверить те терминологические базы, которые вообще используются.

### 00:50:12–00:54:25 — Демонстрация внутреннего агента: инструменты, цикл вызовов и middleware

**Спикер.** Дальше немного возвращаемся к вопросу, связанному с агентами. Поговорили, что есть цель, есть goal, что что-то само собой крутится — autonomous, автономная система. Ну вот пример. Это я прямо взял нашу внутреннюю страничку. Соответственно, здесь стоит агент, и мы с ним общаемся.

**Спикер.** Каким образом? Какой функционал из того, о котором говорится в определении ИИ-агентов, есть в этом интерфейсе? Явно указывается, например, слева, что есть некоторый набор инструментов, которые активируются при вопросе. Когда мы задаём агенту вопрос, он сам решает, что вызывать.

**Спикер.** Есть граф, который строит, например, вызовы, когда нужно что-то вызвать. Можно делать такие обработчики, ставить middleware — и дальше смотреть, что будет. Вот здесь он выделяет: «так, с этим вопросом я смогу разобраться вообще без обращения к чему-либо». И он отвечает на основании своей базы, той модели, которая у него есть, не обращаясь ни к каким внешним источникам.

**Спикер.** А вот другой вопрос. Там я его попросил: прочитай мне документы и скажи, что в них написано, расскажи всё про всё. И у него сразу пошли вызовы.

**Спикер.** Точно так же мы видим это в конструкциях, когда работаем с какой-нибудь публичной моделью *[название системы распознано неразборчиво]* или с какой-то другой системой — иногда видно, каким образом осуществляется работа. То есть здесь явно говорится: «так, я решил, мне нужно вызвать вот это». Он вызывает, получает результат. Дальше пошла аналитика: этот результат отдаётся модели, и она выдаёт нам ответ не только на основании прямого запроса и тех знаний, которые у неё есть, но и на основании информации, которую она получила из внешнего источника и которой у неё до этого не было. Соответственно, количество этих вызовов может быть и больше. Вот здесь видно latency.

**Спикер.** Здесь прямо есть трассировка. О чём идёт речь? Вот этот процесс вызовов, вложенность, latency. Мы задаём агенту — а фактически через агента модели — запрос. Первый запрос идёт к агенту, дальше он формирует определённые сообщения, которые направляются в модель. Модель отвечает относительно того вопроса. Причём модель специфическая: она способна на основе того, что ей подали, не только что-то решать, но ещё и использовать средства, которые ей передали. И вот она говорит: мне нужен вызов инструмента, tool call.

**Спикер.** Следующее сообщение идёт непосредственно на вызов — оно направлено агенту. То есть модель сообщает агенту, что нужно вызвать определённые средства. Агент этот вызов делает, получает результат, отдаёт его опять в сторону модели. И по определённому алгоритму, который в него заложен, определяется, что необходимо остановиться. То есть на этом цикл ReAct закончен. Последнее сообщение — там написано что-то вроде response data *[значение распознано неразборчиво]*. Видно, что это тоже вызов. А вот тут написано middleware — это отдельный вызов.

**Спикер.** Здесь видно многие конструкции, которые связаны с middleware: они вызываются до вызова модели и после вызова модели. Точно такое же middleware есть и после каждого tool call. То есть можно таким образом обрабатывать вызовы, отдельно их фильтровать. Потому что в качестве средства, которое вызывается, может быть ещё один агент, может быть `MCP` *[аббревиатура распознана неуверенно]*, может быть какая-то система, которую мы построили: обратился туда — и там можно что-то отфильтровать, например, ограничить чувствительную информацию.

**Спикер.** На этом по агентам всё. Как я и говорил, минуты на три — получилось чуть больше. Следующая часть не связана с этой, она относится к вопросам таким… больным-небольным.

### 00:54:26–00:57:20 — Образовательные стандарты: ФГОС и раскладка «роль — задача — знания»

**Спикер.** Мы постоянно живём в переменах. У нас стандарт был третий, потом «три плюс», потом «три плюс плюс», а потом плюсы, мне кажется, закончились — и давайте четвёртый стандарт.

**Спикер.** Здесь хотелось бы проговорить следующее. Мы видим уход от прежней конструкции. Это прямо с государственного сайта. Понятно, что пока я говорю, всё может ещё двадцать пять раз поменяться. Это как раз группа специальностей по информационной безопасности — та, в которой приходилось работать. И вот перешли: компетенции раскладываются уже не на тройку, а фактически на знания, практику и теорию.

**Спикер.** Это, кстати, было давно — наверное, году в четырнадцатом, пятнадцатом, шестнадцатом, когда пошла эта песня со стандартами и прочим. Заходишь с нашими стандартами, как обычно, и думаешь: что вообще происходит? И оказывается, что есть 800-я серия публикаций, посвящённая информационной безопасности. И у них там есть публикация 800-181, и её редакция.

**Спикер.** Там примерно так же, в духе раскладывания на три компонента, разложены все фактические роли. Роли разложены на таски. И для выполнения набора тасок в определённой роли необходим набор знаний. Они все идентифицированы — прямо можно посмотреть.

**Спикер.** Понятно, что этот подход кому-то был абсолютно понятен, а кому-то — абсолютно непонятен. И у нас точно так же возникала какая-то путаница. И, возможно, именно поэтому в новом стандарте — если брать версию 181-ю, которая сейчас уже старая, — их немного сократили и тоже перешли к двойному разложению, примерно как у нас: оставили скиллы и знания.

**Спикер.** Редакция r1 полностью заменяет 181-й. И она уже не содержит вот таких офигительных таблиц. Фактически, если мы её посмотрим, увидим, что там констатируется: знания развиваются настолько быстро, что уложить их и сказать «вот, давайте учить по этому, и больше ничему не учить» не представляется возможным. И фактически представили фреймворк, который говорит: смотрите, вот так раскладывайте. У них есть несколько таких схем — от рабочих ролей, от компетенций.

### 00:57:21–01:00:02 — Отбор стажёров: почему не боремся с ИИ и в каких ограничениях работаем

**Спикер.** Но всё равно в конце у нас всё раскладывается на эти компоненты. Такой подход. Мы, в принципе, по такому подходу и идём, и он, наверное, близок к какой-то общей практике. Это был кусочек про обучение и про вопросы терминологии.

**Участник.** А что теперь — мы будем с этим бороться?

**Спикер.** Нет, бороться не будем — будем радоваться, что она есть. Особенно радоваться будут те, кто получает образование.

**Участник.** А те, кто преподаёт?

**Спикер.** Расстраивать это будет только тех, кто проверяет. И тех, кто преподаёт, наверное, тоже.

**Спикер.** У нас есть некоторые активности, связанные со студентами: мы берём студентов и нанимаем их стажёрами. Понятно, что стажировку разные люди понимают по-разному. Кто-то подходит, смотрит: «а ты что делаешь? а ты что делаешь?» — и всё, пошёл дальше. А у нас люди прямо в активную работу включаются. И поэтому на входе нам нужны люди, которые — несмотря на то что это студенты — реально знают и умеют.

**Спикер.** Соответственно, у нас есть некоторые методы отбора. Понятно, что если бы мы обладали, как обычно, бесконечными ресурсами времени, то можно было бы всё сделать идеально. Но на самом деле мы работаем в ограничениях. У нас есть схема, по которой мы отбираем специалистов.

**Спикер.** Есть часть, посвящённая тестам. Интересно даже не столько само задание, сколько ограничение: там нет возможности списать. Проходят только те, кто явно и активно подготовился. Про списывание я тоже немного скажу.

**Спикер.** Там есть запись, есть ограничение по времени. Дальше даётся задача — и вот про этот момент я расскажу подробнее. Тесты я подробно рассматривать не буду. А вот задачка, которая предполагает четырёхдневное самостоятельное решение…

**Спикер.** В первый момент это немного… не то чтобы расстроило. Мы же понимаем, что это не просто «мы сейчас придумаем задачку, они четыре дня решают, а потом нам пришлют». Если бы они нам ничего не присылали, можно было бы задробить любое задание и наслаждаться этим. А здесь нам приходится проверять.

### 01:00:03–01:02:57 — Экономика проверки и поток отчётов bug bounty

**Спикер.** Мало того, хотелось бы сделать так, чтобы время, потраченное на формирование задания, было кратно меньше, чем время на его решение. Иначе мы устанем сами: мы так и не узнаем, что люди умеют, — мы просто очень сильно устанем.

**Спикер.** Дальше. Мы не сможем сказать «не используйте модель» — её будут использовать. Это изначально был такой подход. Сначала было несколько обезличенных идей: давайте что-то заложим в задание, какие-то закладки, чтобы у нас потом в отчёте выдавались какие-то метки. Может, в следующий раз мы такую штуку и подготовим.

**Спикер.** Но в этот раз решили пойти по-простому — посмотреть, как сейчас обстоят дела. Такой первый заход с решением наших задач с помощью ИИ. Основное — это задача, на которую даётся четыре дня. Четыре дня, за которые нужно всё сделать, — это довольно много.

**Спикер.** Какие у нас направления были в подразделении по стажировке? Первое — аналитика: прямо сейчас это вообще больная боль, бесконечно можно про это рассказывать. Вторая боль, сравнимая с первой, — это бесконечный поток отчётов bug bounty. Просто бесконечный. Коллеги говорят, что отчётов сейчас за месяц столько же, сколько раньше за три года. Вот такое соотношение.

**Спикер.** Понятно, каким образом эти отчёты готовятся. Есть, конечно, и интересные плюсы. Хотя человек порой настолько не понимает, что именно ему выдала моделька. Наши друзья из страны, второй по численности населения, постоянно пишут так, что там то сто тысяч баксов, то ещё что угодно: «у вас опечатка на сто тысяч баксов». Ну просто народу много.

**Спикер.** Качественные отчёты, конечно, позволяют находить довольно серьёзные вещи — их нужно разбирать. Причём программа bug bounty устроена так, что платформа управляет процессом: ты просто не отвечаешь — и всё равно приходится реагировать. У платформы жёсткая модерация, и по времени они ждать долго не будут. Вот такой расклад. *[Часть реплик в этом фрагменте распознана неразборчиво.]*

**Спикер.** Поэтому решили: давайте посмотрим, как люди анализируют. И для этого сделаем им задачку на четыре дня.

### 01:02:58–01:05:53 — Что мы ждём от кандидата и как готовили задание

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

**Спикер.** И основная цель. Можно сказать, что задача звучит так: нам нужно найти одного человека. Если бы нам нужно было ранжировать людей, расставлять их по росту, наблюдать, как они стоят, — это была бы другая история. А у нас есть одна позиция, и нам нужно найти адекватного человека на эту позицию — такого, который, например, формирует отчёт и понимает, что в нём написано.

**Спикер.** Первые части фактически отсекали кандидатов сразу. Тесты и первые задания фактически отсекают людей. Поэтому на четырёхдневную задачу приходят уже не все, кто чувствует себя умелым пользователем веб-интерфейса, а немного более адекватные. Но оказалось, что и здесь тоже есть проблема.

**Спикер.** Какой контекст, что за люди? Старшие курсы: пятый курс, но обычно третий-четвёртый. Очень много пришло с третьего-четвёртого курса.

**Спикер.** Так вот, повторю: кроме того что нужно всех отобрать, нам нужно ещё и потратить не бесконечное время. Поэтому все остальные данные, которые у нас есть, — всё в эту модельку. Генерация — меньше секунды. Вот это мне понравилось.

**Спикер.** Потому что, как вы думаете, выделил ли мне кто-то на это дело секунду, минуту или день? Нет. Просто «вот это надо сделать». Причём задачи поступали так: «нужно сделать задание». — «Хорошо, сделал». — «Всё точно?» — «Всё точно». — «А тесты?» — «Тесты потом». И так до самого последнего момента.

**Спикер.** Но я прямо сразу в это включился: «подожди три секунды» — вот вопросы для теста, вот задание. Немного проверяли, потому что модель тоже бывает с чудинкой. Про настройки мы уже говорили — можно кое-что подкрутить, специально что-то подать. Была секунда, и ещё одна секунда. Ну, мы немного доработали, немного осталось. Если они потратят столько же, ну, нормально, будем считать.

### 01:05:54–01:07:54 — Что выдала модель, масштабируемость задания и объём выборки

**Спикер.** Но если я трачу неделю, а они берут секунду — это уже какой-то перекос.

**Спикер.** Что нам эта конструкция выдавала? Задача была посвящена аналитике безопасности. И она нам всё прямо описала, без каких-то дополнений и без всякой жести: что нужно сделать, какие цели, какие тесты, план работ; описала инструменты, которые нужно использовать в тот или иной момент; какие артефакты необходимо проверять, какие критерии, как нужно смотреть. Объём немного корректировали, но правки минимальные — сопоставимые с адекватным временем, которое на это выделяется.

**Спикер.** Опять же, если есть бесконечное время, можно позаботиться о матрице компетенций, посмотреть, какие предметы у третьего курса, и так далее. Но времени нет, поэтому вот так.

**Спикер.** Ещё одна особенность этой задачи в следующем: она хорошо масштабируется. В задании непосредственно указана определённая выдержка — конкретная технология. На следующий год можно дать следующую, более свежую. То есть можно подбирать эти выдержки по типу: например, если нам нужна какая-то конкретная технология — вставили её и смотрим. Фактически это позволяет грамотно работать примерно вот с этими активностями.

**Спикер.** Дальше было, конечно, интересно. Понятно, что тот метод, который я расскажу чуть позже и который мы использовали для проверки, пока очень сильно простой. Если бы у нас было не семнадцать человек, а сто семнадцать или тысяча сто семнадцать, мы бы, конечно, вручную не смотрели. Мы шли из объёма: оценили, сколько человек придёт, и выбрали метод под этот объём.

### 01:07:55–01:09:49 — Ошибочная методика отбора и метод «самой простой конструкции»

**Спикер.** Сначала мы делали не то чтобы неправильно — просто расскажу, как было. Сначала мы отбирали людей с самыми большими отчётами: у кого много всего написано и кто хотя бы выполнил те пункты плана, которые были заданы. Там написано: сделай отчёт, сделай видео, сделай презентацию, чтобы было понятно, что они делают. Вот так и отбирали.

**Спикер.** И с каждой секундой оказывалось, что объём отчёта, который человек предоставлял, обратно пропорционален его функциональным знаниям. Вот такая схема получилась.

**Спикер.** *[Фрагмент про скрипт, в котором что-то генерируется, распознан обрывочно.]* Но гуглить при этом нельзя. Как раз один человек у нас на этом и попался.

**Спикер.** Каким образом проверять? Я рассказывал, что есть технологии, которые отслеживают сгенерированный текст. Наверное, да, можно было бы сделать и так. Но почему-то мы взяли мой старый подход — тот, который применяется, когда нужно определить, списывал человек или нет.

**Спикер.** Наверное, можно сделать следующим образом: найти — не то чтобы в отчёте, а вообще в принципе — какая существует в языках программирования самая невероятная конструкция. Та, которую ты случайно когда-то прочитал и теперь всех про неё спрашиваешь и мучаешь. Сидишь и думаешь: я знаю одну эту конструкцию, которую нормальный адекватный человек никогда в жизни не будет использовать в коде. И спрашиваешь: а что она делает? а что она делает? И никто не знает про эту глупость. Наверное, так и должно быть.

**Спикер.** Поэтому мы брали прямо отчёт. Ты берёшь отчёт — просто отчёт, простой план — и находишь самую-самую простую конструкцию, которая там есть. Ну, присваивание значения переменной, самое обычное.

### 01:09:50–01:12:47 — Отчёты на смеси языков и чтение чужого текста с экрана

**Спикер.** Берёшь это присваивание и прямо спрашиваешь. Я это прямо со скриншотов разбирал: что значит вот это? а что значит вот это? а что значит вот это? И всё.

**Спикер.** Были прикольные отчёты — на смеси языков. Мы в какой-то момент подумали, что над нами просто издеваются. Просто издеваются. В отчёте написано на смеси: вот здесь десять минут смесь русского и английского языка. Мы такие: ладно, хорошо, открываем презентацию. То же самое. Ладно, там же есть видео. И человек так же и говорит.

**Спикер.** В какой-то момент уже просто стало интересно. Думаешь: ну где-то же есть грань, когда ты говоришь. Вот здесь я отношусь к большинству. А для кого-то грани нет — она размыта, и всё нормально.

**Спикер.** Решили узнать, что вообще происходит: у вас всё нормально? Это же текст, который написан, — они же его просто произносят. *[Часть реплики распознана неразборчиво.]* Когда текст написан не тобой, ты его так не произносишь. Понятно, что это кто-то написал.

**Спикер.** А в ответ: «понимаете, у нас преподают на английском языке, я русский плохо понимаю». Хорошо: плохо понимаешь русский — давай на английском. Бывает такое, может, тебе действительно так рассказывают. Ну окей. И там уже всё стало понятно. Мы такие: ладно, на английском не будем.

**Спикер.** И это образование. То есть людей так обучают. У меня в своё время был опыт, я видел таких людей — там, где я учился. У нас учились коллеги из дружественных стран. И вот идёт лекция на русском языке, человек её слушает, ошибку перевода замечает — то есть русский он понимает, он всё понимает. Такое обучение: тебе просто на русском объясняют, и у тебя всё укладывается. А теперь кто-то сделал так, что всё делается за него. И это, конечно, груз. Это серьёзно.

**Спикер.** Люди прошли тесты, записали своё видео, сделали этот отчёт. Кого-то мы там поймали.

### 01:12:48–01:16:14 — Что показали вопросы по отчёту, обратная корреляция и идея скринера

**Спикер.** Спрашиваешь: а как вы там делаете моделирование угроз? Что там вообще происходит? Там как раз был `STRIDE` *[название восстановлено по контексту]* и вопрос, как делать пентест. Короче, текст в отчёте был. А в ответ человек делает Ctrl+C прямо на преподавателя — а мы же преподаватели, мы это видим.

**Спикер.** Дальше: у вас написано команда — что она делает? Отвечает: «она запускает». То есть ты запускаешь программу, она разбирает аргументы — и это всё, что человек может про неё сказать. Мне понравилась работа, где был контейнер и аргументы контейнера *[термины распознаны неуверенно]*, — это вообще был просто отдельный вид.

**Спикер.** И это не один какой-то отдельный человек. Причём, как обычно: когда кажется, что хуже уже быть не может, тебе говорят «подожди». Примерно так у нас каким-то чудом и получилось.

**Спикер.** Возможно, мы вообще методически неправильно построили отбор. Мы брали самые хорошие отчёты — те, где больше всего умничают, — и по ним начали спрашивать. А надо было начинать с конца: у кого там вообще было написано меньше всего. И действительно оказалось, что там… Ну, не то чтобы прямо с конца — оттуда мы тоже брали. Но взять человека и действительно получить внятный ответ…

**Спикер.** Сейчас уже никто не любит вести подробные записи: «я там что-то написал» — вот в таком духе человек отвечает. Вот и результат. Здесь ты просто спрашиваешь — и человек не может объяснить.

**Спикер.** В принципе, поэтому мы и тратили минимальное время на одного кандидата. Ты берёшь самое простое — вот самое простое, что там есть, проще уже некуда, — прямо спрашиваешь: нет. Следующий: нет. Следующий: нет.

**Спикер.** У нас тут не было желания вытягивать. Хотя иногда как преподаватель ты думаешь: если человек не научился — ну, на лекции мы сейчас научим, мы это знаем, научим, давай-давай. И такой: о, есть знания, ура. Или уже сам за него пишешь. Мы старались так не жестить, иногда переключались. Но всё равно.

**Спикер.** Это к чему? Что контекст — объём людей и наши ресурсы — позволил использовать все те же старые исторические методы, которые были ещё тысячу лет назад. Если бы объём был другой, пришлось бы иначе.

**Спикер.** Кто-то — какая-то контора, *[название распознано неуверенно: возможно, Figma]* — сделал у себя вот такой подход: ты сначала убеди агента. Убеди агента, что твой отчёт адекватный, — а потом уже включится человек. Наверное, при большом объёме это правильнее. Но тут мы бы просто не уложились — ни в рамки, ни в ресурсы, ни во время, ни во что. Возможно, к этому придём, будем ещё смотреть. Потому что здесь мы в принципе оценили, что затраченные ресурсы позволили выполнить задачу довольно качественно. Ну и столкнулись с жестью и с тем, что надо думать.

### 01:16:15–01:19:26 — Интервью, ретроспектива про телефоны на экзаменах и выводы

**Спикер.** Надо подумать, что с этим делать. В следующий раз, возможно, будем менять методы. Метод, к сожалению, тут нам немного сверху пришёл: можно применять методы оценки к тем задачам, которые будут даваться.

**Спикер.** Слава богу, у нас в задании есть интервью. Интервью прямо всё показало. Самое расстройство — когда ты спрашиваешь, а в ответ ничего. Мы, конечно, будем разбирать всякие интересные моменты.

**Спикер.** А кто-то подготовился. Ты его спрашиваешь — а он смотрит куда-то в сторону; просишь камеру включить — сидит и говорит: «может, это очень интересный вопрос».

**Спикер.** Я опять же вспоминаю, как было тысячу лет назад, когда только начались вот эти люди, которые «теряют микрофон», лишь бы не отвечать. Мне кажется, у нас это уже тогда всех достало. Хотя, наверное, чуть-чуть иначе: когда я учился, эти телефоны… решение ещё нужно было заранее закачать на телефон. Не в конце обучения, а где-то в середине — решение нужно было на телефон.

**Спикер.** И тогда возник такой ход: «слушайте, я вам сейчас напишу вопрос — вы его не произносите вслух и напишите мне ответ». И пишешь вопрос. Вот такие методы.

**Спикер.** Пока это работает — на малом объёме. Когда завалят объёмом, будем расстраиваться. Возможно, придётся вводить какие-то системы. Не то чтобы «против» — не совсем прямо против, — а использовать те же самые технологии для проверки.

**Спикер.** Здесь мне сначала казалось, что мы будем искать в огромных отчётах какие-то слова, по которым должны догадаться, что человек его сгенерировал. Полностью сгенерировал, имеется в виду. Вот это не понадобилось. Просто выхватываешь конструкцию — и спрашиваешь.

**Спикер.** На этом всё. Можно было бы перейти к вопросам и ответам, но скажу одно: ждать нас можно бесконечно, и я могу говорить бесконечно, но то, что лежит и ждёт, становится всё менее свежим. У вас ещё активности, а эти вещи не ждут. Так что на этом всё, коллеги.

### 01:19:27–01:20:01 — Завершение: сертификаты и анкета обратной связи

**Ведущий.** Итак, коллеги, наша образовательная лаборатория подходит к концу, вас уже ждут угощения. Но перед этим нам нужно выполнить ещё две важные короткие активности. Первая — получение сертификата, что-то на память. И вторая — просим заполнить небольшую анкету обратной связи. С этого и начнём.

**Ведущий.** *[Завершающие организационные реплики распознаны неразборчиво.]*
