На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Serafim, fatalist
  
    > Элементарные правила безопасности
      Мне тут пришло в голову, что надо бы собрать некоторый сборник "полезных советов" по части безопасности. Топик не плохо бы дополнить другими примерами очевидных "дыр". Так же хотелось бы иметь еще и примеры кода на PHP.
      Просто, к сожалениию, за частую программисты не выполняют даже самых элементарных малостей по части безопасности. Какследствие этого - "сломать" большое чилсо сайтов может любой школьник, в достаточной мере владеющий интернет эксплорером.


      * SQL-инъекция. Если вы принимаете некоторый параметр из POST- или GET- запроса и потом используете его в формировании SQL-запроса ОБЯЗАТЕЛЬНО проверяйте его на SQL-инъекции.
      Иначе, вызвав ваш скрипт так: script.aspx?id=0);DROP TABLE users;-- взломщик может изрядно попортить вам нервы.
      Простейший код для проверки -
      ExpandedWrap disabled
                Public Const PATTERN_SQL_VALID = "^[^'""\n]*$"
                Public Function IsSafeForSql(ByVal nVal As String) As Boolean
                    Return Text.RegularExpressions.Regex.IsMatch(nVal, PATTERN_SQL_VALID)
                End Function
      Степень опасности: критическая, злоумышленник получает полный или частичный доступ к базе данных.

      * HTML-инъекция. Если вы позволяете пользователям размещать некоторый текст, который в последствии будет выводится другим пользователям, ОБЯЗАТЕЛЬНО проверяйте этот текст на наличие html-тэгов. Иначе, злоумышленник может простым скриптом похитить куки пользователя тем самым, поставив под удар "персональность" его аккаунта(например, если вы храните в этих самых куках логин\пароль для входа).
      Если вам необходимо что бы пользователи могли использовать форматирование своего текста - предложите им использовать bbcode. Благо, в интренете хватает исходных кодов для bbcode-движков на любом языке.
      И не думайте, что удаляя тэги <SCRIPT> вы спасаете ситуацию - помните, скрипты могут также хранится в атрибутах элементов(например в атрибуте onload). В общем случае исключить из html-кода клиентские скрипты невозможно.
      Простейший код, убирающий HTML-inj:
      ExpandedWrap disabled
                Public Function EscapeHTML(ByVal nStr As String) As String
                    Return nStr.Replace("&", "&").Replace(">", ">").Replace("<", "&lt").Replace("""", ""e;").Replace("'", "'")
                End Function
      Степень опасности: средняя, злоумышленник получает доступ к cookie пользователя.

      * Проверяйте Referer. Если на вашем сайте существуют страницы, меняющие личные данные пользователя, ОБЯЗАТЕЛЬНО, проверяйте на этих страницах сайт, с которого была передана ссылка(referer'а). Помните - JavaScript позволяет сделать переход на нужную страницу совершенно незаметно для пользователя - как следствие этого, злоумышленник может, к примеру, удалить аккаунт пользователя из вашей системе написав простой JavaScript-код на странице, а-ля:
      some_invisible_iframe.location="http://your_site/profile.php?mode=del":
      В определенных ситуациях, например если пользователь использует автовход, этот скрипт приведет к невидимой для пользователя загрузке страницы от имени его аккаунта.
      Простой код, проверяющий referer'а такой:
      ExpandedWrap disabled
                    Public Function SecurityCheck(ByVal nPage As Page) As Boolean
                        If Not nPage.Request.UrlReferrer Is Nothing Then
                            If StrComp(nPage.Request.UrlReferrer.Host, nPage.Request.Url.Host, CompareMethod.Text) <> 0 Then
                                nPage.Response.Clear()
                                Dim nOutputHtml As String
                                nOutputHtml = "<html><head><title>Action must be accepted</title></head><body><h2>You must accept this action</h2>Url was coming from another site and you must accept, that you really want to go to it.<br><A href=""" & nPage.Request.Url.AbsolutePath & """>" & nPage.Request.Url.ToString & "</A></body></html>"
                                nPage.Response.Write(nOutputHtml)
                                nPage.Response.End()
                                Return False
                            End If
                        End If
                        Return True
                    End Function

      Степень опасности: выше среднего, злоумышленник может совершать действия от имени пользователя.

      * Проверяйте расширения загружаемых пользователем файлов. Если ваш сайт позволяет пользователям загружать на сервер свои файлы помните, что компилятор PHP или ASP не знает, был ли этот файл создан вами, или загружен другим пользователем. Как следствие из этого - СТРОГО ОГРАНИЧТЕ ПОЛЬЗОВАТЕЛЯМ ВОЗМОЖНОСТЬ ЗАГРУЖАТЬ В ДИРЕКОТОРИЮ ПРИЛОЖЕНИЯ СВОИ ФАЙЛЫ.
      Сделать это можно двумя путями - либо жестко задать допустимые расширения(например .rar, .zip, .doc - и ВСЕ). Второй вариант - пусть пользователи загружают файлы в особую директорию, которая не обслуживается транслятором php\asp. А получать содержимое этой папки следует с помощью скрипта, который сообщит броузеру, что этот файл надо именно скачать, а не открыть(например сообщив, что его content-type это binary).
      ДРУГОГО СПОСОБА НЕТ.
      Если вы думаете, что есть - наверное, вы глубоко заблуждаетесь. Вероятно, вам пришел в голову еще один способ: можно просто задать список "небезопасных" разширений. Однако, этот способ неправильный - едва ли вам удастся перечилить все таки разширения. А если вы про что-то забудете, то ошибка может вам дорого обойтись.
      Ну и еще один так же неверный способ - это разместить в папке с вложениями файл htaccess, отменяющий ассоциацию php-файлов с php-транлятором. В качестве упражнения подумайте, почему этот способ является весьма небезопасным.
      Степень опасности: критическая, злоумышленник получает полный или частичный доступ к сайту.


      * Храните ВСЕ личные данные в сессиях. Сессии можно защитить. Как - это другой вопрос. Факт в том, что сессию, определяемую двумя параметрами - 128-битным идентификатором и IP-адресом пользователя "украсть" практически невозможно. Но не вздумайте хранить id-пользователя в куках и полагаться на то, что если он там есть - значит пользователь осущствели вход. Большей глупости придумать сложно.
      Степень опасности: низкая, злоумышленник шанс украсть "скрытую" от него информацию.

      * Не передавайте данные в GET-запросе, если ихможно взять из базы. Честно говоря, до посещения одного интеренет магазина, мне и в голову не пришло, что id товара, его цену и наличие можно передавать в строке get-запроса. Таким образом, подкорректировав этот запрос можно получить страничку, с "бесплатным" товаром. Что бы этого не произошло - берите всю нужную информацию из базы данных, передавайте только id.
      Степень опасности: низкая, злоумышленник получает возможность фальсифицировать ваши страницы.

      * Помните - пользователь может передать АСБОЛЮТНО ЛЮБОЙ запрос. Не надо надется, что запросы будут идти именно в той последовательности, в которой вы даете пользователю ссылки. Например, если ваша система регистрации работает в два шага - обязательно проверяйте на последнем шаге ВСЕ введенные данные. Не надо надеятся на то, что они были проверены предыдущими скриптами.
      И не думайте, что если на вашей странице стоит JavaScript, следящий за тем, что бы пользователь ввел цифру а не букву, то пользователь и правда передаст вашему пользователю именно цифру, и не в коем случае не букву.
      Степень опасности: не определена. Зависит от того, какую именно проверку вы пропустите.
        Цитата ANDLL @
        Если вы принимаете некоторый параметр из POST- или GET- запроса и потом используете его в формировании SQL-запроса ОБЯЗАТЕЛЬНО проверяйте его на SQL-инъекции.
        Никаких SQL-инъекций не существует. Есть неправильносоставленные запросы.
        http://phpfaq.ru/slashes
          Цитата
          Простейший код для проверки
          бред. По ссылке SiMM'а сходи.

          Цитата
          компилятор PHP или ASP
          ы?

          Цитата
          ДРУГОГО СПОСОБА НЕТ.
          есть.

          Цитата
          Простой код, проверяющий referer'а такой:
          ооо, нифига себе простой.

          Цитата
          можно просто задать список "небезопасных" разширений. Однако, этот способ неправильный - едва ли вам удастся перечилить все таки разширения. А если вы про что-то забудете, то ошибка может вам дорого обойтись.
          Далеко ходить не надо: файл с именем blah.ext1.ext2, где в апаче не зарегана ext2, будет работать так, как будто .ext2 в имени нету.
          Например blah.php.lol будет обработан хендлером для пхп.
            Бред... Автор - тебе самому еще учиться и учиться, а не чайничков наставлять.
            И еще кстати - если такой "гуру кислых щей", то для людей не знакомых с описываемыми проблемами, неплохо бы указать на каком языке ты написал этот, с позволения сказать, код.

            и решения проблем описанных даже кривыми не назвать... В общем "Ф топку" такие "элементарные правила"
              Цитата RussianSpy, 07.11.2006, 15:10:54, 1332709
              неплохо бы указать на каком языке ты написал этот, с позволения сказать, код.

              бейсик. вероятно, подразумевается ASP... если честно, код я ниасилил ( ;) ) какой-то он тяжёлый... :D
                Как это не осилил...
                Проверка существования реферера
                Проверка совпадения доменов реферера и домена запроса, если они не равны то код об ошибке...

                Добавлено
                Цитата RussianSpy @
                Бред... Автор - тебе самому еще учиться и учиться, а не чайничков наставлять.
                И еще кстати - если такой "гуру кислых щей", то для людей не знакомых с описываемыми проблемами, неплохо бы указать на каком языке ты написал этот, с позволения сказать, код. и решения проблем описанных даже кривыми не назвать... В общем "Ф топку" такие "элементарные правила"

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

                Добавлено
                Цитата ANDLL @
                Простой код, проверяющий referer'а такой:


                Public Function SecurityCheck(ByVal nPage As Page) As Boolean
                If Not nPage.Request.UrlReferrer Is Nothing Then
                If StrComp(nPage.Request.UrlReferrer.Host, nPage.Request.Url.Host, CompareMethod.Text) <> 0 Then
                nPage.Response.Clear()
                Dim nOutputHtml As String
                nOutputHtml = "<html><head><title>Action must be accepted</title></head><body><h2>You must accept this action</h2>Url
                was coming from another site and you must accept, that you really want to go to it.<br><A href=""" & nPage.Request.Url.AbsolutePath & """>" &
                nPage.Request.Url.ToString & "</A></body></html>"
                nPage.Response.Write(nOutputHtml)
                nPage.Response.End()
                Return False
                End If
                End If
                Return True
                End Function

                ExpandedWrap disabled
                  function SecurityCheck($nPage){
                           if (isset($_SERVER['HTTP_REFERER'])){
                                   $URL[0] = parse_url($nPage);
                                   $URL[1] = parse_url($_SERVER['HTTP_REFERER']);
                                   $_SERVER['REQUEST_URI'] = htmlspecialchars($_SERVER['REQUEST_URI'],ENT_QUOTES);
                                   if (strcmp($URL[0]['host'],$URL[1]['host']) !== 0){
                                           echo "<html><head><title>Action must be accepted</title></head><body><h2>You must accept this action</h2>Url was coming from another site and you must accept, that you really want to go to it.<br><A href='{$_SERVER['REQUEST_URI']}'>{$_SERVER['REQUEST_URI']}</A></body></html>";
                                            return false;
                                   }
                           }
                           return true;
                   }

                Перевод в лоб
                  Цитата Pr0[)!9Y, 07.11.2006, 20:02:24, 1333225
                  Как это не осилил...

                  так... ПыХПых обычно просто читаю и понимаю, нормальный VB тоже... а этот бейсек при беглом прочтении ничего мне не сказал, а вдумываться в подобный код не вижу смысла...
                    Такс. Давайте все же выбирать выражения?

                    Змей(Чёрный), если лично ты не смог прочесть код с ходу, это не значит, что он кривой, неправильный итд итп.
                    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                    0 пользователей:


                    Рейтинг@Mail.ru
                    [ Script execution time: 0,0460 ]   [ 15 queries used ]   [ Generated: 6.11.24, 20:05 GMT ]