HttpListener: прослушивание порта с явным именем хоста (без подстановочных знаков верхнего уровня) - PullRequest
2 голосов
/ 11 апреля 2019

Предположим, у меня есть машина с IP, например 183.41.22.22. Я хочу прослушать все HTTP-сообщения, которые будут отправлены на порт 43 этого IP на локальном хосте. На самом деле меня не очень интересуют все сообщения, отправляемые на этот порт, только сообщения, отправляемые на https://183.41.22.22:443/CustomerData/

В документации класса HttpListener сказано, что мне следует добавить префикс. Они приводят пример: http://www.contoso.com:8080/customerData/.

Значит ли это, что в моем случае я должен добавить префикс https://183.41.22.22:443/CustomerData/? Или я должен использовать https://localhost:443/CustomerData/?

В качестве альтернативы, поскольку мой компьютер предназначен для этой задачи, я уверен, что никто на моем компьютере никогда не получит никаких сообщений, отправляемых на порт 443. Поэтому, согласно той же документации, я также мог бы использовать подстановочный знак: http://*:443

Тем не менее, документация предупреждает:

Подстановочные знаки верхнего уровня (http://*:80/ и http://+:80) не должны использоваться. Подстановочные знаки верхнего уровня создают уязвимости безопасности приложения. Это относится как к сильным, так и к слабым подстановочным знакам. Используйте явные имена хостов или IP-адреса вместо подстановочных знаков.

Что такое явное имя хоста ? Это часть CustomerData?

Для тех, кто заинтересован, упрощенная часть кода (без надлежащей возможности завершить программу)

using (var httpListener = new HttpListener())
{
    httpListener.Prefixes.Add("https://*:443/");
    httpListener.Start();

    while (true)
    {
        var context = httpListener.GetContext();
        var httpRequest = context.Request();

        // fill the response
        string responseText = this.CreateResponseText(httpRequest);
        byte[] buf = Encoding.UTF8.GetBytes(responseText);
        context.Response.ContentLength64 = buf.Length;
        context.Response.OutputStream.Write(buf, 0, buf.Length);
    };

1 Ответ

1 голос
/ 18 апреля 2019

Что такое явное имя хоста ? Это часть CustomerData?

Имя хоста - это то, что обычно называют «доменом». См. Компоненты URL . Также предупреждение содержит больше информации (которую вы пропустили, возможно, для краткости, но она содержит важную информацию):

Подстановочный знак поддомена (например, *.mysub.com) не имеет такой угрозы безопасности, если вы контролируете весь родительский домен (в отличие от *.com, который уязвим). См. rfc7230 section-5.4 для получения дополнительной информации.

Раздел RFC относится к заголовку HTTP Host . Это является частью спецификации HTTP / 1.1 и было введено, когда люди начали , управляющую более чем одним веб-сайтом на хосте , еще в первые дни Интернета. Хост («машина») используется для простого прослушивания (обычно) порта 80 и обслуживания страниц, запрошенных клиентами. Но когда сеть стала более широко использоваться, возникла необходимость «разместить» несколько сайтов на одной машине. Вы можете использовать foo.com и bar.com, используя DNS, оба указывают на один и тот же IP-адрес, но тогда аппарат не будет знать, отправлять ли домашнюю страницу foo.com или домашнюю страницу bar.com. Итак, заголовок Host был введен; Затем веб-браузеры (точнее, клиенты http) могут сообщить серверу, какой хост им интересен, и предоставить правильную страницу.

Обратите внимание, что каждая часть домена (например, sub.domain.foo.co.uk) потенциально относится к другому хосту (но они также могут также указывать на один и тот же хост). Использование домена верхнего уровня подстановочных знаков (например, *.com или, что еще хуже: *) является потенциальным риском, поскольку любой может получить домен .com (myevildomain.com) и укажите его на свой сервер. Если вы используете *.company.com, никто, кроме company.com, не сможет управлять поддоменами. Почему это угроза безопасности - это совсем другая история, но суть в том, что использование подстановочного знака *.com заставит ваше приложение реагировать на любой заголовок host, заканчивающийся .com, тогда как *.company.com запретит вашему приложению отвечать (вероятно, обманутому) клиенту, запрашивающему myevildomain.com.

...