prototype(azure_execution_binding): bind HCLAkPub exponent e and key size, reject duplicate JSON keys, and harden _secure_boot_state and authenticode_sha256

オープン
#613 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@drk-ram がすでに取り組んでいます。

2026年10月23日 から。

  • #620 @drk-ram による — オープン

評価

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

調査の方向性

Start with prototype/azure_execution_binding.py, focusing on authenticate_ak, _runtime_claims, _secure_boot_state, and authenticode_sha256; compare the duplicate-key handling with execution_appraisal.py, tdx_collateral.py, and verifier_token.py. Reproduce the supplied SecureBoot event cases, then inspect existing tests for these entry points. Done means all four malformed-input cases are rejected with the specified exceptions and the RSA key checks enforce the stated requirements.

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

説明

needs-review:MEDIUM

What is wrong

At main (a8e3559), prototype/azure_execution_binding.py has four security and input-validation bugs:

  1. authenticate_ak checks only the RSA modulus n of HCLAkPub and ignores kty, e, and key size (GHSA-vwq2 exponent-mismatch class):

    • In prototype/azure_execution_binding.py:466-492, authenticate_ak reads keys[0]["n"] from HCLAkPub, compares if modulus != ak.public_numbers().n: raise ExecutionDenied("ak_not_hcl_bound"), and returns ak (loaded from attacker-supplied packet["ak_pem"]).
    • It never checks keys[0].get("kty") == "RSA", never decodes or validates keys[0]["e"] as a canonical Base64urlUInt, never requires exponent == 65537 and modulus.bit_length() >= 2048, and never checks ak.public_numbers().e == exponent.
    • Supplying an ak_pem with the same modulus n as HCLAkPub and a different public exponent e (e.g., e=3), or an HCLAkPub with a non-RSA kty, weak exponent, or < 2048-bit modulus, passes authenticate_ak.
  2. authenticate_ak and _runtime_claims accept duplicate JSON object keys in HCL runtime JSON:

    • authenticate_ak (line 467) and _runtime_claims (line 512) call json.loads(...) without an object_pairs_hook to reject duplicate keys, unlike execution_appraisal.py, tdx_collateral.py, and verifier_token.py.
  3. _secure_boot_state leaks struct.error / UnicodeDecodeError and accepts truncated variable payloads:

    • In prototype/azure_execution_binding.py:207-218, _secure_boot_state calls name_len, data_len = struct.unpack_from("<QQ", event.data, 16) and event.data[32 : 32 + 2 * name_len].decode("utf-16-le") without checking len(event.data) >= 32 or 32 + 2 * name_len + data_len <= len(event.data) and without catching (struct.error, UnicodeDecodeError) as ExecutionDenied. When data_len exceeds the remaining bytes and 1 byte \x01 follows SecureBoot, Python's slice event.data[32 + 2 * name_len : 32 + 2 * name_len + data_len] silently truncates to b"\x01" and returns True.
  4. authenticode_sha256 leaks struct.error / TypeError on non-bytes or truncated PE images instead of raising ValueError.

Reproduction on a8e3559:

import hashlib, struct
from prototype import azure_execution_binding as aeb

# 1. Truncated SecureBoot UEFI variable event with data_len=9999 and 1 trailing byte b'\x01' passes:
name_utf16 = "SecureBoot".encode("utf-16-le")
data = b"\x00" * 16 + struct.pack("<QQ", len("SecureBoot"), 9999) + name_utf16 + b"\x01"
ev = aeb.UefiEvent(pcr=7, event_type=aeb.EV_EFI_VARIABLE_DRIVER_CONFIG, sha256=hashlib.sha256(data).digest(), data=data)
assert aeb._secure_boot_state([ev]) is True

# 2. Short event data (< 32 bytes) raises raw struct.error instead of ExecutionDenied:
bad_data = b"\x00" * 20
bad_ev = aeb.UefiEvent(pcr=7, event_type=aeb.EV_EFI_VARIABLE_DRIVER_CONFIG, sha256=hashlib.sha256(bad_data).digest(), data=bad_data)
aeb._secure_boot_state([bad_ev])  # raises struct.error

Spec section or file

  • prototype/azure_execution_binding.py (authenticate_ak, _runtime_claims, _secure_boot_state, authenticode_sha256)

Expected behavior

  1. authenticate_ak requires keys[0].get("kty") == "RSA", decodes keys[0]["e"] as a canonical Base64urlUInt, requires exponent == 65537 and modulus.bit_length() >= 2048, and verifies (ak.public_numbers().n, ak.public_numbers().e) == (modulus, exponent).
  2. authenticate_ak and _runtime_claims reject duplicate JSON object keys in HCL runtime JSON with ExecutionDenied.
  3. _secure_boot_state validates len(event.data) >= 32 and 32 + 2 * name_len + data_len <= len(event.data) (requiring exact data_len bytes) and catches (struct.error, UnicodeDecodeError) as ExecutionDenied("secure_boot_state").
  4. authenticode_sha256 validates isinstance(image, bytes) and PE header/section bounds, raising ValueError on malformed inputs.

Impact

An attacker-supplied ak_pem with a mismatched public exponent e (or a truncated PCR 7 SecureBoot variable event) is accepted by azure_execution_binding.

主要言語
Python
スター
37
フォーク
33
平均マージ
1日 18時間
マージ済み PR(30日)
118

環境構築

はじめの一歩

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

agentrust-io/trace-spec のほかの issue

agentrust-io/trace-spec の issue をすべて見る

似ている issue

Python の issue をもっと見る

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

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