Безопасность кода

14 августа 2011

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

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

Пользовательские программы, которые работают локально, тоже должны быть надежны. Потребители не любят, когда софт падает и каждые пять минут сообщает об ошибке выполнения.

Планирование безопасности

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

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

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

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

Помимо этого необходимо определить все точки ввода информации пользователем или возможного поступления данных в программу. К таким точкам ввода относиться:

  • сетевые данные;
  • файлы, особенно с текстом, который должен идти на выполнение (скрипты);
  • данные, передаваемые пользователем через любые методы ввода информации (например, элементы управления).
    • Когда план готов, можно приступать к работе по реализации программы. Если проект большой, то каждые пару месяцев (можно и реже, это зависит от скорости разработки) лучше останавливаться и пересматривать/корректировать план. Все в нашей жизни меняется, и задание тоже может быть подвержено изменениям.

      Уровень защиты

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

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

      Самые страшные ошибки — ошибки алгоритмов или логики, когда разработчик ошибочно выбрал метод защиты или неправильно реализовал алгоритм. Эти ошибки сложнее всего найти и чаще всего очень сложно исправить. Например, во время планирования сетевого протокола вы решили, что шифровать данные не имеет смысла, и посчитали, что пользователь будет использовать программу для передачи через Интернет не критичных к безопасности данных. Если пользователь захочет передать более критичные данные, то он может использовать VPN или другие методы навесной защиты. Защита с помощью навесных методов хороша, но не всегда реализуема, поэтому у пользователя может возникнуть потребность в добавлении в программу возможности шифрования, хотя бы самого простого. Как это сделать? Это на словах все просто, но ведь на рынке уже существует множество копий вашей программы, которая не использует шифрования. Те пользователи, которые не обновятся до новой версии, не смогут работать с теми, у кого версия с шифрованием. Вы не можете заставить всех зайти на свой сайт и скачать обновление, поэтому придется реализовывать возможность работы в двух режимах, с шифрованием и без.

      Исправление ошибок

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

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

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

      Шифрование

      Алгоритмов шифрования существует большое количество, и каждый обладает своими характеристиками скорости/стойкости/потребности в ресурсах, но не существует одного, который подошел бы для всех случаев. Стоит обратить внимание на общепринятые стандарты RSA и DES.

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

      Алгоритм DES отличается в принципе, потому что он симметричен, т. е. используется только один ключ для шифрования и дешифрования. Он был разработан в недрах компании IBM и уже долгие годы является стандартом шифрования во многих странах, рождение этого алгоритма также датируется 1977г.

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

      Тестирование

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

      Возможности системы

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

      Помимо этого, не стоит разрабатывать собственную систему контроля доступа, когда есть ACL. Не стоит придумывать собственную систему аутентификации и авторизации, когда есть готовые решения.

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

      Установка программы

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

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

Рейтинг@Mail.ru