Бестиарий программирования – Telegram
Бестиарий программирования
903 subscribers
280 photos
4 videos
4 files
344 links
Наблюдения за жизнью ошибок в коде.
Андрей Карпов.

ГОСТ Р 71207-2024, ГОСТ Р 56939-2024, РБПО, Статический анализ кода
Download Telegram
Компетенция: теория разработки безопасного ПО (РБПО)

В нашей компании ООО "ПВС" существует матрица компетенций, на основании которой сотрудники проходят различные обучения, получают навыки и получают баллы для движения по сетке грейдов. Нам полезно развивать сотрудников, чтобы они лучше понимали суть РБПО, могли использовать некоторые подходы в работе, проводили доклады/вебинары на эту тему и т.д. Поэтому мы решили выделить и оформить сходную компетенцию, которую смогут получить заинтересованные сотрудники. Началом этого процесса стало составление списка полезных для нас материалов по теме РБПО. Всё это внутренняя кухня, однако сам список достаточно интересный и может быть полезен широкому кругу разработчиков и менеджеров. Поэтому мы решили опубликовать список ссылок на выбранные нами материалы в виде этой статьи.
👍3
Бестиарий программирования pinned «Компетенция: теория разработки безопасного ПО (РБПО) В нашей компании ООО "ПВС" существует матрица компетенций, на основании которой сотрудники проходят различные обучения, получают навыки и получают баллы для движения по сетке грейдов. Нам полезно развивать…»
РБПО-064. Процесс 19 — Нефункциональное тестирование

Цели 19-го процесса ГОСТ Р 56939-2024:
Подтверждение того, что поверхность атаки, модель угроз и архитектура ПО содержат необходимую информацию.

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

Можно сказать так: функциональное тестирование проверяет, что ПО делает то, что должно делать. А нефункциональное проверяет:

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

2) ПО не делает того, что не должно делать. Т.е. программа случайно или преднамеренно не содержит недекларированные возможности (НДВ).

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


Дополнительные ссылки:
1. QA_Bible. Нефункциональное тестирование (Non-Functional testing).
2. Ttestengineer ru. Нефункциональное тестирование — гайд.
3. Нефункциональные проверки при тестировании мобильных приложений.
4. Wikipedia. Non-functional testing.
5. Алексей Симкин. Гайд по тестированию локализации и интернационализации, а также большой и полезный checklist.
Запись вебинара "Оптимизация игр".
Вместе с экспертами из игровых студий — Forgotten Empires и Playrix — поговорили о тонкостях работы с памятью, кастомных аллокаторах, а также способах ускорить запуск мобильных игр.
🔥4
Подножка для AI в виде UTF-8. Часть 1 из 3: предисловие

Публикую своё наблюдение в преддверии подкаста Ever Secure на тему "Любимые грабли программистов, и станет ли вайб-кодинг спасением или новым проклятием". Решил разместить здесь пример, который я, скорее всего, упомяну в подкасте. На слух может быть сложно понять суть бага, поэтому код для наглядности не помешает.

Я немного экспериментировал с генерацией кода с помощью GigaChat и DeepSeek. Это не рабочие задачи и не полноценное исследование. Мне просто было интересно найти примеры пересечения некой грани сложности при решении задачи, после которой начинаются проблемы с генерацией C++ кода.

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

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

Для одного из экспериментов я выбрал создание программы, которая будет читать файлы с исходным кодом и выполнять ряд операций над названиями переменных или их составными частями. Одна из задач — это получить из имени переменной RedColor три токена: RedColor, Red и Color.

Думаю, задача разбития на токены часто встречается в программировании, и существует много открытого кода на эту тему. Поэтому в такой постановке GigaChat и DeepSeek с этой задачей справляются хорошо.

Однако мир сложнее, и нужно работать не просто со стандартной ANSI кодировкой, но и, например, с UTF-8. Поэтому я начал просить писать код, обрабатывающий файлы в том числе в формате UTF-8. И в этот момент генераторы кода поплыли.

Полагаю, количество открытого кода, учитывающего кодировки, в том числе и UTF-8, в несколько раз меньше. Дополнительно мои формулировки задания стали сложнее и от этого расплывчатее. Кстати, за пару подходов у меня не получилось добиться работающего кода. Думаю, это можно сделать, проведя ещё несколько генераций с уточнениями задания. Но у меня нет цели написать конечную программу и мне интересно экспериментировать именно со сбоями :)
🔥4
Подножка для AI в виде UTF-8. Часть 2 из 3: баги

Итак, приведённый ниже код сделал для меня GigaChat. Интересно, кстати, что пока он схалтурил: решил не делать настоящую конвертацию кода. Но при этом сам момент, что надо обрабатывать UTF-8, уже приводит к возникновению некорректного C++ кода.
....
// Вспомогательная функция для преобразования
// char-вектора в utf-8 строку
std::string to_utf8(const std::vector<char>& data)
{
// Для простоты считаем, что вектор представлен в UTF-8 изначально
return { data.begin(), data.end() };
}
....
// Главная функция для разделения строки на токены
std::vector<std::string_view>
tokenize_string_giga(const std::vector<char>& input_data)
{
std::string text = to_utf8(input_data);

std::vector<std::string_view> result;

size_t pos = 0;
while (pos < text.size())
{
if (is_letter(text[pos]) || is_digit(text[pos]))
{
size_t begin_pos = pos++;

// ищем конец текущего набора алфавитно-цифровых символов
while (pos < text.size() &&
(is_letter(text[pos]) || is_digit(text[pos])))
++pos;

// Извлекаем полное слово
std::string_view current_word =
text.substr(begin_pos, pos - begin_pos);

// Дробим слово на отдельные токены
split_word_into_tokens(current_word, result);
}
else
{
++pos; // пропускаем неалфавитно-цифровые символы
}
}

return result;
}

Ошибка связана со временем жизни объекта. Обратите внимание на фрагмент, где извлекаются слова:
std::string_view current_word = text.substr(begin_pos, pos - begin_pos);


Функция substr создаёт временный объект типа std::string, который затем разрушается. В результате в current_word сохраняются указатели на уже разрушенный объект.

Естественно, я попробовал запустить PVS-Studio. Он выявляет эту ошибку следующим предупреждением: V1017 [CWE-416] Variable of the 'string_view' type references a temporary object which will be removed after evaluation of an expression. Tokenizer_giga.cpp 79

Что интересно, приблизительно на том же споткнулся и DeepSeek. Он сгенерировал больше кода, так как не поленился повозиться с UTF-8, поэтому приведу здесь сразу выжимку:
std::vector<std::string_view>
tokenize_string(const std::vector<char>& buffer)
{
std::vector<std::string_view> tokens;
....
std::string utf8_text = detect_and_convert_to_utf8(buffer);
....
std::string_view token(utf8_text.data() + token_start, pos - token_start);
....
tokens.push_back(token);
....
return tokens;
}


В функции создаётся локальная переменная utf8_text типа std::string. Её разбивают на токены и записывают указатели на них в выходной массив tokens. Естественно, после выхода из функции переменная utf8_text уничтожается и ссылки становятся невалидными. К сожалению, здесь PVS-Studio пока помочь не смог: у него не получилось сопоставить время жизни utf8_text и tokens.
Подножка для AI в виде UTF-8. Часть 3 из 3: осмысление

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

Наверное, нет одной причины, почему так получается, и влияние следующих моментов суммируется:

1. Более обобщённая, и, следовательно, менее чёткая постановка задачи.

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

3. Класс std::string_view относительно молодой (C++17), и ещё создан не такой огромный объём кода с его участием, как, например, с std::string.

4. Возможно, концепция времени жизни объектов сложна для обучения.

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

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

P.S. Приглашаю в комментариях делится своими подобными случаями.
1
РБПО-065. Процесс 20 — Обеспечение безопасности при выпуске готовой к эксплуатации версии программного обеспечения

Цели 20-го процесса ГОСТ Р 56939-2024:
Организация приемки ПО с целью недопущения недостатков кода ПО перед его предоставлением пользователям.

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

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

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

Также процесс предписывает обеспечить возможность проверки целостности ПО (5.20.2.3-5.20.2.4):
5.20.2.3 Разработать регламент обеспечения целостности ПО, передаваемого пользователям.
5.20.2.4 Обеспечивать возможность проверки пользователями целостности ПО.

Речь идёт о подписи в исполняемых файлах и/или контрольных суммах, которые можно проверить.

Дополнительные ссылки:

1. Мазеин Михаил. Задача готова! Или нет? Definition of Done и зачем он нужен.
2. Что такое приёмочное тестирование?
3. Wikipedia. Подпись исполняемого кода.
4. Автоматизация подписи кода в современных условиях.
5. УБИ.145: Угроза пропуска проверки целостности программного обеспечения.
3
РБПО-066. Процесс 21 — Безопасная поставка программного обеспечения пользователям

Цели 21-го процесса ГОСТ Р 56939-2024:
Обеспечение защиты ПО, в том числе документации ПО, от угроз, возникающих в процессе передачи ПО пользователю.

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

Например, меры защитят от того, чтобы кто-то в компании подменил дистрибутив. Это реализуется за счёт того, что:

• в регламенте прописаны обязанности и роли сотрудников. На основе этого будет построена политика прав доступа к хранилищам дистрибутивов;
• пользователям должна быть предоставлена процедура проверки подлинности ПО (обновлений ПО).

Описание 21-го процесса, пожалуй, получится самым коротким. Не знаю, что интересного про него написать, а просто пересказывать требования и артефакты не вижу смысла. Тогда уж лучше сразу ГОСТ смотреть. В Интернете по этой теме тоже ничего не находится. Странно даже. Попадаются статьи про "безопасные цепочки поставок", но это относится к 16 и 17 процессу.

Постараемся найти кого-то для цикла "РБПО за 25 вебинаров", кто раскроет эту тему. Иначе придётся импровизировать :)

P.S. Кстати, сегодня будет "Процесс 13. Обеспечение безопасности сборочной среды программного обеспечения". 16:00 по МСК.
Дочитал книгу "Безопасный C++"

Приведён хороший и достаточно редкий материал. Признаюсь – некоторые темы прошли мимо осознания :) Например, раздел про криптографию не очень мне понятен и интересен/полезен. Зато очень зашла тема про выполнение произвольного кода и как от этого защищаться. Раздел 4.3 – сборка и укрепление, тоже прям хорош.

Как видите, книга с подписью для моего коллеги Михаила Гельвиха. Приятно знать, что Сергеем оценён его вклад в рецензирование книги.

В общем книга достойна внимания и знакомства с ней.
👍13🔥3🙏1
Интеграция результатов анализа PVS-Studio в CyberCodeReview
CyberCodeReview — это ASOC-платформа для анализа защищённости кода и приложений.
РБПО-067. Процесс 22 — Обеспечение поддержки программного обеспечения при эксплуатации пользователями

Цели 22-го процесса ГОСТ Р 56939-2024:
Обеспечение технической поддержки ПО при его эксплуатации с целью устранения вы являемых в ходе использования и обновления ПО недостатков.

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

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

Также требуется проработать процедуру оповещения пользователей о выпуске обновлений (включая обновления безопасности) и необходимости их установки. Эта процедура нужна и важна для любого приложения, но, когда мы говорим о РБПО, критичность этого действия возрастает. Мало исправить уязвимость в коде и выложить исправленный дистрибутив, необходимо ещё, чтобы пользователи как можно быстрее его установили.

Подробнее, что именно следует подготовить, смотри в п.5.22.3 - Артефакты реализации требований. Это один из самым больших разделов про артефакты среди других процессов.

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

Кое-что про нашу поддержку:
1. Пример, когда исследование проблемы, описанной пользователем, сложнее, чем кажется в начале. Ложные срабатывания в PVS-Studio: как глубока кроличья нора.
2. Шуточный доклад Юрия Минаева "Не связывайтесь с поддержкой C++ программистов".
3. Когда баг не там, где кажется. Один день из поддержки пользователей PVS-Studio.
4. Работа нашей поддержки.

Теперь вернёмся обратно к теме построения процесса поддержки. На эту тему есть следующие хорошие материалы:
1. ГОСТ Р ИСО/МЭК 14764-2002. Информационная технология. Сопровождение программных средств.
2. Wikipedia. Сопровождение программного обеспечения.
3. Роль технической поддержки программного продукта в SDLC.

Примеры разделов на сайте компаний про сопровождение ПО:
1. Лаборатории Касперского. Правила поддержки Программного Обеспечения Лаборатории Касперского.
2. Открытая мобильная платформа. Техническая поддержка программных продуктов.
3. РЕД СОФТ. Положение о технической поддержке операционной системы "РЕД ОС".
4. Киберпротект. Положение о сопровождении ПО.
5. Securitm. Правила технической поддержки.
А теперь время хорошей новости! 🔥

Друзья, коллеги, Java-разработчики, приглашаем вас на наш митап — Карты, деньги, JVM!

На митапе обсудим внутренности JVM и компилятора: разберём, как JVM оптимизирует динамические вызовы, чем MethodHandle лучше рефлексии, и как компилятор обрабатывает код — от фронтенда до практического применения.

Вас ждут два интересных доклада от разработчиков PVS-Studio, нетворкинг и вкусная пицца ❤️

🗓 30 октября
📍Санкт-Петербург + онлайн

Подробное расписание и регистрация по ссылке 🔗

#мероприятия #митап #java
Please open Telegram to view this post
VIEW IN TELEGRAM
10
РБПО-068. Процесс 23 — Реагирование на информацию об уязвимостях

Цели 23-го процесса ГОСТ Р 56939-2024:
Обеспечение выявления и устранения уязвимостей при эксплуатации ПО.

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

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

Часто этот процесс отсутствует. Вернее, к полученной информации о угрозах относятся точно так же, как и к сообщениям об ошибках. Дефекты безопасности попадают в багтрекеры наравне с другими багами и ждут своей очереди… и иногда очень долго. Другими словами, часто в компаниях выстроен 22-й процесс "Обеспечение поддержки программного обеспечения при эксплуатации пользователями", но не выстроен 23-й.

На практике это может выглядеть следующим образом. Я открываю задачу в багтрекере проекта о том, что в некоторых функциях не происходит очистка приватных данных. Компилятор в процессе оптимизации удалит вызов функции memset для зануления буфера, т.к. затем этот буфер более не используется. В общем, речь про CWE-14: Compiler Removal of Code to Clear Buffers.

Я не утверждаю, что это прям ужас-ужас какая ошибка. Она может ни на что не влиять и, скорее всего, эти незатёртые данные невозможно как-то заполучить и использовать. И тем не менее это вполне себе дефект безопасности, который, согласно ГОСТ Р 71207-2024, можно классифицировать как критическую ошибку (6.3.г — Ошибки некорректного использования системных процедур и интерфейсов, связанных с обеспечением информационной безопасности (шифрования, разграничения доступа и пр.)). Если речь идёт о РБПО, то такую ошибку следует просто на всякий случай сразу исправить и жить дальше спокойно. Тем более, что правка несложная.

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

Или, например, я месяц ждал реакции от разработчиков на информацию о дефектах, которые я затем описал в статье "Релиз PVS-Studio для macOS: 64 weaknesses в Apple XNU Kernel". Так ничего не дождался и опубликовал статью. Моё письмо или потеряли, или оно в спам попало, или пылится среди других. И подобных случаев на нашей практике много.

Чтобы такого не происходило, согласно ГОСТ Р 56939-2024, следует разработать и внедрить регламент (п.5.23.3.1):
- обязанности сотрудников и их роли при реагировании на информацию об уязвимостях ПО;
- правила реагирования на информацию об уязвимостях;
- правила оценки актуальности и критичности уязвимости с точки зрения безопасности ПО;
- периодичность проведения поиска известных (подтвержденных) уязвимостей в общедоступных источниках информации об уязвимостях ПО.

Рассматриваемый процесс также пересекается c композиционным анализом (см. РБПО-061), если речь идёт о нахождении уязвимостей в сторонних используемых компонентах.

По каждому случаю должна быть проведена работа по оценке актуальности и критичности. Т.е. должен появится артефакт, подтверждающий выполнение оценки актуальности и критичности уязвимости с точки зрения безопасности. Он должен содержать (п.5.23.3.4):
- информацию об оценке актуальности уязвимости;
- информацию об оценке уровня критичности уязвимости ПО;
- решение по результатам анализа актуальности и критичности уязвимости.

Дополнительные ссылки:
1. Терминология. Уязвимость нулевого дня.
2. Станислав Мриль. Всё об управлении уязвимостями в 2025: Vulnerability Management.
3. Positive Technologies: раскрытие уязвимостей и опыт взаимодействия исследователей и вендоров в 2022–2023 годах.
4. Руслан Рахметов. Поиск и предотвращение уязвимостей в ПО: эффективные методики.
5. Порядок подачи уязвимости в базу ФСТЭК России: пошаговая инструкция.