Skip to content

fix(selection-monitoring): reject representation-preserving post-issuance runtime aliases #273

Description

@seonghobae

Finding

Canonical Selection Outcome Monitoring evidence is issuance-sealed by HMAC over canonical JSON, but the current export path treats equality of serialized bytes as sufficient post-issuance runtime integrity.

At exact owner head ec35dc87d6be4f44a2c7b44311fa8c89bb080fb3, construction correctly rejects caller-defined str subclasses. After issuance, however, object.__setattr__ can replace an exact built-in text field with a behavior-bearing str subclass carrying the same underlying text. _canonical_plan_json_unchecked(...) serializes that subclass to the same JSON bytes, so the HMAC comparison can still succeed. The live packet therefore retains executable caller-owned runtime state even though the canonical bytes are unchanged. The same class of representation-preserving alias applies to exact date evidence if a post-issuance subclass can reach .isoformat() before an exact-type gate.

This is distinct from the already-covered value-changing tamper case: changing population_snapshot_digest from a…a to f…f changes bytes and is rejected today. The missing regression is same canonical value, different executable runtime type.

Canonical owner / constraints

PR #42 (feat/selection-outcome-monitoring-plan) is the existing Selection Monitoring writer and is already based on protected develop@eb9757f8649aaad026a9865508d9aad50c1a7a4f. Repair there; do not create a second package owner.

Preserve aggregate-only scope, protected-attribute/small-sample/statistical-plan provenance, human-only consequential authority, exact 100% statement/branch coverage, current #258/#259 Foundation dependency order, and all existing privacy/issuance regressions. Do not weaken the process-local seal or accept mutable/subclass evidence merely because canonical bytes are unchanged.

Test-first acceptance

  1. Add an immutable RED regression that issues a valid plan, replaces at least one trust-bearing exact string with a str subclass carrying identical text, and proves current canonical_json() incorrectly succeeds before repair.
  2. The repaired canonical export must fail closed on representation-preserving runtime aliases before invoking caller-controlled methods/comparisons.
  3. Cover exact-string trust fields and exact date/UTC datetime/integer/boolean runtime types consumed by canonical export; valid issued plans must preserve byte-for-byte canonical JSON and SHA-256 behavior.
  4. Keep serialization output/schema and public builder contract unchanged for valid inputs.
  5. Obtain exact-head Foundation/Selection Monitoring coverage/security/review evidence on the successor; predecessor checks do not transfer.

This is a runtime-integrity repair, not a statistical-method or employment-decision authority expansion.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions