Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-33936 — ecdsa(PyPI)におけるサービス拒否(DoS)の脆弱性 | Kitploit
ツール/GitHubGitHub/0xmrma/cve-2026-33936
脆弱性分析コード分析暗号化論文と研究学習と教育
GitHub0xmrma/cve-2026-33936

CVE-2026-33936

ecdsa(PyPI)におけるサービス拒否(DoS)の脆弱性

リポジトリを見る
14ヶ月前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

CVE-2026-33936

ecdsa (PyPI) におけるサービス拒否 (Denial of Service) の脆弱性

はじめに

私は python-ecdsa において、Moderate(中程度) の深刻度の脆弱性を特定し、責任ある開示(responsible disclosure)を行いました。python-ecdsa は、先月だけで 4780 万回ダウンロード された広く使われている Python 暗号ライブラリです。

私は python-ecdsa をレビューしているときに、非常に具体的な問いを念頭に置いてこの問題を発見しました。

不正な DER が長さについて嘘をつき、パーサーがそれを信じすぎてしまうとどうなるのか?

この場合、その問いは実際のバグにたどり着きました。

ecdsa.der の DER パース用ヘルパーは、エンコードされた長さが実際に存在するバイト数よりも多くのバイト数を主張する場合に、切り詰められた(トランケートされた)データを受け入れていました。このような不正な入力は即座に拒否されるべきでした。しかし実際には、パースロジックのより深い部分まで通過し、最終的に鍵パース中に内部の IndexError を引き起こす可能性がありました。

この問題は CVE-2026-33936 として登録されました。

プロジェクト: python-ecdsa on GitHub
パッケージ: ecdsa (pip)
CVE: CVE-2026-33936

photo0

攻撃チェーン

攻撃者が制御する不正な DER → 切り詰められた長さが有効として受け入れられる → パーサーが信頼境界を越えて処理を継続 → SigningKey.from_der() が内部例外パスに到達 → 予期しない IndexError / アプリケーションレベルの DoS リスク


python-ecdsa が行うこと

python-ecdsa は、楕円曲線暗号のための広く使われている Python ライブラリです。

その他の機能の中でも、以下を処理します:

  • 鍵のパース
  • 鍵のシリアライズ
  • DER/ASN.1 デコード
  • 署名および検証ワークフロー

つまり、そのパースコードはセキュリティ境界上に直接位置しています。

ライブラリが外部から提供された鍵素材や構造化されたバイナリ入力を受け入れる場合、正確性は単なる品質の問題ではありません。 それはセキュリティ上の特性です。

拒否されるべき不正な入力が受け入れられると、後段のコードは不正な状態の上に仮定を置き始めます。 そこでバグは「単なるパースの誤り」ではなくなり、脆弱性になり始めます。


この攻撃面が調査に値した理由

DER パースは、小さな検証ミスが過大な影響を持つ可能性がある領域の1つです。

バグの分類は単純明快です:

  • 長さフィールドはある値を示している
  • 実際のバッファはそれより短い内容しか含んでいない
  • パーサーがその主張を信じすぎる
  • 後のコードが、存在すべきでなかった状態に対して操作を行う

これはまさに、セキュリティレビューにおいて確認する価値のある種類の境界の失敗です。

私はここで奇妙な暗号挙動を探していたわけではありません。 構造化入力の処理における信頼の失敗を探していました。

それが正しい調査対象でした。


根本原因

根本的な問題は、不正なまたは切り詰められた入力をパースする際の DER 長さフィールドの検証不備 でした。

具体的には、ecdsa.der.remove_octet_string() は、宣言された DER 長さがバッファ内で実際に利用可能なバイト数を超える入力を受理していました。

つまり、以下のような不正な DER を拒否する代わりに:

  • 宣言された長さ: 4096
  • 実際の残りバイト数: 3

ヘルパーはそれを受け入れ、切り詰められた内容をあたかも有効であるかのように返していました。

これはすでにバグです。

しかし、より強い影響は後段で現れました。

境界で拒否される代わりに不正な入力が受理されたため、SigningKey.from_der() は後で内部例外パスに到達し、以下を送出する可能性がありました:

root@kitploit:~
IndexError: index out of bounds on dimension 1

これは、呼び出し側が不正な入力に対して期待する種類の失敗ではないため重要です。 正しい動作は、UnexpectedDER や ValueError などのクリーンなパース拒否です。

つまり、脆弱性は単独で「IndexError が存在する」ということではありませんでした。

本当の脆弱性は次のとおりです:

  • 不正な DER 長さフィールドが正しく検証されていなかった
  • 切り詰められた入力がパース境界を越えた
  • 結果として後段のコードが内部例外パスに到達した

これは1つのバグチェーンであり、無関係な2つの問題ではありません。


なぜこれが単なるパースの不始末ではなくセキュリティ問題なのか

パーサーが不正な入力を拒否することは、見た目の改善ではありません。 それはセキュリティモデルの一部です。

ここでの重要な区別は、入力が無効だったかどうかではありません。 もちろん無効でした。

重要な区別は、ライブラリが無効な入力に対してどのように振る舞ったか です。

以下の間には実際の違いがあります:

  • 境界で不正な DER をクリーンに拒否すること
  • 不正な DER を受け入れ、より深く処理を続け、内部例外でクラッシュすること

前者は堅牢な動作です。

後者は、ソフトウェアが信頼できない DER をパースし、ライブラリの失敗が想定された例外タイプの範囲内にとどまると仮定する場合、アプリケーションレベルのリスクを生み出します。

そのため、これは単なるパーサー品質のバグではなく、脆弱性として適切に分類されました。


概念実証 (Proof of Concept)

同じバグチェーンの異なる2つの部分を実証するために、2つの PoC を使用しました。

PoC 1: 切り詰められた DER が受理される

最初の PoC は、remove_octet_string() が、宣言された長さが利用可能なバッファを超える切り詰められた DER を受理することを示しました。

これにより、コアとなる検証の失敗が確認できました:

  • バッファがエンコードされた長さより短かった
  • ヘルパーはそれを拒否すべきだった
  • しかし拒否しなかった

PoC 2: 決定論的な内部例外パス

2番目の PoC は、より重要な後段の影響を示しました: 修正前は、SigningKey.from_der() に供給された不正な DER が、決定論的に内部の IndexError を引き起こしていました。

これにより、セキュリティ上関連する影響が確認できました:

  • 不正な入力が境界を越えた
  • パースが必要以上に続行された
  • ライブラリコードがクリーンなパースエラーの代わりに内部例外を送出した

これは「パーサーが奇妙なバイトを受け入れた」よりもはるかに強い結果です。

境界の失敗と実際の運用上の影響の両方を示しています。


なぜ PoC をこのように選んだのか

最初の PoC は根本原因を証明します。

2番目の PoC は影響を証明します。

その分割は重要です。

多くの報告書は次の時点で止まります:

「このパーサーは不正なデータを受け入れる。」

それは有用ですが、なぜそのバグが重要かを示すには必ずしも十分ではありません。

このケースでは、より強力な報告は次のとおりでした:

  • 不正な DER が誤って受理される
  • その受理は自己完結的ではない
  • 鍵パース中のクラッシュを伴う内部例外パスに伝播する可能性がある

これにより、セキュリティ上のストーリーがはるかに明確になります。


修正内容の分析

修正は最小限かつ正確でした。

パッチは、remove_sequence() ですでに使用されている、欠落していた同じ安全性ルールを追加しました:

宣言された長さは利用可能なバッファ内に収まらなければならない

そのチェックは以下に適用されました:

  • remove_constructed()
  • remove_implicit()
  • remove_octet_string()

これらの境界チェックが追加されると、不正な/切り詰められた DER は即座に拒否されました:

root@kitploit:~
UnexpectedDER: Length longer than the provided buffer

そして、以前 IndexError を引き起こしていた PoC は、もはや内部例外パスに到達しませんでした。 パース中にクリーンに失敗します。これはまさに最初から起こるべきだったことです。

これはパーサー脆弱性の修正として理想的なものです:

  • 限定的
  • 明示的
  • 信頼境界に直接結びついている
  • 推論しやすい
  • リグレッションカバレッジで強化されている

再設計なし。 曖昧さなし。 欠落していた場所に正しい検証を追加しただけです。


リグレッションテスト

また、この正確な種類の不正な DER が拒否され続けることを保証するために、焦点を絞ったリグレッションテストも追加しました。

新しいテストは、以下の切り詰められた長さの拒否をカバーしています:

  • remove_octet_string
  • remove_constructed
  • remove_implicit

これは重要でした。なぜなら、このバグは1つの奇妙なランタイムパスに関するものではなく、関連する DER ヘルパー全体で一貫して成立する必要がある検証ルールに関するものだったからです。

修正とテストの追加後、完全なテストスイートがローカルでパスしました:

root@kitploit:~
python -m pytest -q
# 2018 passed, 5 skipped

これは実際の開示作業において重要です。

境界を固定するテストが付属している修正は、はるかに強力です。


深刻度と分類

この問題は妥当に Moderate(中程度) に分類されました。

ここでの主な影響は、機密性や完全性ではなく、可用性/堅牢性です。

アドバイザリの分類は次のとおりでした:

  • CWE-20: 不適切な入力検証 (Improper Input Validation)
  • CVSS: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

これは理にかなっています。

この主張は、不正な DER が攻撃者にコード実行を許すというものではありません。 この主張は、このライブラリを使用して信頼できない DER 素材をパースするソフトウェアにおいて、不正な DER が予期しない内部例外を引き起こす可能性があるというものです。

これは現実的で、擁護可能な DoS 型パースバグです。


開示 (Disclosure)

この問題は、GitHub Security Advisories を通じて非公開で報告されました。

報告には以下が含まれていました:

  • 検証のバグ
  • 決定論的な後段の IndexError 再現コード
  • 最小限のパッチ
  • リグレッションテスト
  • ローカルでの検証結果

メンテナーはこの問題を検証し、ユニットテストとともに修正を導入するよう要請し、調整された修正は GHSA の一時的なプライベートフォークワークフローを通じて進行しました。

CVE 処理の間、GitHub はアドバイザリのテキストが複数の脆弱性を説明している可能性があるように見えたため、当初割り当てを拒否しました。 明確化は単純でした:

これは単一の根本原因(不適切な DER 長さ検証)を持つ 単一の脆弱性 であり、SigningKey.from_der() の IndexError は、同じ不正入力の受理の後段の結果であり、独立して修正可能な別の問題ではない、ということでした。

その明確化で十分であり、問題には以下が割り当てられました:

CVE-2026-33936


このバグが実際に教えてくれること

ここでの教訓は「DER は厄介だ」ということではありません。

DER が厄介なことは誰もがすでに知っています。

本当の教訓は次のとおりです:

不正な構造化入力は、パーサーがそれが無効であると認識した正確な時点で拒否されなければならない。

その境界を逃すと、後段のコードはもはや信頼できない仮定に基づいて動作することになります。

それが、低レベルのパースミスがセキュリティ問題になる方法です。

このバグはまた、報告書(writeup)とトリアージに関する重要なことを強化します:

  • 根本原因が重要
  • 影響経路が重要
  • そして両者をクリーンに結びつけることがさらに重要

「不正な入力が受理された」はストーリーの始まりでした。

「不正な入力が受理され、その後、鍵パース中に内部例外パスへ伝播した」が完全なストーリーでした。

その区別が、この件を明確かつ正確に説明するのに役立ちました。


重要ポイント

  • DER パーサーはセキュリティ境界である
  • 不正な長さフィールドは実際のバッファに対して検証されなければならない
  • 切り詰められた構造化入力の受理はすでにバグである
  • 後段のパースが内部例外パスに到達する場合、それはより強い脆弱性になる
  • クリーンなパース拒否は安全な動作の一部である
  • 最小限の検証修正とリグレッションテストは、パーサーバグの是正においてまさに必要なものである

最後に

この脆弱性は、特殊な暗号に関するものではありませんでした。

それは、パーサーが不正な入力を必要以上に長く信頼していたことに関するものでした。

切り詰められた DER 長さフィールドが境界を越え、拒否されるべきだったのに検証を通過し、最終的に鍵パースでクラッシュを伴う動作を引き起こしました。

そのため、これが CVE-2026-33936 になりました。

影響を受けるヘルパーパーサーに適切な DER 長さの境界チェックを適用することで修正されました。

photo0
ツールをダウンロード