The Security Boundary Was in the Wrong Place

The PHANTOM study answers the title’s question by separating authenticity from resource safety. This final synthesis connects the Android and iOS cases, interprets what the study’s numbers and reproductions establish, and maps the defenses to the point where metadata changes form. The result is not that code signing has failed as a security control. It is that a signed package can still be an unsafe input to privileged lifecycle code before its application process exists.

One design error, different processing boundaries

Android and iOS do not share one parser, one memory manager, or one recovery subsystem. Android’s severe paths involve package state being serialized through Binder or written through a bounded Modified UTF-8 representation. iOS’s reported paths involve privileged daemons materializing property-list values under Jetsam memory limits, with the Widget case reaching an early-boot supervision boundary. The mechanisms are different enough that it would be misleading to describe PHANTOM as one universal crash bug.

They do, however, share a design error. Installation metadata begins as external package input. The platform then accepts it into a trusted-looking description of installed software, persists or indexes it, and later sends it to a privileged consumer. At some point the consumer’s representation has a limit: a message buffer, a serialization field, a per-process memory high-water mark, or a recovery window during boot. If the platform did not carry a matching bound across the transition, the consumer receives a value whose cost was never safely established.

That common structure can be stated as a sequence of ownership changes:

  • The package author supplies metadata within a nominally valid format.
  • The installer or package manager interprets it and decides what to retain.
  • A system database, framework object, or extension registry stores part of the interpretation.
  • A launcher, daemon, or other service requests or scans the stored state.
  • A transport or memory manager enforces a hard limit.
  • Exception handling and recovery logic determine whether the failure stays local or spreads.

The first four stages are why the app’s code need not execute. The last two are why the effect can reach the operating system. The metadata does not need to become executable to become consequential; it needs to become input to a component with broader authority and a high-consequence failure path.

This model also explains why the four PHANTOM primitives are variations on one theme. A long string stresses an individual-value assumption. Repeated elements stress count or aggregate-size assumptions. An indirect resource reference delays the true cost until a later resolver materializes it. Signature-chain inflation uses cryptographic metadata that reviewers may regard as trustworthy, even though it still consumes space when returned through a package query. The surface differs, but each primitive asks the platform to handle more data than the earlier validation stage promised.

Android then demonstrates two ways the final boundary can fail. A Binder response can become too large for the transaction buffer and crash a receiving system process. A string can fit in the parser’s in-memory representation but fail when FastDataOutput tries to persist it, producing data loss or an unchecked assertion in system_server. iOS demonstrates another split: on-demand consumers can be terminated by Jetsam while leaving the device generally usable, whereas the Widget boot scan can make a restart loop part of the system’s startup path and lead to kernel panic.

The processing boundary therefore matters as much as the field. A field name does not carry a fixed severity everywhere. The outcome depends on who reads it, when they read it, how they represent it, how they handle failure, and whether recovery changes the input. This is the paper’s reason for separating architectural root cause, processing boundary, and concrete vector. Without that separation, a platform might patch one visible label while leaving the same unbounded-data assumption in a neighboring query or extension path.