Как точно работает защита на основе хеш-фрагмента?

Я изучаю OAuth 2.0 и не могу получить способ обеспечения доступа к токену доступа в неявном потоке предоставления. В спецификации есть некоторые тезисы, а некоторые ответы на SO, которые противоречат друг другу. Кто-нибудь может это понять? Цитаты из ответов SO и спецификации, которые меня путают:

  • (From spec) URI перенаправления, используемый для доставки токена доступа клиенту. токен доступа может быть предоставлен владельцу ресурса или другому приложения с доступом к пользовательскому агенту владельца ресурса.
  • (From spec) Учетные данные доступа к токену (а также любой секретный токен доступа атрибуты) ДОЛЖНЫ быть конфиденциальными в пути и хранении, и только совместно используемый сервером авторизации, серверами ресурсов токен доступа действителен, а клиент, которому принадлежит токен доступа выпущен. Учетные данные доступа к токену ДОЛЖНЫ только передаваться с использованием TLS.
  • (От принятый и поддержанный ответ SO). В неявном потоке токен доступа передается как хэш-фрагмент, только браузеры знают о хэш-фрагменте. Браузеры передают хэш-фрагмент непосредственно на целевую веб-страницу/URL-адрес перенаправления, который является веб-страницей клиента (хэш-фрагмент не является частью HTTP-запроса), поэтому вам нужно прочитать хэш-фрагмент с использованием Javascript. Хэш-фрагмент не может быть перехвачен промежуточными серверами/маршрутизаторами (это важно).

Мой вопрос:

P1 говорит, что токен, доставленный клиенту через URI перенаправления и P2, говорит, что канал доставки ДОЛЖЕН быть TLS-ed. Но P3 говорит, что хэш-фрагмент не отправляется в сеть. Как токен доступа достигает клиента, если он не отправляется, потому что это хэш-фрагмент? Во всяком случае, это должно быть отнесено сетью, не так ли? Или отправить токен с URI перенаправления делает некоторые магии без сетевых сделок?

Единственное вероятное объяснение - под браузером капота посылает только не хэш-часть URL-адреса по сети и после загрузки новой страницы просто вставляет хэш-фрагмент и делает его доступным для JS. Если я прав, я все равно не понимаю, почему мы просто не отправляем токен с надежным, защищенным каналом HTTPS в качестве параметра ответа?

Ответ 1

Поставщик OAuth отправляет токен доступа обратно потребителю OAuth с перенаправлением HTTP-ответа:

HTTP/1.1 302 Found
Location: https://consumer.org/redirect_uri#access_token=1111-2222-3333-4444

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

Затем ваш браузер выполнит новый HTTP-запрос GET конечной точке пользователя:

GET /redirect_uri HTTP/1.1
Host: consumer.org

Обратите внимание, что токен доступа НЕ отправляется потребителю через сеть. Сервер в consumer.org не получит токен в этом HTTP-запросе. Вместо этого веб-страница, возвращаемая из https://consumer.org/redirect_uri, будет содержать javascript, который может и будет читать токен доступа из фрагмента url.

Следовательно, вам нужно доверять код javascript, который вы получаете с сайта consumer.org(используя HTTPS), потому что, если злоумышленник может вводить код, он также может косвенно получать токен доступа (и отправлять его в любом месте).

Пример ответа HTTP от пользователя:

200 OK
Content-Type: text/html

<html><head><script> 
    alert(window.location.hash) 
</script>
</head><body></body></html>