company_banner

Сервис проверки HTTP-заголовков сервера

    Для любого сайта важно правильно настроить HTTP-заголовки. На тему заголовков было написано много статей. Здесь мы обобщили накопленный опыт, документацию RFC. Какие-то из заголовков обязательные, какие-то устаревшие, какие-то могут вносить путаницу и противоречия. Мы сделали пузомерку для автоматической проверки HTTP-заголовков веб-сервера. В отличии от многих других сервисов, которые просто показывают заголовки, данный сервис позволяет:

    1. задать значение типовых заголовков;
    2. добавить свои произвольные заголовки;
    3. указать версию HTTP-протокола: 1.0, 1.1, 2 (проверяет поддерживается ли HTTP/2);
    4. указать метод запроса, время ожидания и данные postdata для отправки на сервер;
    5. также пузомерка проверяет корректность ответа на запросы If-Modified-Since, If-None-Match, если в ответе сервера есть Last-Modified или ETag.

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

    Обязательные заголовки


    • Date
    • Content-Type с указанием charset для текстового контента желательно utf-8
    • Content-Encoding сжатие для текстового контента

    Устаревшие и ненужные заголовки


    • Server с детальной версией веб-сервера
    • X-Power-By
    • X_ASPNET-Version
    • Expires
    • Pragma
    • P3P
    • Via
    • X-UA-Compatible

    Желательные заголовки для безопасности


    • X-Content-Type-Options
    • X-XSS-Protection
    • Strict-Transport-Security
    • Referrer-Policy
    • Feature-Policy
    • Content-Security-Policy или Content-Security-Policy-Report-Only для запрета встроенных скриптов и стилей.

    Заголовки для кэширования


    Обязательны для статического контента с большим сроком кэширования и крайне желательны для динамического контента с небольшим сроком кэширования.

    • Last-Modified
    • ETag
    • Cache-Control
    • Vary
    • Важно, чтобы сервер корректно отвечал на заголовки: If-Modified-Since и If-None-Match

    HTTP/2


    Сейчас сервер должен поддерживать HTTP/2. По умолчанию сервис проверяет работу сервера по HTTP/2. Если ваш сервер не поддерживает HTTP/2, то выбирайте HTTP/1.1.
    ITSOFT
    Поддержка сайтов на базе собственного дата-центра

    Комментарии 24

      +1
      Итоговая оценка качества настройки веб-сервера 11 из 50 возможных

      Спойлер
      image
        0

        У меня 26. Но особо на этом не акцентировал внимание

        0

        Как-то странно у вас с заголовком vary.
        Во-первых, он распарсился дважды, как в оригинале (lowercase), и с первой заглавной буквой с описанием, которое немного меня удивило.


        Vary: сделать кэширование контента и сам контент зависимым от Cookie плохая идея потому что заголовок Cookie подвержен частым изменениям, его могут менять счётчики и прочие JS-библиотеки. Это сводит кэширование на нет. Нужно либо ту часть контента, которая зависит от Cookie подгружать через AJAX либо Cache-Control сделать private.

        Почему это описание однозначно направлено на кеширование? Vary, например, рассказывает гуглоботу, что контент может меняться в зависимости от [...], и разный контент не является маскировкой (cloaking).


        Вообще, очень интересный сервис. Но объяснения было бы неплохо подкрепить ссылками. Например, если бы я не читал статью от гугла про тег Vary, я бы подумал, что Vary — только для кеширования

          0
          Дайте ссылку на результат анализа. Посмотрю что именно там выдалось и прокомментирую.
          0

          https://http.itsoft.ru/?url=https%3A%2F%2Fwww.babai.ru&accept=text%2Fhtml%2Capplication%2Fxhtml%2Bxml%2Capplication%2Fxml%3Bq%3D0.9%2Cimage%2Fwebp%2Cimage%2Fapng%2C*%2F*%3Bq%3D0.8%2Capplication%2Fsigned-exchange%3Bv%3Db3%3Bq%3D0.9&accept_en=gzip%2C+deflate%2C+br&accept_lang=en&if_modified_since=&if_none_match=&user_agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F81.0.4044.129+Safari%2F537.36&h1=&v1=&h2=&v2=&h3=&v3=&h4=&v4=&h5=&v5=&http_version=2&method=GET&timeout=2&postdata=#h2_http_request


          Ошибка — Значение X-XSS-Protection не равно 1


          А оно равно 1 :) Что-то не туда ваш сервис смотрит


          Referrer-Policy strict-origin-when-cross-origin тоже вполне даже "секурно" а вашему сервису нравится только 'no-referrer', 'same-origin', 'strict-origin'


          Это только начал отчёт смотреть :)

            0
            Значение X-XSS-Protection не равно '1; mode=block; report=...' -1 балл.
            Вы не обрабатываете отчёты. См. developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection

            developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
            Send the origin, path, and querystring when performing a same-origin request, only send the origin when the protocol security level stays the same while performing a cross-origin request (HTTPS→HTTPS), and send no header to any less-secure destinations (HTTPS→HTTP).

            Под это HTTP→HTTP тоже подпадает. А мы исходим из того, что HTTP абсолютное зло. Его используют собянинские рукожопы для отправки персональных данных. Поэтому рукожопость лучше отсечь во всех возможных вариантах.

            Продолжайте смотреть. :) Буду рад замечаниям.
              0
              1. Отчёты (также как и report-uri к csp ) никак не влияют ни на что. Придирка пустая. Всё что надо у меня modsecurity в связке с fail2ban отсекают и блокируют.


              2. Вы сферического коня в вакууме рассматриваете? Или таки анализируемый сайт? Какой нафиг http->http если анализируемый сайт на https ?


              3. Обсерватория Мозиллы разумнее всё оценивает при похожей по смыслу проверке.


                0
                1. Да почти всё ни на что не влияет. Выше же сказано, что это просто наше, а больше даже моё мнение. Знать что происходит не так полезно. А можно и не знать. 99.99% в логи не заглядывают. 99% на w3c валидаторе не проверяют. И работает.

                2. Это завязка на другое условие. Сегодня это есть, а завтра нет. Выберите другой вариант, который не допускает передачи реферера при HTTP→HTTP и всё.

                3. Приведите конкретику. Пока это сводится только к тому, что там чуть мягче, а у меня чуть жёстче. Они менее требовательны. Тут нет абсолютной истины.
                  0

                  По пункту 2.


                  Что значит сегодня есть а завтра нет? Куда https может деться? Кстати при прописанном HSTS? И добавленном домене в preload список всех браузеров.


                  Так что никакой угрозы "безопасности" в этом конкретном случае просто нет от strict-origin-when-cross-origin.


                  Я сам параноить люблю, но Вы совсем палку перегнули как в этом случае так и в снижении оценки вашего теста от отсутствия report-uri.


                  Также в ответе Server: Nginx без указания версии тоже нет ничего такого чтобы считать что это ужас как небезопасно и снижать оценку.


                  Мне кажется во всём мера должна быть.


                  P.S. А чем Вам cp1251 не угодил так что аж минус 3 балла? :)))) Это никакого отношения к безопасности не имеет !

                    0
                    SSL-сертификат может кончиться и всё.

                    Я и не говорил, что она есть. Но проверка должна мотивировать запретить использовать HTTP→HTTP, что она и делает.

                    Нет, ничего. Где вы увидели, что за Server оценка снижается? Везде, где снижается, там пишется. А про Server просто предупреждение подумать.

                    Пузомерка не только про безопасность. inline CSS-стили тоже не имеют. И до недавнего времени Яндекс.Метрика требовала unsafe-inline. Я написал в Яндекс, что это неправильно. Они месяц работали и переписывали код Метрики. Переписали и сегодня ответ прислали, что исправили.

                    Кодировка win-1251 плохо уже совместима с жизнью. Она не может воспроизводить все символы, что есть в UTF-8. То есть можно просто потерять часть контента при вставке откуда-то. Например у меня на сайте иконки ошибки, предупреждения — это не графические иконки, а UTF-8 символы.
                    UTF-8 всё ширится и ширится. Ну и что будет с графическими символами при копировании их в кодировку win-1251?
            0
            Не в ту ветку написал ответ. Перенёс.
              0

              Ах да — снижать аж на целых пять пунктов из-за отсутствия Etag при абсолютно правильно работающем и выполняющем совершенно теже функции Last-modefied это вообще за гранью :)

                0
                Last-Modified может быть подвержен глюкам связанным с неправильной настройкой временных зон, отсутствием этой настройки, переходом на летнее, зимнее время, перенастройкой временной зоны.

                Время относительный параметр, а ETag абсолютный.

                Ну и сервис тестирует заголовки независимо друг от друга. Его задача не рейтинг ТОП-100 сгенерить, а обратить внимание. С этой задачей он и справляется раз вы внимание обратили. А дальше уже вам решать, добавлять ETag или и так сойдёт.

              +1
              Если проверяется наличие HTTP/2, то проверяется наличие SSL. Если проверяется SSL, то можно добавить какие протоколы поддерживает — SSL, TLS (1, 1.1, 1.2, 1.3) с указанием устаревших, as ssllabs.

                0
                Спасибо за идею.

                То что вы предлагаете выходило за рамки моего исследования. Всё же версия HTTP присутствует непосредственно в ответе сервера и указывается при отправке HTTP-запроса. И это может быть реальной проблемой, когда на хостинге нет поддержки HTTP/2, например, в штатных пакетах CentOS 7 по умолчанию.

                Сейчас пробую прикрутить проверку TLS, но
                    $ch = curl_init();
                    curl_setopt($ch, CURLOPT_URL, $url);
                    curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_3);
                    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                
                    $r = curl_exec($ch);
                


                Возвращает контент для сервера, который не поддерживает TLS 1.3.

                Попробую разобраться, найти надёжный метод проверки поддержки версий TLS и добавим.
                  +1
                  Попробую разобраться, найти надёжный метод проверки поддержки версий TLS

                  https://github.com/drwetter/testssl.sh или https://github.com/nabla-c0d3/sslyze но зачем когда есть тот же ssllabs и immuniweb? Всёравно специализированные сервисы лучше будут а загромождать свой сервис проверки ответа сервера ИМХО не стоит.

                    0
                    Да, это тоже верно, будет перебор. Надо подумать.
                0

                Для больших файлов (например, дистрибутива PhpStorm 2020.1.1 — 296 МБ) заголовки ответа сервера не выводятся.

                  0
                  http.itsoft.ru/?url=https%3A%2F%2Fdownload-cf.jetbrains.com%2Fwebide%2FPhpStorm-2020.1.1.exe&accept=text%2Fhtml%2Capplication%2Fxhtml%2Bxml%2Capplication%2Fxml%3Bq%3D0.9%2Cimage%2Fwebp%2Cimage%2Fapng%2C*%2F*%3Bq%3D0.8%2Capplication%2Fsigned-exchange%3Bv%3Db3%3Bq%3D0.9&accept_en=gzip%2C+deflate%2C+br&accept_lang=en&if_modified_since=&if_none_match=&user_agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F81.0.4044.129+Safari%2F537.36&h1=&v1=&h2=&v2=&h3=&v3=&h4=&v4=&h5=&v5=&http_version=2&method=HEAD&timeout=2&postdata=#h2_http_request

                  Метод HEAD указать нужно. 296М это всё же перебор, чтобы качать такой контент.
                    0

                    При использовании метода HEAD заголовки нередко отличаются от заголовков при обычном GET-запросе. Теоретически можно разрывать соединение сразу после получения заголовка, без необходимости скачивания файла. Я в своём личном аналогичном инструменте на основе CURL-расширения PHP способа это сделать не нашёл, но, возможно, у вас доступ более низкоуровневый.

                      0
                      Между тем он есть: CURLOPT_RANGE => '0-1' (поддерживается не всеми серверами), CURLOPT_PROGRESSFUNCTION (с ней у меня как-то не срослось) и, возможно, CURLOPT_WRITEFUNCTION (её я просто не заметил).
                • НЛО прилетело и опубликовало эту надпись здесь
                    0
                    А есть сервисы, которые генерируют индивидуальный URL, на который я могу посылать запросы, к примеру, из мобильного приложения для его отладки, а потом через браузер смотреть результаты?
                      0
                      А в чём проблема записать в лог ваш запрос? Ваше же приложение знает, что оно отправляет на сервер в запросе.
                      Ну или сами же можете phpinfo(); сделать и вам распечатается всё, что пришло на вход урла.

                      Поясните какую задачу вы решить хотите.

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

                    Самое читаемое