А не так уж и страшно, на самом-то деле

7 август, 2007 - 00:17Андрей Зубинский
Книга «19 смертных грехов программной безопасности» построена, по сути, на фразе Амита Йорана, выпускника военной академии Вест-Пойнт, на гражданке получившего степень магистра computer science в Университете Джорджа Вашингтона:
«95% ошибок программного обеспечения вызвано одними и теми же 19 недостатками».

Перечень этих недостатков весьма забавно сначала отсортировать по «популярности» их проявлений ( данные с сайта CVE, Common Vulnerabilities and Exposures), а, затем, - по условной, но вполне очевидной классификации «недостатки используемого языка программирования – недостатки конструкции (архитектуры) реализуемой программы – недостатки рода  человеческого». Немного «поковырявшись» в электронной таблице с пересчётами частоты упоминаний «болячек» на CVE в процентные вклады, получил следующую картину:

87% всех программных проблем порождаются всего четырьмя «болячками», только одна из которых относится к недостаткам языков программирования (и, что характерно, избавиться от неё элементарно – есть множество отработанных приёмов и готовых библиотек), две – к недостаткам архитектуры и ещё одна – к недостаткам человечества вообще. Пресловутое переполнение буфера, являющееся причиной 29,6% программных аварий – «болячка», по большому счёту, свойственная не столько С и C++, сколько «болячка» в каком-то смысле социальная, разве что подвержены ей представители определённого социума – программисты: как только они начинают мнить себя Творцами Своих Миров, так сразу и появляется латентное допущение «в моём Мире никогда и никто не введёт здесь строку больше чем из 128 символов». А в реальном мире – вводят.
На втором и третьем месте первой четвёрки – архитектурные хвори: XSS, cross-site scripting, подагра web-приложений, и впрыскивание SQL-кода (SQL Injection), врождённый дефект многих систем, основанных на трансляции SQL-запросов.
Четвёртое место – общечеловеческий недостаток: где от человека требуют запоминания пароля, там он хорошо запоминает пароли «Бомба» и «12345», остальное же запоминает или плохо, или вообще не запоминает. Плюс, - люди разговорчивы и доверчивы. В общем, - брешь всегда там, где вводится пароль.
В перечне оставшихся 15 «болячек» (их суммарный вклад в дело ненадёжности ПО около 13%) на первом месте опять идёт родовая травма С/C++, на самом деле также зависящая всё-таки больше от культуры работы программиста – строковые шаблоны форматирования ввода-вывода, так что правило опять же простое: реальный мир отличается от мира Творца, и где есть возможность вводить не то, что должно вводить в идеальном мире, там и будет введено не то. Причём, - самое не то из всего возможного не того.
Второе место – переполнения при целочисленных вычислениях. Это от языка не зависит, это – болячка фундаментальная, потому и исключительно интересная (рекомендую почитать вот это).
С третьего места во втором эшелоне начинается «архитектурщина». Впрыскивание команд – если контроль доступа к механизму исполнения команд несовершенен, можно найти способ заставить его исполнять всякие нехорошие команды.  Затем, – гонки. Естественно, - гонки за общий ресурс. И стоит его «пощекотать» со стороны, как начинается… да что угодно начинается. Это хворь тяжёлая, хроническая, поражающая многопоточные и «параллельные» архитектуры.
Дальше же – всякая мелочевка, от общеархитектурных расстройств (кривые обработчики ошибочных ситуаций, беспечный подход к «несущественному» времени модификации файла, дающий возможность атакующему «подсунуть» вместо реального файла какую-нибудь гадость) до ужасов конкретных API (SSL и TSL, например).

Главная же, «19-я болезнь», действительно страшная, потому что собирательная и в симптомах, и в латентных факторах: безопасность всегда усложняет жизнь не только разработчикам, но и пользователю. Это означает, что даже огромные затраты на разработку подсистемы безопасности будут сведены на нет её сложностью для пользователя.

А 20-я скрытая болезнь, поражающая программистов в самый их главный нервный узел, уже дважды "вылезла" в этой записи. Да, - мощный и одновременно гибкий инструмент очень трудно сделать одновременно совершенно безопасным, потому что мощность+гибкость и безопасность - взаимоисключающие критерии. Но ведь есть же методы, есть - достаточно посмотреть на код gpsd, чтобы понять, что такое ведь доступно всем желающим:

"gpsd is high-quality, carefully-audited code. It is regularly checked with the standard mode of splint, audited with Valgrind, and an extensive regression-test suite is used to check correct behavior before each release. This care has paid off in an exceptionally low defect rate; our first Coverity scan, in March 2007, turned up only two errors in over 22,000 LLOC."