habrahabr

Конспект по веб-безопасности

  • вторник, 6 мая 2014 г. в 03:10:32
http://habrahabr.ru/post/221503/

Простите, но накипело.
Много шишек уже набито на тему безопасности сайтов. Молодые специалисты, окончившие ВУЗы, хоть и умеют программировать, но в вопросе безопасности сайта наступают на одни и те же грабли.

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


Итак, каким должен быть безопасный сайт?


1. О сервере


  1. FTP – не безопасный протокол, передает информацию не в зашифрованном виде, поэтому стоит выбрать либо FTPS, либо SFTP. Теперь по SSH, авторизация по ключам, ─ используем denyhost или его аналог, можно сменить дефолтный порт.
    Все, что брутят, нужно закрывать. Если у вас есть свой сервер и вы хоть раз смотрели в логи, вы наверняка замечали многочисленные попытки авторизации по SSH и по FTP, идущие с китайских IP.
  2. Во вне должны смотреть только действительно нужные порты, остальное закрываем фаерволом.
  3. Используем всегда актуальные версии софта, вовремя обновляемся.
    Недавняя история с OpenSSL тому подтверждение

  4. Обязательно настроить логи и мониторить любую подозрительную активность.
  5. Никаких левых папок и файлов а-ля .svn, .git, .idea, dump.tar.gz в корне проекта не должно быть.
    Были случаи, когда на сайтах клиента оставлялись архивы с базой и файлом в открытом доступе. То же самое и с бекапами.
  6. Устанавливаем минимально допустимые права на файлы, никаких 777.
  7. Динамику, если возможно, лучше выносить за пределы корня.
  8. Статика (js, css, image) должна лежать отдельно, в идеале ─ на другом сервере.
  9. Если работаем с важными данными, используем https/ssl с коротким expiration.
  10. Сообщения об ошибках на экран не выводим ─ только подсказки пользователю.
  11. Бекапы нужно делать обязательно и сохранять на другом сервере.

2. О входных данных


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

  2. В модели:
    • Для SQL-запросов используем prepared statements.
    • Оптимизируем запросы к базе — никаких select в цикле.
    • Не забываем про индексы.
    • Сложный поиск? Используйте поисковые движки (ElasticSearch, Sphinx и т.д.).

  3. В представлении:
    • Приводим в нужные сущности данные. Проверяем на xss, никаких html тегов или js скриптов от клиента.
    • В отправке формы или изменений состояний используем уникальные для каждого пользователя токены (csrf). Не хотите токенов, тогда проверяйте HTTP_REFERER.
    • Если используете AJAX, не забывайте проверять данные и на входе, и на выходе. В 99% случаев eval в JS – зло.


3. О клиенте


Как говорил Доктор Хаус, пациент всегда врет.
Большинству клиентов наплевать на свою безопасность.
  1. Валидация на клиенте – только для его удобства, обязательно перепроверяем на сервере.
  2. POST так же легко подделывается, как и GET.
  3. Если есть форма в открытом доступе без капчи, в нее обязательно начнут писать спамеры.
  4. Усложните авторизацию, несколько неудачных попыток входа — пусть вводят капчу.
  5. Хотите еще усложнить? Прикручиваем двухфакторную аутентификацию.
  6. Для подтверждений используем одноразовый длинный токен, завязанный на конкретного пользователя.
  7. Заставляем клиента делать сложные пароли.

4. О шифровании


  1. Ничего не храним в открытом виде.
  2. Пароли — в виде хешей с солью, желательно проверять на криптостойкость и коллизии.
  3. от ValdikSS Не используйте ни MD5, ни SHA1. Лучше всего для паролей использовать специализированные хеш-функции, типа PBKDF2 или scrypt.
  4. Никаких данных на клиенте, даже в зашифрованном виде, только id-сессии в куках.


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