Каждый день я вижу потенциально уязвимый код. Иногда код настолько уязвим, что любой школьник может поломать его. Я также много общался с программистами, которым стоило бы больше знать об уязвимостях. Это очень, как бы это сказать, удручающе. Это грустно, что средний девелопер знает так мало об обычных практиках безопасности. Так что я собрал здесь маленький манифест.
Я пишу защищенный код, если соблюдаю все эти пункты:
- Я не буду хранить чувствительные данные в plain text, я буду защищать их как следует.
- Я всегда буду защищать пользовательские данные, как защищал бы свои.
- Я всегда буду использовать проверенные и известные алгоритмы, не буду изобретать колесо.
- Я буду использовать существующие библиотеки, пока возможно, и буду писать свои только когда нет подходящих альтернатив.
- Я всегда буду использовать параметризованные запросы (читай бинды) SQL, я не буду доверять экранированию.
- Я буду воспринимать уязвимости серьезно, не буду игнорировать их.
- Я должен понимать OWASP топ 10 уязвимостей, и всегда буду защищать свои приложения от них.
- Я не буду всегда предполагать, что знаю лучше, но буду постоянно развиваться.
- Я не буду доверять безопасность системам, которые самостоятельно не исследовал.
- Я всегда буду стараться обучать других.
Разбор полетов
Я не буду хранить чувствительные данные в plain text, я буду защищать их как следует
Чувствительные данные, в этом случае, — это любые данные, утечка которых может вызвать негативные последствия. Это включает в себя данные пользователей, системные, или данные компании… Например пароли, номера соц. страхования (читай пасспорта), кредиток, адреса… Вместо этого, храните минимум данных в plain text. Вам лишь нужно убедиться, что информация корректна? Тогда можете захешировать необратимым алгоритмом. Вам позже понадобиться оригинал? Тогда зашифруйте с открытым ключом. Но не храните в исходном виде.
Я всегда буду защищать пользовательские данные, как защищал бы свои
Это довольно обширно. Это может значить защиту всего приложения от угроз безопасности, или добавление каких-то особых механизмов защиты для определенных данных. Но смысл в том, что все данные пользователей должны быть защищены, и только та информация, которая может быть публичной — может не подвергаться такой опеке. Это значит, что вы должны принять приватность данных серьезно, и не допускать утечки, как не захотели бы утечки своей личной информации.
Я всегда буду использовать проверенные и известные алгоритмы
Это гораздо серьезней, чем многие думают. Есть очень много примеров (некоторые из которых принадлежат известным open-source проектам) как люди «изобретают» собственные крипто-алгоритмы. Суть здесь в том, что криптография — это сложно. Эту задачу лучше оставить людям, которые хорошо знают что делают. Используйте только те алгоритмы, которые доступны всем и были хорошо проверены и опробованы. Еще лучше будет, если вы будете использовать алгоритмы, использованные в публичных (известных) стандартах.
Я буду использовать существующие библиотеки, если возможно
Написание кода, отвечающего за безопасность, — сложная задача. Написание реализаций алгоритмов защиты — еще сложнее. Это довольно сложно тестировать (под все возможные кейсы). Так что, лучше использовать готовые, проверенные (и open-source-ные) библиотеки, чем писать свою собственную версию стандартного алгоритма. Иногда, все же, вы не сможете найти библиотеку, которая реализует алгоритм, который вам нужен. В этом случае — это норма, писать свою собственную версию, но будьте осторожны и тестируйте сполна.
Я всегда буду использовать параметризованные запросы SQL
Это возможно — писать безопасные запросы, используя экранирование. Но это очень сложно. Есть очень много вещей, о которых вы должны знать (особенно при работе с MySQL). Экранирование безопасно только тогда, когда вы все делаете безупречно правильно, оно не прощает. Параметризованные запросы (prepared statements входят в эту категорию) лучший способ решения этой задачи (прим. пер. — лучший чем экранирование), т.к. вам не нужно беспокоится об экранировании, теперь это проблема БД (или драйвера).
Я буду воспринимать уязвимости серьезно
Очень уж часто я слышу что-то вроде «Но это внутреннее приложение, мне не нужно беспокоиться о...» Это не оправдание. Единственная причина игнорировать уязвимости — это их отсутствие. Всегда пишите защищенный код, и вы никогда не попадете в ситуацию, когда пустив все на ветер, узнаете, что система выходит в паблик.
Я должен понимать OWASP топ 10
OWASP top 10 — это каталог топ 10 уязвимостей и способов атак, используемых против веб-приложений. Понимая все эти пункты, вы будете лучше знать, как защищать свои веб-приложения.
Я не буду всегда предполагать, что знаю лучше
Безопасность — скользкая штука. Все постоянно изменяется и прогрессирует. Единственный способ оставаться в курсе — продолжать учиться и познавать изменяющиеся окружение. Самодовольство убивает, вы должны постоянно спрашивать себя, что вы вынесли из прочитанного, и постоянно улучшать свои знания.
Я не буду доверять безопасность системам, которые самостоятельно не исследовал
Только потому, что система — open-source, или разрабатывается профессионалами, не значит, что там используются лучшие практики защиты, или что она 100% безопасна. Только посмотрите на что-нибудь вроде WordPress-а, почти каждый релиз фиксит какую-нибудь уязвимость в безопасности. Не доверяйте системе только потому, что ее безопасность — это ответственность кого-то другого. Посмотрите на код, убедитесь что там все в порядке. И если нет, найдите причину почему. Не доверяйте слепо.
Я всегда буду стараться обучать других
Этот пункт так же распространяется не только на безопасность, но он так же стоит того, чтобы быть упомянутым. Мало того, что лучший способ учиться — это учить, но и благодаря обучению других, мы как коммьюнити вырастаем. Если вы видите, что что-то не так в чьем-то коде, расскажите ему, что он сделал не так, и как это исправить. Не игнорируйте просто потому, что «это его проблема». Безопасность — это задача всего коммьюнити. Вы либо часть решения, либо часть проблемы.
PS в комментариях, Andy Lester, дал ссылку на ресурс, на котором вы можете увидеть как использовать параметризованные запросы в разных языках
PPS По поводу готовых библиотек — для PHP рекомендую Security компонент из Symfony2. Он, естественно, может работать без симфони (но, скорее всего, ему нужен DBAL от Doctrine2, это довольно легкая абстракция над PDO, oci8 и т.п.)
Автор: nikita2206