Skip to content

Fix GH-21682: Add NOT_SERIALIZABLE to ZipArchive, XMLWriter, XMLReader, SNMP, tidy, tidyNode#26

Closed
iliaal wants to merge 3 commits intomasterfrom
fix/gh-21682-ziparchive-not-serializable
Closed

Fix GH-21682: Add NOT_SERIALIZABLE to ZipArchive, XMLWriter, XMLReader, SNMP, tidy, tidyNode#26
iliaal wants to merge 3 commits intomasterfrom
fix/gh-21682-ziparchive-not-serializable

Conversation

@iliaal
Copy link
Copy Markdown
Owner

@iliaal iliaal commented Apr 9, 2026

Fixes php#21682

Six classes wrap native C handles but allow serialization. Unserializing them produces objects with NULL internal pointers.

Segfault:

  • tidyNode (ext/tidy): crashes on hasChildren(), dangling TidyNode pointer

Silent data loss:

  • ZipArchive (ext/zip): numFiles returns 0, archive contents gone
  • tidy (ext/tidy): body() returns NULL, cleanRepair() no-ops
  • SNMP (ext/snmp): methods run against a dead session without error

Throws on use:

  • XMLWriter (ext/xmlwriter): methods throw "Invalid or uninitialized XMLWriter object"
  • XMLReader (ext/xmlreader): read() throws "Data must be loaded before reading"

Adds @not-serializable to all six so serialize() throws instead of producing broken objects.

Two existing UAF exploit tests (bug72479.phpt, bug72434.phpt) relied on unserialize() instantiating SNMP and ZipArchive objects. With NOT_SERIALIZABLE, unserialize() rejects these classes outright, removing the UAF vector.

iliaal added 2 commits April 9, 2026 12:10
ZipArchive allowed serialization, producing a string that unserializes
into an empty object with no open file handle. Add the
@not-serializable annotation so serialize() throws an exception.

Closes phpGH-21682
These classes wrap native C handles (libxml2 writer/reader, SNMP
session, libTidy document/node) that cannot survive serialization.
Unserializing produces a broken object with NULL internal pointers.
@iliaal iliaal changed the title Fix GH-21682: ZipArchive is missing the NOT_SERIALIZABLE flag Fix GH-21682: Add NOT_SERIALIZABLE to ZipArchive, XMLWriter, XMLReader, SNMP, tidy, tidyNode Apr 9, 2026
@iliaal iliaal force-pushed the fix/gh-21682-ziparchive-not-serializable branch from 118e561 to 92a0bf7 Compare April 9, 2026 17:16
bug72479.phpt and bug72434.phpt tested UAF vulnerabilities through
unserialize(). With NOT_SERIALIZABLE, unserialize() rejects these
classes entirely, preventing the UAF by construction. Update tests
to verify the rejection.
@iliaal iliaal force-pushed the fix/gh-21682-ziparchive-not-serializable branch from 92a0bf7 to b7a9957 Compare April 9, 2026 17:37
@iliaal
Copy link
Copy Markdown
Owner Author

iliaal commented Apr 9, 2026

Submitted upstream as php#21694

@iliaal iliaal closed this Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ZipArchive is missing the NOT_SERIALIZABLE flag

1 participant