python / python/cpython

`HTTPPasswordMgr` can send saved HTTPS credentials via HTTP because of incorrect scheme matching

オープン
#155,694 コメント 3 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

3.10 3.11 3.12 3.13 3.14 3.15 3.16 stdlib type-security
主要言語
Python
スター
77.2k
フォーク
35.9k
PR マージ指標
PR 指標を取得中

説明

Bug report

(Copied from the private security issue)

Bug description:
Summary

urllib.request.HTTPPasswordMgr ignores http:// and https:// when matching
saved passwords. A password saved for an HTTPS URL can be sent over unencrypted HTTP.

Details

HTTPPasswordMgr.reduce_uri(self, uri, default_port=True) in Lib/urllib/request.py drops the scheme, and the password manager calls it with both default_port=True and default_port=False. With default_port=False, https://example.com and http://example.com are reduced to the same name/path, so there's an incorrect match.

This conflicts with RFC 9110 section 11.5, which defines a "protection space" using the origin and the realm. The origin includes the scheme.

RFC 7617 section 2.2 also gives HTTP and HTTPS URLs as examples of different Basic authentication
scopes.

PoC

This script saves a password for an HTTPS URL, then shows that the handler adds it to a matching HTTP request.

from base64 import b64decode
from urllib.request import HTTPBasicAuthHandler, HTTPPasswordMgrWithPriorAuth, Request

passwords = HTTPPasswordMgrWithPriorAuth()
passwords.add_password(
    None, "https://example.com/", "alice", "secret", is_authenticated=True
)
request = Request("http://example.com/")
HTTPBasicAuthHandler(passwords).http_request(request)

header = request.get_header("Authorization")
if header:
    print("Vulnerable:", b64decode(header.split()[1]).decode())
else:
    print("Not vulnerable")

is_authenticated=True makes the handler add the password before contacting a server, so the PoC does not need a running web server.

Current output:

Vulnerable: alice:secret

Needs to be fixed in: main, 3.15, 3.14, 3.13, 3.12, 3.11, and 3.10

CPython versions tested on:

3.10, 3.11, 3.12, 3.13, 3.14, 3.15, CPython main branch

Operating systems tested on:

macOS

Linked PRs
  • gh-155696
  • gh-155968
  • gh-155969
  • gh-155970
  • gh-155971
  • gh-155972
  • gh-155973

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

Lib/urllib/request.py の HTTPPasswordMgr.reduce_uri と HTTP パスワード照合フローから始めます。提供されている HTTPPasswordMgrWithPriorAuth の proof of concept を実行し、その後、記載されている Python バージョンと関連するテスト全体で動作を検証します。HTTPS の認証情報が一致する HTTP リクエストに追加されず、既存の認証動作が維持されれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
python
領域
networking, security
issue の種類
バグ
難易度
3/5
見積もり時間
1〜2日
活発さ
停滞
明瞭さ
明確に書かれている
初心者へのやさしさ
25/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。