Рубрики
Без рубрики

Утверждение и упрощение урлопена Python

Недавно я написал статью, в которой подробно описывается использование Urlopen () Python для выполнения HTTP -вызовов. В то время как … с меткой Python, Tuperial, Security, WebDev.

Я недавно написал Статья, в которой подробно описывается использование Python’s urlopen () для выполнения HTTP -вызовов Анкет Во время исследования и письма я узнал о OpenerDirector учебный класс. Этот класс предлагает возможность оптимизировать urlopen () Сделайте его более безопасным и предоставьте пользовательскую обработку ошибок.

Проблемы безопасности с Urlopen () по умолчанию ()

Вы можете попробовать следующее в системе Linux:

from urllib.request import urlopen

url = "file:///etc/passwd"

with urlopen(url) as response:
  print(response.read().decode())

Немного тревожно, да? Бандит соглашается Анкет Возможно, вы хотите рассмотреть вопрос о сканировании с Этот инструмент безопасности или его связанный плагин Flake8 .

Приведенный выше код, безусловно, передает урок «дезинфицировать входы пользователей». Конечно, если вы контролируете это URL строка или может убедиться, что она начинается с правильного https:// Схема, тогда все выглядит лучше. Если этот URL -адрес будет поступить от пользовательского ввода, было бы хорошо проверить протокол, по крайней мере, и, что еще лучше, убедитесь, что домен находится в таком случае, как и ожидалось.

Предлагаемое решение

Следующий код приводит к urlopen () команда, которая только открывается https:// URLS по умолчанию:

import urllib.request


class SafeOpener(urllib.request.OpenerDirector):
    def __init__(self, handlers: typing.Iterable = None):
        super().__init__()
        handlers = handlers or (
            urllib.request.UnknownHandler,
            urllib.request.HTTPDefaultErrorHandler,
            urllib.request.HTTPRedirectHandler,
            urllib.request.HTTPSHandler,
            urllib.request.HTTPErrorProcessor,
        )

        for handler_class in handlers:
            self.add_handler(handler_class())


opener = SafeOpener()
urllib.request.install_opener(opener)

После запуска вышеизложенного, используя urllib.request.urlopen () должен потерпеть неудачу с Urlerror Если попытка открыть http: , FTP: , Файл: , Данные: , или любой другой URL, который не имеет https: с начала. Он все равно будет следовать за перенаправлениями автоматически, так же, как urlopen () делает и поднимает исключение для любого кода статуса HTTP, который не за 200 или 300 -е.

Кстати, если вы предпочитаете не переопределять новичок в urlopen () функция, вы можете удалить install_opener (Opener) линия. Тогда позвоните Opener.open () вместо использования urlopen () Анкет

Приведенный выше код предполагает, что все вызовы HTTP будут зашифрованы с помощью TLS (он же «SSL», используя https: ). Это также означает, что тестирование должно будет использовать https: URL также. Подумайте об использовании VCR Библиотека, чтобы издеваться над вызовами HTTP или TrustMe Библиотека, чтобы фактически настроить CERT для тестирования. Если вам нужно использовать незашифрованные http: URLS, однако, вы можете просто добавить urllib.request. Httphandler к обработчики Анкет

Обработчики, определенные

Это цепочка обработчиков по умолчанию, обычно используемой urlopen () :

  • ProxyHandler : Поиск настройки системы для прокси. Если вы на 100% уверены, что ваш инструмент или библиотека никогда не будут использоваться с прокси, то в этом нет необходимости.
  • Неизвестный ихандлер : поднимает Урлерр Если протокол, запрашиваемый в URL, не поддерживается обработчиком в этой цепочке. Очень полезно и рекомендуется.
  • Httphandler : ручки не зашифрованы http:// соединения. Добавьте это только в том случае, если вы уверены, что вам нужна поддержка URL, кроме https:
  • Httpdefaulterrorhandler : своего рода предпочтения, который превращает все ответы в исключения, для обработки вниз по течению. Это необходимо, если вы не планируете обработать статусы, исключения и перенаправления.
  • Httpredirecthandler : Обработки перенаправления (коды состояния 301, 302, 303 или 307) и необходимо, если желательно автоматическое после перенаправления.
  • Ftphandler : ручки FTP: URL. Не обязательно для вызовов HTTP.
  • FileHandler : ручки Файл: URL -адреса и представляет риски безопасности. Редко это должно быть необходимо, если вообще когда -либо.
  • Httperrorprocessor : Окончательный обработчик ответов, повышение любых ответов без 20x (OK)
  • DataHandler : ручки Данные: URL. Трудно представить, почему это было бы необходимо при нормальном использовании, и может представлять потенциальные риски безопасности с помощью пользовательского ввода.

Как может быть очевидно, некоторые из вышеперечисленных редко необходимы, если вообще когда -либо, для работы API HTTP. Вместо этого я рекомендую этот список как счастливую среду между безопасностью и удобством для использования:

  • ProxyHandler
  • Неизвестный
  • Httphandler
  • Httpdefaulterrorhandler
  • Httpredirecthandler
  • Httpshandler
  • Httperrorrorprocessor

Из вышеперечисленного, ProxyHandler Может быть удален, если вы знаете, что вам это не нужно, и даже Httphandler можно удалить, если вы знаете, что только https: URL -адреса будут вызваны. На самом деле, это довольно хорошая комбинация: точка https: это убедиться, что ничто не перехватывает связь, и что нет прокси. Таким образом, список наиболее обнаруженных, что в примере примеров выше:

  • Неизвестный
  • Httpdefaulterrorhandler
  • Httpredirecthandler
  • Httpshandler
  • Httperrorrorprocessor

Пять обработчиков, а не оригинальная девять.

Гибкость

Варианты использования для пользовательского OpenerDirector Случаи выходят за рамки справедливой безопасности и простоты. Подклассом BaseHandler Затем добавление пользовательских методов обработки состояния с такими именами, как http_error_401 Вы создаете свои собственные обработчики, которые затем можно добавить в список обработчиков. Они могут быть использованы для разрешения, повторной каденции и других целей.

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

Оригинал: “https://dev.to/bowmanjd/hardening-and-simplifying-python-s-urlopen-4gee”