Топ-10 багов в истории IT: от 10-го места к 1-му
От goto fail до Therac-25: что сломалось, к чему привело и какие выводы стоит взять в QA. Причины и последствия — по первоисточникам.

Почему эти десять
Это учебная подборка известных багов и инцидентов — от 10-го места к 1-му. Порядок учитывает известность, последствия и разнообразие уроков для QA; это не строгий рейтинг денежного ущерба или человеческих потерь. В сложных авариях программный дефект сочетался с проблемами требований, процессов и защитных барьеров. Pentium FDIV отдельно включён как аппаратный дефект, влияющий на результат программ.
10. Apple goto fail: пропущенная проверка подписи
Дата: 21 февраля 2014 — исправление iOS 7.0.6.
Что сломалось. В SSLVerifySignedServerKeyExchange повторный безусловный goto fail перескакивал через завершение хеширования и проверку подписи. Функция могла вернуть успешный результат без выполнения этих проверок.
Последствия. Apple подтвердила возможность перехвата или изменения данных SSL/TLS атакующим с привилегированным положением в сети. Исправление восстановило пропущенные проверки.
Урок для QA — наш вывод. Одного успешного HTTPS-соединения мало: добавляйте отрицательные тесты с неверной подписью и проверяйте, что проверка действительно выполняется. Статический анализ недостижимого кода и ревью изменений управляющего потока дополняют такие тесты.
Источники: Первоисточник · Технические подробности.
9. Pentium FDIV: неверное деление на редких данных
Дата: 1994; 20 декабря — объявление программы замены.
Что сломалось. В таблице, используемой аппаратной реализацией деления ранних Pentium, отсутствовали некоторые записи. На определённых операндах это снижало точность результата.
Последствия. Intel организовала замену процессоров по запросу владельцев. В годовом отчёте за 1994 год компания отразила 475 млн долларов расходов до налогообложения, связанных с заменой и другими затратами по этому дефекту.
Урок для QA — наш вывод. Проверяйте численные алгоритмы против независимого эталона, включайте специально подобранные операнды и свойства результата. Низкая частота на случайных данных не заменяет анализа риска для научных и финансовых вычислений.
Особенность: это аппаратный дефект процессора. Дата объявления замены отличается от даты обнаружения ошибки.
Источники: Первоисточник · Технические подробности · Годовой отчёт Intel: расходы на замену.
8. Cloudbleed: чужая память в HTTP-ответе
Дата: 23 февраля 2017 — публикация отчёта.
Что сломалось. HTML-парсер при обработке определённых некорректных входных данных проходил за конец буфера. Сочетание старого и нового парсеров сделало достижимым ранее скрытый дефект.
Последствия. Cloudflare подтвердила попадание фрагментов памяти с cookies, токенами и данными HTTP-запросов в ответы; часть ответов попала в кеши поисковиков. Затронутые функции отключили, затем исправили проверку границ.
Урок для QA — наш вывод. Проверяйте обрезанные и некорректные документы, EOF на каждом участке буфера и взаимодействие компонентов после изменения конвейера. Fuzzing и проверка границ памяти особенно важны для парсеров.
Источники: Первоисточник.
7. Mars Climate Orbiter: несовместимые единицы измерения
Дата: 23 сентября 1999 — потеря аппарата.
Что сломалось. Наземная программа SM_FORCES записывала импульсы двигателей в фунт-сила-секундах, хотя интерфейсная спецификация требовала ньютон-секунды. Навигационная обработка считала единицы корректными и недооценивала влияние манёвров. Ошибку не выявили проверки, взаимодействие команд и эксплуатационные процессы; комиссия также установила сопутствующие организационные причины.
Последствия. 23 сентября 1999 года сигнал аппарата исчез во время захода за Марс и не был восстановлен. Миссия потеряна. Реконструкция траектории после события дала высоту около 57 км в ближайшей точке, которую комиссия сочла недостаточной для выживания.
Урок для QA — наш вывод. Единицы измерения должны быть частью проверяемого контракта данных. Помимо проверки формата файла нужны интеграционные примеры с физически осмысленными контрольными значениями и независимым пересчётом. Аномалии навигационных расчётов требуют владельца и формального решения, даже если схема данных валидна.
Потеря миссии подтверждена. Точная дальнейшая судьба аппарата не наблюдалась; вывод о его сгорании нельзя выдавать за установленный факт.
Источники: Первоисточник.
6. Ariane 5: одинаковый сбой основной и резервной системы
Дата: 4 июня 1996 — полёт 501.
Что сломалось. В ненужной после старта функции юстировки значение BH, связанное с горизонтальным движением, превысило диапазон при преобразовании 64-битного floating-point в 16-битное знаковое целое. Необработанная ситуация остановила обе одинаковые инерциальные системы. Программные предположения от Ariane 4 не соответствовали траектории Ariane 5; испытания не воспроизвели эту комбинацию.
Последствия. Примерно через 37 секунд после начала последовательности зажигания главного двигателя система потеряла корректные данные наведения. Затем ошибочные команды вызвали резкое отклонение и разрушение ракеты; сработала штатная система самоуничтожения. Первый полёт Ariane 5 завершился неудачей.
Урок для QA — наш вывод. При повторном использовании кода заново проверять ограничения входных значений в новой среде. Дублирование одинакового ПО не защищает от общей ошибки. Интеграционный стенд должен воспроизводить реалистичные входные данные и поведение ошибок, включая резервирование.
Источники: Первоисточник.
5. Patriot: потеря точности после долгой работы

Дата: 25 февраля 1991 — инцидент в Дахране.
Что сломалось. При переводе внутреннего времени из целого числа десятых долей секунды в вещественное значение терялась точность. С ростом времени непрерывной работы ошибка расчёта позиции цели увеличивалась. Батарея проработала более 100 часов, и расчётное окно сопровождения сместилось настолько, что система не смогла сопровождать входящую ракету.
Последствия. 25 февраля 1991 года Patriot не перехватил Scud в Дахране. Снаряд попал в армейскую казарму; по GAO погибли 28 американских военнослужащих. Исправленная версия ПО прибыла в Дахран 26 февраля, на день позже.
Урок для QA — наш вывод. Нужны длительные прогоны и проверки времени далеко от момента запуска. Численные погрешности стоит оценивать по итоговому воздействию на систему, а не только по размеру ошибки одного вычисления. Для критических исправлений проверять доставку и установку на каждом экземпляре, а эксплуатационные ограничения задавать конкретно.
Источники: Первоисточник.
4. Knight Capital: релиз дошёл не до всех серверов
Дата: 1 августа 2012 — торговый инцидент.
Что сломалось. Новый код RLP не попал на один из восьми серверов SMARS. Переиспользованный флаг активировал оставшийся на том сервере старый Power Peg, в котором раньше перенесли счётчик исполненного объёма. Программа продолжала отправлять дочерние поручения после исполнения родительского. Контроли развёртывания, лимиты и останавливающие процедуры не предотвратили развитие инцидента.
Последствия. Примерно за 45 минут система получила более 4 млн исполнений в 154 бумагах, обработав 212 клиентских поручений, и создала незапланированные позиции. В итоге компания потеряла более 460 млн долларов. Эти факты зафиксированы SEC в постановлении 2013 года.
Урок для QA — наш вывод. Проверять одинаковые версии всех узлов после релиза, тестировать переиспользованные флаги и убирать недостижимый старый код. Перед включением потока проверять лимиты, аварийную остановку и сценарий отката. Уведомления о нештатном состоянии должны приводить к действию до открытия основной нагрузки.
Источники: Первоисточник.
3. CrowdStrike: схема ожидала 21 поле, код передавал 20
Дата: 19 июля 2024 — распространение Channel File 291.
Что сломалось. Определение шаблона ожидало 21 вход, но интеграционный код передавал 20. Новая конфигурация потребовала сравнить 21-е поле; отсутствие проверки границ привело к чтению за пределами массива. Ранее тестовые wildcard-условия не раскрывали дефект.
Последствия. Windows-системы с получившими эту конфигурацию сенсорами завершались аварийно. CrowdStrike опубликовала технический RCA 6 августа 2024 года и описала исправления валидации, проверки границ, расширение тестов и поэтапное развёртывание.
Урок для QA — наш вывод. Контракт между схемой и потребителем нужно проверять автоматически и в runtime. Тестируйте каждое поле с конкретными значениями, каждую конфигурацию — в реальном интерпретаторе; выпускайте изменения через canary и последовательные группы.
Источники: Первоисточник.
2. Heartbleed: длина пакета открывала доступ к памяти
Дата: 7 апреля 2014 — security advisory.
Что сломалось. В обработке расширения TLSHeartbeat отсутствовала проверка границ. Это позволяло прочитать до 64 КБ памяти на запрос к уязвимой стороне соединения.
Последствия. OpenSSL подтвердила возможность раскрытия памяти подключённому клиенту или серверу. Уязвимыми были ветки 1.0.1 и 1.0.2-beta, включая 1.0.1f и 1.0.2-beta1; исправление выпущено в 1.0.1g.
Урок для QA — наш вывод. Сопоставляйте заявленную длину с реальным размером каждого сообщения. Проверяйте 0, границу, границу + 1, обрезанные пакеты и повторные запросы; используйте fuzzing и средства обнаружения ошибок памяти.
Источники: Первоисточник.
1. Therac-25: гонки состояний и недостаточная защита
Дата: 1985–1987 — серия аварий.
Что сломалось. В расследовании описаны несколько программных дефектов и системных проблем безопасности. Для аварий в Тайлере быстрый возврат к редактированию режима во время настройки магнитов создавал гонку состояний: интерфейс и управляющий код расходились в представлении о выбранном режиме. Защитные барьеры, сообщения оператору и расследование предыдущих инцидентов были недостаточны.
Последствия. Между июнем 1985 и январём 1987 исследователи документировали шесть известных аварий с массивными передозировками. Были смертельные исходы и тяжёлые травмы; точное единое число смертей в эту карточку не включаем.
Урок для QA — наш вывод. Тестировать быстрые последовательности действий, прерывание и повторное редактирование во время фоновых операций. Для опасного оборудования отдельно проверять независимые защитные блокировки и безопасный отказ. Сигнал об инциденте должен запускать расследование всей цепочки защиты, а не только локальную правку.
Шесть — число известных аварий с передозировками. Причины отдельных происшествий различались; все их нельзя свести к одной гонке состояний.
Источники: Первоисточник · Технические подробности.
Как использовать подборку
Возьмите один класс ошибки и найдите аналог в своём продукте: несовместимый контракт, неверные единицы, потеря точности, длинная сессия, гонка, неполный релиз или ошибочная длина входных данных. Добавьте конкретную проверку с наблюдаемым ожидаемым результатом. Одна проверка могла бы выявить часть условий, но не гарантирует предотвращение всей цепочки инцидента.

