Двадцать предупреждений для ASP-разработчиков

Двадцать предупреждений для ASP-разработчиков

Файрволы защищают от прямого подсоединения хакеров к вашим сетевым ресурсам. Администраторы Windows поддерживают систему на современном уровне с помощью последних программных патчей, чтобы пресечь атаки червей типа Nimda и Code Red. И пароли пользователей надежнее, чем когда-либо. Достаточно ли мы защищены? Несмотря на то, что ситуация выглядит гораздо лучше, чем пару лет назад, многие компании по-прежнему часто подвержены атакам. Блокирование портов и установка патчей не остановили хакеров, а только вынудили их искать новые пути для взлома. И первое, что они попытаются использовать – ваши Web-приложения.

Михаил Разумов

Файрволы защищают от прямого подсоединения хакеров к вашим сетевым ресурсам. Администраторы Windows поддерживают систему на современном уровне с помощью последних программных патчей, чтобы пресечь атаки червей типа Nimda и Code Red. И пароли пользователей надежнее, чем когда-либо. Достаточно ли мы защищены? Несмотря на то, что ситуация выглядит гораздо лучше, чем пару лет назад, многие компании по-прежнему часто подвержены атакам. Блокирование портов и установка патчей не остановили хакеров, а только вынудили их искать новые пути для взлома. И первое, что они попытаются использовать – ваши Web-приложения.

Проблема в том, что даже если вы имеете команду экспертов, обеспечивающих безопасность вашей сети, вы по-прежнему зависите от ваших разработчиков Web-приложений. Достаточно ли они обучены, чтобы противостоять наиболее искушенным хакерам? Или, по крайней мере, достаточно ли они хороши, чтобы защититься от зеленого хакера, который прочитал только пособие по SQL injection? Многие компании не понимают, что их код недостаточно защищен.

Эта статья содержит двадцать советов для ASP-программистов. Это советы не о том, как защитить Web-приложение, а о том, чего следует избегать при их разработке. Эти двадцать ошибок повторяются в Web-приложениях вновь и вновь.

  1. Не передавайте нефильтрованный пользовательский ввод Web-клиенту

    Одна из наиболее типичных ошибок программирования, передача нефильтрованного пользовательского ввода Web-клиенту, открывает Web-приложение для cross-site scripting атак. Cross-site scripting, часто называемый XSS, позволяет вводить в Web-приложение HTML, JavaScript, Java Applets, VBScript, и др.

    Никогда не следует использовать объект Request в выражении Response.Write:
    Response.Write "You have entered " & Request("UserInput")

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

  2. Не доверяйте клиентским или сессионным переменным

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

  3. Не забывайте специфицировать кодировку символов

    Простой методикой для уменьшения подверженности cross-site scripting атакам является явное определение кодировки символов, разрешенных к использованию на вашей HTML странице. Если кодировка не задана, тогда может использоваться любая, и становится сложнее отфильтровать запрещенные символы.

    Следующий HTML код явно задает кодировку символов в windows-1251:

    <META http-equiv="Content-Type" content="text/ HTML; charset=windows-1251">

  4. Не осуществляйте доступ к файлам, заданным в пользовательском вводе, без проверки пути

    Нет ничего необычного в URL типа:

    http://www.example.net/article.asp?file=new.htm

    Всякий раз, когда я вижу что-то в этом роде, я задумываюсь, что случится, если изменить этот URL как в одном из следующих примеров:

    http://www.example.net/article.asp?file=/global.asa

    http://www.example.net/article.asp?file=/../../../boot.ini

    http://www.example.net/article.asp?file=LPT1

    http://www.example.net/article.asp?file=\%2e%2e\global.asa

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

    Например, рассмотрим следующий код:

    <%
            Set fso = CreateObject("Scripting.FileSystemObject")
    On Error Resume Next
    Set f = fso.GetFile(request("file"))
    If err then
         Response.Write "Error"
    Else
        Response.Write f.Path
    End If
    %>
    

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

  5. Не посылайте SQL запросы без фильтрации пользовательского ввода

    SQL Injection – это процедура взлома Web-приложения, обычно через Web-форму, путем передачи злонамеренных SQL инструкций на сервер баз данных. У Microsoft's SQL Server это обычно делается путем ввода одинарной кавычки в Web-форме, после которой следует корректныйSQL запрос. Например, рассмотрим следующий код аутентификации пользователя с помощью Web-формы:

    strSQL="SELECT * FROM Customers WHERE Username = '" &Request("Username") & "' & Password = '" & strPassword & "'"

    Этот код довольно типичен для Web-приложений. Рассмотрим, однако, что произойдет, если пользователь введет следующее:

    Username: Test

    Password: ' or True

    Итоговая строка SQL запроса будет выглядеть:

    strSQL="SELECT * FROM Customers WHERE Username = 'ValidUser' & Password= '' or True --'"

    Это выражение по существу возвращает ValidUser customer, независимо от пароля; условие True заставляет всегда выполняться условие WHERE. Обратите внимание, что двойная черта ("--") в конце выражения действует как символ комментария, заставляя игнорировать все последующие символы.

    Чтобы исправить пользовательский ввод перед передачей его в базу данных, проверьте его на наличие одиночной кавычки и замените ее двумя одиночными кавычками. В этом случае база данных будет рассматривать ее как символ, а не закрытие строки. Учтите, однако, что в случае численного ввода кавычки не требуются; в этом случае просто проверьте, что ввод действительно цифровой.

  6. Не доверяйте содержимому базы данных

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

  7. Не храните пароли или другую чувствительную информацию в ASP страницах

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

    Как альтернатива, храните эту информацию в COM компонентах, ключах реестра, File DSNs, или других местах, отличных от корня Web.

  8. Не полагайтесь на слабые проверки защиты

    Легко попасть в ловушку слабых мер защиты, например, полагаясь на переменнуюHTTP referrer, обеспечивая безопасность с помощью скрипта на стороне клиента, или ограничивая ввод формы установкой свойства формы maxlength. Хотя эти меры безопасности могут казаться достаточными, они предохраняют как дешевый замок на двери: кто-то не сможет войти, но достаточно лома или кувалды – и посторонний уже внутри.

  9. Не оставляйте комментариев в клиентском HTML коде

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

  10. Не выдавайте излишней информации

    На Web-сайте одного банка существовала очень интересная защита эккаунтов клиентов. На первой странице запрашивался номер эккаунта и пароль. При этом номер эккаунта соответствовал номеру счета клиента, который, к примеру, распечатывается на чеках, а вот с паролем вышел такой курьез. При попытке ввести что-нибудь не то, например популярное “asdfg”, сервер выдавал сообщение, что пароль должен быть длиной в 4 символа и состоять только из цифр. Таким образом, число вариантов от триллионов комбинаций неожиданно сводится к десяти тысячам. Мораль здесь такова, что не нужно выдавать свойства пароля – человек либо знает его, либо нет. В противном случае любому желающему будет несложно его определить.

  11. Не пишите туда, откуда читаете

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

    Помните, что в Internet Services Manager, отмечая пункт Write, вы подтверждаете, что любой анонимный пользователь может писать файлы в эту директорию.

  12. Не помещайте чувствительную информацию в URL

    Будьте внимательны к пользователям вашего Web-приложения; не помещайте их чувствительную информацию в своих URL. URL передаются в текстовом виде, сохраняются в Web-кэше и авто-заполняются в адресном поле. Любую информацию, отображенную в URL, вы раскрываете для посторонних. Вместо помещения чувствительной информации вURL, используйте сессионные переменные, POST данных, и шифруйте все, что возможно.

  13. Не используйте .INC файлы

    Использование include файлов для централизации кода – хорошая программная практика, но обычная ее реализация не очень хороша для безопасности. В стандартной IIS установке файлы .INC не относятся ни к чему, и при запросе любого из них, добрый IIS вернет исходный код, как если бы это был текстовый файл.

    Централизуя свой код, дайте всем include файлам расширение .ASP и поместите их в ту же директорию. Какие разрешения IIS необходимо установить на include директории? Ответ – none. Запрет на чтение, запись и исполнение.

  14. Не отправляйте e-mail без проверки пользовательского ввода

    Как уже было сказано выше, пользовательскому вводу нельзя доверять. И это также относится к e-mail адресам. Проанализируйте, как ваша форма регистрации пользователей будет обрабатывать множественныеe-mail адреса, вставку SMTP команд, аргументы командной строки и др.

  15. Не помещайте чувствительные данные в скрытые поля форм

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

  16. Не позволяйте IIS обрабатывать ошибки

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

  17. Не теряйте контроль над вашим кодом

    Лучший способ защититься от хакеров – поддержка контроля над своим кодом. Это означает жесткий контроль за изменениями и знание того, какой код там должен быть, а какой нет. Вам следует удалять остатки программного процесса, такие какdebug-код, временные файлы,backup-файлы, а также обычный test.asp.

  18. Не выставляйте код без проверки

    Перед тем, как выставить новый код на Web-сайт, следует протестировать его. Хороший тест даст вам гарантию, что в ваше Web-приложение не прокрался небезопасный код. Более того, не следует просто обновлять код на сайте; лучше заменить все Web-файлы с надежной резервной копии.

  19. Не храните без необходимости чувствительную информацию в вашей базе данных

    Если хакер взломает вашу базу данных, что он там найдет? Храните ли вы там чувствительную информацию о клиентах, такую как телефонные номера, или номера кредитных карт от старых транзакций? Нужна ли эта информация вашему Web-приложению? Перед кем вам придется отвечать, если эта информация окажется украдена?

    Совершенно ясно, что многое из того, что хранится, не нуждается в этом. И даже если нуждается, то, возможно, не в базе данных Web-приложения. Более того, что касается номеров кредитных карт, нет никакой нужды хранить их в базе данных после завершения транзакции. Если ваша база данных полна такой информации, задайте себе вопрос, хотите ли вы нести ответственность за все это? Представьте себе такой заголовок: Web-сайт ВАШЕЙ КОМПАНИИ взломан, похищено 50000 номеров кредитных карт клиентов. После этого можно просто закрыть компанию – никто больше не станет рисковать связываться с вами.

  20. Не думайте, что это все, что необходимо учесть

    Безусловно, взлом и безопасность постоянно развиваются. Совершенно необходимо постоянно знать как новые способы взлома, так и новейшие стратегии защиты.

    Думать о безопасности – непривычный переход для программистов. После многих лет обучения тому, как делать программы проще для пользователей, приходится учиться, как делать их сложнее для хакеров. Создание защищенных Web-приложений - действительно огромная проблема, но по крайней мере вы можете начать с этих двадцати предупреждений, чего не следует делать. Так что, прочитав эту статью, взгляните на ваш ASP код. Вы можете удивиться тому, что обнаружите.

Мы расшифровали формулу идеальной защиты!

Спойлер: она начинается с подписки на наш канал

Введите правильный пароль — подпишитесь!