@raishin/vanguard-frontier-agentic 3.2.0 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (380) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +22 -1
  3. package/.cursor-plugin/plugin.json +22 -1
  4. package/.github/plugin/marketplace.json +1 -1
  5. package/README.md +33 -15
  6. package/agents/cross-functional/revenue-critical-journey-integrity-agent/AGENT.md +112 -0
  7. package/agents/cross-functional/revenue-critical-journey-integrity-agent/harnesses/claude-code.agent.md +111 -0
  8. package/agents/cross-functional/revenue-critical-journey-integrity-agent/harnesses/codex.toml +37 -0
  9. package/agents/cross-functional/revenue-critical-journey-integrity-agent/harnesses/copilot.agent.md +120 -0
  10. package/agents/cross-functional/revenue-critical-journey-integrity-agent/harnesses/cursor.agent.md +112 -0
  11. package/agents/cross-functional/revenue-critical-journey-integrity-agent/harnesses/gemini.agent.md +112 -0
  12. package/agents/cross-functional/revenue-critical-journey-integrity-agent/harnesses/kiro-cli.agent.json +5 -0
  13. package/agents/cross-functional/revenue-critical-journey-integrity-agent/harnesses/kiro-ide.agent.md +111 -0
  14. package/agents/cross-functional/revenue-critical-journey-integrity-agent/metadata.json +42 -0
  15. package/agents/java/README.md +73 -0
  16. package/agents/java/java-application-server-exit-agent/AGENT.md +59 -0
  17. package/agents/java/java-application-server-exit-agent/harnesses/claude-code.agent.md +42 -0
  18. package/agents/java/java-application-server-exit-agent/harnesses/codex.toml +40 -0
  19. package/agents/java/java-application-server-exit-agent/harnesses/copilot.agent.md +42 -0
  20. package/agents/java/java-application-server-exit-agent/harnesses/cursor.agent.md +42 -0
  21. package/agents/java/java-application-server-exit-agent/harnesses/gemini.agent.md +42 -0
  22. package/agents/java/java-application-server-exit-agent/harnesses/kiro-cli.agent.json +5 -0
  23. package/agents/java/java-application-server-exit-agent/harnesses/kiro-ide.agent.md +42 -0
  24. package/agents/java/java-application-server-exit-agent/metadata.json +41 -0
  25. package/agents/java/java-concurrency-and-virtual-thread-agent/AGENT.md +59 -0
  26. package/agents/java/java-concurrency-and-virtual-thread-agent/harnesses/claude-code.agent.md +42 -0
  27. package/agents/java/java-concurrency-and-virtual-thread-agent/harnesses/codex.toml +40 -0
  28. package/agents/java/java-concurrency-and-virtual-thread-agent/harnesses/copilot.agent.md +42 -0
  29. package/agents/java/java-concurrency-and-virtual-thread-agent/harnesses/cursor.agent.md +42 -0
  30. package/agents/java/java-concurrency-and-virtual-thread-agent/harnesses/gemini.agent.md +42 -0
  31. package/agents/java/java-concurrency-and-virtual-thread-agent/harnesses/kiro-cli.agent.json +5 -0
  32. package/agents/java/java-concurrency-and-virtual-thread-agent/harnesses/kiro-ide.agent.md +42 -0
  33. package/agents/java/java-concurrency-and-virtual-thread-agent/metadata.json +41 -0
  34. package/agents/java/java-container-and-kubernetes-readiness-agent/AGENT.md +59 -0
  35. package/agents/java/java-container-and-kubernetes-readiness-agent/harnesses/claude-code.agent.md +42 -0
  36. package/agents/java/java-container-and-kubernetes-readiness-agent/harnesses/codex.toml +40 -0
  37. package/agents/java/java-container-and-kubernetes-readiness-agent/harnesses/copilot.agent.md +42 -0
  38. package/agents/java/java-container-and-kubernetes-readiness-agent/harnesses/cursor.agent.md +42 -0
  39. package/agents/java/java-container-and-kubernetes-readiness-agent/harnesses/gemini.agent.md +42 -0
  40. package/agents/java/java-container-and-kubernetes-readiness-agent/harnesses/kiro-cli.agent.json +5 -0
  41. package/agents/java/java-container-and-kubernetes-readiness-agent/harnesses/kiro-ide.agent.md +42 -0
  42. package/agents/java/java-container-and-kubernetes-readiness-agent/metadata.json +41 -0
  43. package/agents/java/java-database-migration-safety-agent/AGENT.md +59 -0
  44. package/agents/java/java-database-migration-safety-agent/harnesses/claude-code.agent.md +42 -0
  45. package/agents/java/java-database-migration-safety-agent/harnesses/codex.toml +40 -0
  46. package/agents/java/java-database-migration-safety-agent/harnesses/copilot.agent.md +42 -0
  47. package/agents/java/java-database-migration-safety-agent/harnesses/cursor.agent.md +42 -0
  48. package/agents/java/java-database-migration-safety-agent/harnesses/gemini.agent.md +42 -0
  49. package/agents/java/java-database-migration-safety-agent/harnesses/kiro-cli.agent.json +5 -0
  50. package/agents/java/java-database-migration-safety-agent/harnesses/kiro-ide.agent.md +42 -0
  51. package/agents/java/java-database-migration-safety-agent/metadata.json +41 -0
  52. package/agents/java/java-deserialization-and-parser-security-agent/AGENT.md +57 -0
  53. package/agents/java/java-deserialization-and-parser-security-agent/harnesses/claude-code.agent.md +40 -0
  54. package/agents/java/java-deserialization-and-parser-security-agent/harnesses/codex.toml +37 -0
  55. package/agents/java/java-deserialization-and-parser-security-agent/harnesses/copilot.agent.md +40 -0
  56. package/agents/java/java-deserialization-and-parser-security-agent/harnesses/cursor.agent.md +40 -0
  57. package/agents/java/java-deserialization-and-parser-security-agent/harnesses/gemini.agent.md +40 -0
  58. package/agents/java/java-deserialization-and-parser-security-agent/harnesses/kiro-cli.agent.json +5 -0
  59. package/agents/java/java-deserialization-and-parser-security-agent/harnesses/kiro-ide.agent.md +40 -0
  60. package/agents/java/java-deserialization-and-parser-security-agent/metadata.json +41 -0
  61. package/agents/java/java-framework-production-readiness-agent/AGENT.md +57 -0
  62. package/agents/java/java-framework-production-readiness-agent/harnesses/claude-code.agent.md +40 -0
  63. package/agents/java/java-framework-production-readiness-agent/harnesses/codex.toml +39 -0
  64. package/agents/java/java-framework-production-readiness-agent/harnesses/copilot.agent.md +40 -0
  65. package/agents/java/java-framework-production-readiness-agent/harnesses/cursor.agent.md +40 -0
  66. package/agents/java/java-framework-production-readiness-agent/harnesses/gemini.agent.md +40 -0
  67. package/agents/java/java-framework-production-readiness-agent/harnesses/kiro-cli.agent.json +5 -0
  68. package/agents/java/java-framework-production-readiness-agent/harnesses/kiro-ide.agent.md +40 -0
  69. package/agents/java/java-framework-production-readiness-agent/metadata.json +41 -0
  70. package/agents/java/java-jdk-lifecycle-and-upgrade-agent/AGENT.md +55 -0
  71. package/agents/java/java-jdk-lifecycle-and-upgrade-agent/harnesses/claude-code.agent.md +38 -0
  72. package/agents/java/java-jdk-lifecycle-and-upgrade-agent/harnesses/codex.toml +37 -0
  73. package/agents/java/java-jdk-lifecycle-and-upgrade-agent/harnesses/copilot.agent.md +38 -0
  74. package/agents/java/java-jdk-lifecycle-and-upgrade-agent/harnesses/cursor.agent.md +38 -0
  75. package/agents/java/java-jdk-lifecycle-and-upgrade-agent/harnesses/gemini.agent.md +38 -0
  76. package/agents/java/java-jdk-lifecycle-and-upgrade-agent/harnesses/kiro-cli.agent.json +5 -0
  77. package/agents/java/java-jdk-lifecycle-and-upgrade-agent/harnesses/kiro-ide.agent.md +38 -0
  78. package/agents/java/java-jdk-lifecycle-and-upgrade-agent/metadata.json +41 -0
  79. package/agents/java/java-jpa-hibernate-performance-agent/AGENT.md +57 -0
  80. package/agents/java/java-jpa-hibernate-performance-agent/harnesses/claude-code.agent.md +40 -0
  81. package/agents/java/java-jpa-hibernate-performance-agent/harnesses/codex.toml +38 -0
  82. package/agents/java/java-jpa-hibernate-performance-agent/harnesses/copilot.agent.md +40 -0
  83. package/agents/java/java-jpa-hibernate-performance-agent/harnesses/cursor.agent.md +40 -0
  84. package/agents/java/java-jpa-hibernate-performance-agent/harnesses/gemini.agent.md +40 -0
  85. package/agents/java/java-jpa-hibernate-performance-agent/harnesses/kiro-cli.agent.json +5 -0
  86. package/agents/java/java-jpa-hibernate-performance-agent/harnesses/kiro-ide.agent.md +40 -0
  87. package/agents/java/java-jpa-hibernate-performance-agent/metadata.json +41 -0
  88. package/agents/java/java-jvm-performance-and-gc-agent/AGENT.md +60 -0
  89. package/agents/java/java-jvm-performance-and-gc-agent/harnesses/claude-code.agent.md +43 -0
  90. package/agents/java/java-jvm-performance-and-gc-agent/harnesses/codex.toml +40 -0
  91. package/agents/java/java-jvm-performance-and-gc-agent/harnesses/copilot.agent.md +43 -0
  92. package/agents/java/java-jvm-performance-and-gc-agent/harnesses/cursor.agent.md +43 -0
  93. package/agents/java/java-jvm-performance-and-gc-agent/harnesses/gemini.agent.md +43 -0
  94. package/agents/java/java-jvm-performance-and-gc-agent/harnesses/kiro-cli.agent.json +5 -0
  95. package/agents/java/java-jvm-performance-and-gc-agent/harnesses/kiro-ide.agent.md +43 -0
  96. package/agents/java/java-jvm-performance-and-gc-agent/metadata.json +41 -0
  97. package/agents/java/java-kafka-reliability-agent/AGENT.md +60 -0
  98. package/agents/java/java-kafka-reliability-agent/harnesses/claude-code.agent.md +43 -0
  99. package/agents/java/java-kafka-reliability-agent/harnesses/codex.toml +40 -0
  100. package/agents/java/java-kafka-reliability-agent/harnesses/copilot.agent.md +43 -0
  101. package/agents/java/java-kafka-reliability-agent/harnesses/cursor.agent.md +43 -0
  102. package/agents/java/java-kafka-reliability-agent/harnesses/gemini.agent.md +43 -0
  103. package/agents/java/java-kafka-reliability-agent/harnesses/kiro-cli.agent.json +5 -0
  104. package/agents/java/java-kafka-reliability-agent/harnesses/kiro-ide.agent.md +43 -0
  105. package/agents/java/java-kafka-reliability-agent/metadata.json +40 -0
  106. package/agents/java/java-maestro-agent/AGENT.md +51 -0
  107. package/agents/java/java-maestro-agent/harnesses/claude-code.agent.md +34 -0
  108. package/agents/java/java-maestro-agent/harnesses/codex.toml +37 -0
  109. package/agents/java/java-maestro-agent/harnesses/copilot.agent.md +34 -0
  110. package/agents/java/java-maestro-agent/harnesses/cursor.agent.md +34 -0
  111. package/agents/java/java-maestro-agent/harnesses/gemini.agent.md +34 -0
  112. package/agents/java/java-maestro-agent/harnesses/kiro-cli.agent.json +5 -0
  113. package/agents/java/java-maestro-agent/harnesses/kiro-ide.agent.md +34 -0
  114. package/agents/java/java-maestro-agent/metadata.json +40 -0
  115. package/agents/java/java-resilience-pattern-agent/AGENT.md +59 -0
  116. package/agents/java/java-resilience-pattern-agent/harnesses/claude-code.agent.md +42 -0
  117. package/agents/java/java-resilience-pattern-agent/harnesses/codex.toml +39 -0
  118. package/agents/java/java-resilience-pattern-agent/harnesses/copilot.agent.md +42 -0
  119. package/agents/java/java-resilience-pattern-agent/harnesses/cursor.agent.md +42 -0
  120. package/agents/java/java-resilience-pattern-agent/harnesses/gemini.agent.md +42 -0
  121. package/agents/java/java-resilience-pattern-agent/harnesses/kiro-cli.agent.json +5 -0
  122. package/agents/java/java-resilience-pattern-agent/harnesses/kiro-ide.agent.md +42 -0
  123. package/agents/java/java-resilience-pattern-agent/metadata.json +42 -0
  124. package/agents/java/java-spring-security-agent/AGENT.md +59 -0
  125. package/agents/java/java-spring-security-agent/harnesses/claude-code.agent.md +42 -0
  126. package/agents/java/java-spring-security-agent/harnesses/codex.toml +39 -0
  127. package/agents/java/java-spring-security-agent/harnesses/copilot.agent.md +42 -0
  128. package/agents/java/java-spring-security-agent/harnesses/cursor.agent.md +42 -0
  129. package/agents/java/java-spring-security-agent/harnesses/gemini.agent.md +42 -0
  130. package/agents/java/java-spring-security-agent/harnesses/kiro-cli.agent.json +5 -0
  131. package/agents/java/java-spring-security-agent/harnesses/kiro-ide.agent.md +42 -0
  132. package/agents/java/java-spring-security-agent/metadata.json +40 -0
  133. package/agents/java/java-test-architecture-agent/AGENT.md +60 -0
  134. package/agents/java/java-test-architecture-agent/harnesses/claude-code.agent.md +43 -0
  135. package/agents/java/java-test-architecture-agent/harnesses/codex.toml +40 -0
  136. package/agents/java/java-test-architecture-agent/harnesses/copilot.agent.md +43 -0
  137. package/agents/java/java-test-architecture-agent/harnesses/cursor.agent.md +43 -0
  138. package/agents/java/java-test-architecture-agent/harnesses/gemini.agent.md +43 -0
  139. package/agents/java/java-test-architecture-agent/harnesses/kiro-cli.agent.json +5 -0
  140. package/agents/java/java-test-architecture-agent/harnesses/kiro-ide.agent.md +43 -0
  141. package/agents/java/java-test-architecture-agent/metadata.json +42 -0
  142. package/agents/java/java-transaction-and-consistency-agent/AGENT.md +58 -0
  143. package/agents/java/java-transaction-and-consistency-agent/harnesses/claude-code.agent.md +41 -0
  144. package/agents/java/java-transaction-and-consistency-agent/harnesses/codex.toml +40 -0
  145. package/agents/java/java-transaction-and-consistency-agent/harnesses/copilot.agent.md +41 -0
  146. package/agents/java/java-transaction-and-consistency-agent/harnesses/cursor.agent.md +41 -0
  147. package/agents/java/java-transaction-and-consistency-agent/harnesses/gemini.agent.md +41 -0
  148. package/agents/java/java-transaction-and-consistency-agent/harnesses/kiro-cli.agent.json +5 -0
  149. package/agents/java/java-transaction-and-consistency-agent/harnesses/kiro-ide.agent.md +41 -0
  150. package/agents/java/java-transaction-and-consistency-agent/metadata.json +41 -0
  151. package/agents/php/composer-supply-chain-agent/AGENT.md +114 -0
  152. package/agents/php/composer-supply-chain-agent/harnesses/claude-code.agent.md +113 -0
  153. package/agents/php/composer-supply-chain-agent/harnesses/codex.toml +119 -0
  154. package/agents/php/composer-supply-chain-agent/harnesses/copilot.agent.md +122 -0
  155. package/agents/php/composer-supply-chain-agent/harnesses/cursor.agent.md +114 -0
  156. package/agents/php/composer-supply-chain-agent/harnesses/gemini.agent.md +114 -0
  157. package/agents/php/composer-supply-chain-agent/harnesses/kiro-cli.agent.json +5 -0
  158. package/agents/php/composer-supply-chain-agent/harnesses/kiro-ide.agent.md +113 -0
  159. package/agents/php/composer-supply-chain-agent/metadata.json +31 -0
  160. package/agents/php/php-application-security-agent/AGENT.md +113 -0
  161. package/agents/php/php-application-security-agent/harnesses/claude-code.agent.md +112 -0
  162. package/agents/php/php-application-security-agent/harnesses/codex.toml +118 -0
  163. package/agents/php/php-application-security-agent/harnesses/copilot.agent.md +121 -0
  164. package/agents/php/php-application-security-agent/harnesses/cursor.agent.md +113 -0
  165. package/agents/php/php-application-security-agent/harnesses/gemini.agent.md +113 -0
  166. package/agents/php/php-application-security-agent/harnesses/kiro-cli.agent.json +5 -0
  167. package/agents/php/php-application-security-agent/harnesses/kiro-ide.agent.md +112 -0
  168. package/agents/php/php-application-security-agent/metadata.json +31 -0
  169. package/agents/php/php-maestro-agent/AGENT.md +81 -0
  170. package/agents/php/php-maestro-agent/harnesses/claude-code.agent.md +80 -0
  171. package/agents/php/php-maestro-agent/harnesses/codex.toml +86 -0
  172. package/agents/php/php-maestro-agent/harnesses/copilot.agent.md +89 -0
  173. package/agents/php/php-maestro-agent/harnesses/cursor.agent.md +81 -0
  174. package/agents/php/php-maestro-agent/harnesses/gemini.agent.md +81 -0
  175. package/agents/php/php-maestro-agent/harnesses/kiro-cli.agent.json +5 -0
  176. package/agents/php/php-maestro-agent/harnesses/kiro-ide.agent.md +80 -0
  177. package/agents/php/php-maestro-agent/metadata.json +31 -0
  178. package/agents/php/php-runtime-upgrade-readiness-agent/AGENT.md +117 -0
  179. package/agents/php/php-runtime-upgrade-readiness-agent/harnesses/claude-code.agent.md +116 -0
  180. package/agents/php/php-runtime-upgrade-readiness-agent/harnesses/codex.toml +122 -0
  181. package/agents/php/php-runtime-upgrade-readiness-agent/harnesses/copilot.agent.md +125 -0
  182. package/agents/php/php-runtime-upgrade-readiness-agent/harnesses/cursor.agent.md +117 -0
  183. package/agents/php/php-runtime-upgrade-readiness-agent/harnesses/gemini.agent.md +117 -0
  184. package/agents/php/php-runtime-upgrade-readiness-agent/harnesses/kiro-cli.agent.json +5 -0
  185. package/agents/php/php-runtime-upgrade-readiness-agent/harnesses/kiro-ide.agent.md +116 -0
  186. package/agents/php/php-runtime-upgrade-readiness-agent/metadata.json +30 -0
  187. package/agents/php/wordpress-security-agent/AGENT.md +107 -0
  188. package/agents/php/wordpress-security-agent/harnesses/claude-code.agent.md +106 -0
  189. package/agents/php/wordpress-security-agent/harnesses/codex.toml +112 -0
  190. package/agents/php/wordpress-security-agent/harnesses/copilot.agent.md +115 -0
  191. package/agents/php/wordpress-security-agent/harnesses/cursor.agent.md +107 -0
  192. package/agents/php/wordpress-security-agent/harnesses/gemini.agent.md +107 -0
  193. package/agents/php/wordpress-security-agent/harnesses/kiro-cli.agent.json +5 -0
  194. package/agents/php/wordpress-security-agent/harnesses/kiro-ide.agent.md +106 -0
  195. package/agents/php/wordpress-security-agent/metadata.json +31 -0
  196. package/catalog/agents.json +609 -0
  197. package/catalog/asset-integrity.json +1338 -48
  198. package/catalog/install-roles.json +64 -4
  199. package/catalog/model-assignments.json +777 -84
  200. package/catalog/model-policy.json +5 -0
  201. package/catalog/skill-manifest.json +657 -0
  202. package/catalog/skills.json +567 -0
  203. package/package.json +1 -1
  204. package/plugins/vanguard-frontier-agentic/.codex-plugin/plugin.json +1 -1
  205. package/powers/README.md +4 -2
  206. package/powers/vanguard-generic/POWER.md +1 -1
  207. package/powers/vanguard-java/POWER.md +40 -0
  208. package/powers/vanguard-php/POWER.md +40 -0
  209. package/schemas/agent.schema.json +18 -1
  210. package/schemas/skill.schema.json +27 -1
  211. package/scripts/generate-docs-data.mjs +1 -1
  212. package/skills/cross-functional/revenue-critical-journey-integrity-review/SKILL.md +108 -0
  213. package/skills/cross-functional/revenue-critical-journey-integrity-review/metadata.json +29 -0
  214. package/skills/cross-functional/revenue-critical-journey-integrity-review/references/idempotency-and-safe-retries.md +155 -0
  215. package/skills/cross-functional/revenue-critical-journey-integrity-review/references/official-sources.md +71 -0
  216. package/skills/cross-functional/revenue-critical-journey-integrity-review/references/pci-saq-scope-boundaries.md +118 -0
  217. package/skills/cross-functional/revenue-critical-journey-integrity-review/references/server-side-revalidation-trust-boundary.md +134 -0
  218. package/skills/cross-functional/revenue-critical-journey-integrity-review/references/webhook-delivery-dedup-ordering.md +146 -0
  219. package/skills/cross-functional/revenue-critical-journey-integrity-review/references/workflow-and-output.md +100 -0
  220. package/skills/java/java-application-server-exit/SKILL.md +59 -0
  221. package/skills/java/java-application-server-exit/metadata.json +27 -0
  222. package/skills/java/java-application-server-exit/references/decision-model-and-cost-inputs.md +60 -0
  223. package/skills/java/java-application-server-exit/references/vendor-lifecycle-sources.md +52 -0
  224. package/skills/java/java-application-server-exit/references/workflow-and-output.md +102 -0
  225. package/skills/java/java-concurrency-and-virtual-thread/SKILL.md +60 -0
  226. package/skills/java/java-concurrency-and-virtual-thread/metadata.json +27 -0
  227. package/skills/java/java-concurrency-and-virtual-thread/references/carrier-pinning-and-jdk-version-gating.md +42 -0
  228. package/skills/java/java-concurrency-and-virtual-thread/references/virtual-thread-lifecycle-and-resource-bounds.md +71 -0
  229. package/skills/java/java-concurrency-and-virtual-thread/references/workflow-and-output.md +102 -0
  230. package/skills/java/java-container-and-kubernetes-readiness/SKILL.md +58 -0
  231. package/skills/java/java-container-and-kubernetes-readiness/metadata.json +27 -0
  232. package/skills/java/java-container-and-kubernetes-readiness/references/cpu-and-gc-probe-interaction.md +46 -0
  233. package/skills/java/java-container-and-kubernetes-readiness/references/memory-headroom-and-heap-sizing.md +37 -0
  234. package/skills/java/java-container-and-kubernetes-readiness/references/workflow-and-output.md +103 -0
  235. package/skills/java/java-database-migration-safety/SKILL.md +58 -0
  236. package/skills/java/java-database-migration-safety/metadata.json +27 -0
  237. package/skills/java/java-database-migration-safety/references/expand-contract-and-destructive-ddl.md +57 -0
  238. package/skills/java/java-database-migration-safety/references/migration-integrity-and-ordering.md +51 -0
  239. package/skills/java/java-database-migration-safety/references/workflow-and-output.md +95 -0
  240. package/skills/java/java-deserialization-and-parser-security/SKILL.md +53 -0
  241. package/skills/java/java-deserialization-and-parser-security/metadata.json +27 -0
  242. package/skills/java/java-deserialization-and-parser-security/references/sink-hardening-catalog.md +56 -0
  243. package/skills/java/java-deserialization-and-parser-security/references/workflow-and-output.md +78 -0
  244. package/skills/java/java-framework-production-readiness/SKILL.md +59 -0
  245. package/skills/java/java-framework-production-readiness/metadata.json +27 -0
  246. package/skills/java/java-framework-production-readiness/references/framework-readiness-checklist.md +78 -0
  247. package/skills/java/java-framework-production-readiness/references/framework-support-and-eol-boundaries.md +47 -0
  248. package/skills/java/java-framework-production-readiness/references/workflow-and-output.md +108 -0
  249. package/skills/java/java-jdk-lifecycle-and-upgrade/SKILL.md +54 -0
  250. package/skills/java/java-jdk-lifecycle-and-upgrade/metadata.json +27 -0
  251. package/skills/java/java-jdk-lifecycle-and-upgrade/references/jdk-support-and-license-boundaries.md +61 -0
  252. package/skills/java/java-jdk-lifecycle-and-upgrade/references/lts-migration-and-language-features.md +159 -0
  253. package/skills/java/java-jdk-lifecycle-and-upgrade/references/workflow-and-output.md +101 -0
  254. package/skills/java/java-jpa-hibernate-performance/SKILL.md +53 -0
  255. package/skills/java/java-jpa-hibernate-performance/metadata.json +27 -0
  256. package/skills/java/java-jpa-hibernate-performance/references/fetch-strategy-and-pool-evidence.md +45 -0
  257. package/skills/java/java-jpa-hibernate-performance/references/workflow-and-output.md +94 -0
  258. package/skills/java/java-jvm-performance-and-gc/SKILL.md +59 -0
  259. package/skills/java/java-jvm-performance-and-gc/metadata.json +27 -0
  260. package/skills/java/java-jvm-performance-and-gc/references/allocation-pressure-and-oom-triage.md +58 -0
  261. package/skills/java/java-jvm-performance-and-gc/references/collector-selection-and-refusal-contract.md +44 -0
  262. package/skills/java/java-jvm-performance-and-gc/references/workflow-and-output.md +101 -0
  263. package/skills/java/java-kafka-reliability/SKILL.md +58 -0
  264. package/skills/java/java-kafka-reliability/metadata.json +26 -0
  265. package/skills/java/java-kafka-reliability/references/exactly-once-and-delivery-semantics.md +64 -0
  266. package/skills/java/java-kafka-reliability/references/ordering-lag-rebalance-and-durability.md +50 -0
  267. package/skills/java/java-kafka-reliability/references/workflow-and-output.md +107 -0
  268. package/skills/java/java-maestro/SKILL.md +111 -0
  269. package/skills/java/java-maestro/metadata.json +26 -0
  270. package/skills/java/java-resilience-pattern/SKILL.md +60 -0
  271. package/skills/java/java-resilience-pattern/metadata.json +28 -0
  272. package/skills/java/java-resilience-pattern/references/aspect-order-and-composition.md +59 -0
  273. package/skills/java/java-resilience-pattern/references/isolation-and-timeout-budgets.md +57 -0
  274. package/skills/java/java-resilience-pattern/references/workflow-and-output.md +103 -0
  275. package/skills/java/java-spring-security/SKILL.md +60 -0
  276. package/skills/java/java-spring-security/metadata.json +26 -0
  277. package/skills/java/java-spring-security/references/actuator-endpoint-exposure-catalog.md +45 -0
  278. package/skills/java/java-spring-security/references/filter-chain-and-authorization-catalog.md +69 -0
  279. package/skills/java/java-spring-security/references/workflow-and-output.md +79 -0
  280. package/skills/java/java-test-architecture/SKILL.md +64 -0
  281. package/skills/java/java-test-architecture/metadata.json +28 -0
  282. package/skills/java/java-test-architecture/references/junit5-isolation-and-parallelism.md +59 -0
  283. package/skills/java/java-test-architecture/references/testcontainers-and-archunit-discipline.md +71 -0
  284. package/skills/java/java-test-architecture/references/workflow-and-output.md +101 -0
  285. package/skills/java/java-transaction-and-consistency/SKILL.md +60 -0
  286. package/skills/java/java-transaction-and-consistency/metadata.json +27 -0
  287. package/skills/java/java-transaction-and-consistency/references/dual-write-outbox-and-saga-patterns.md +125 -0
  288. package/skills/java/java-transaction-and-consistency/references/propagation-isolation-and-proxy-pitfalls.md +112 -0
  289. package/skills/java/java-transaction-and-consistency/references/workflow-and-output.md +94 -0
  290. package/skills/php/composer-audit-supply-chain-review/SKILL.md +108 -0
  291. package/skills/php/composer-audit-supply-chain-review/metadata.json +20 -0
  292. package/skills/php/composer-audit-supply-chain-review/references/abandoned-and-advisory-governance.md +30 -0
  293. package/skills/php/composer-audit-supply-chain-review/references/composer-audit-policy.md +35 -0
  294. package/skills/php/composer-audit-supply-chain-review/references/lockfile-integrity.md +27 -0
  295. package/skills/php/php-maestro/SKILL.md +51 -0
  296. package/skills/php/php-maestro/metadata.json +20 -0
  297. package/skills/php/php-maestro/references/hard-gates-and-escalation.md +67 -0
  298. package/skills/php/php-maestro/references/routing-and-dispatch.md +91 -0
  299. package/skills/php/php-runtime-eol-opcache-fpm-review/SKILL.md +109 -0
  300. package/skills/php/php-runtime-eol-opcache-fpm-review/metadata.json +19 -0
  301. package/skills/php/php-runtime-eol-opcache-fpm-review/references/opcache-production-config.md +91 -0
  302. package/skills/php/php-runtime-eol-opcache-fpm-review/references/php-fpm-pool-tuning.md +87 -0
  303. package/skills/php/php-runtime-eol-opcache-fpm-review/references/php-version-lifecycle.md +102 -0
  304. package/skills/php/php-session-upload-deserialization-review/SKILL.md +111 -0
  305. package/skills/php/php-session-upload-deserialization-review/metadata.json +20 -0
  306. package/skills/php/php-session-upload-deserialization-review/references/file-upload-security.md +119 -0
  307. package/skills/php/php-session-upload-deserialization-review/references/session-security.md +126 -0
  308. package/skills/php/php-session-upload-deserialization-review/references/unserialize-object-injection.md +121 -0
  309. package/skills/php/wordpress-rest-block-security-review/SKILL.md +106 -0
  310. package/skills/php/wordpress-rest-block-security-review/metadata.json +20 -0
  311. package/skills/php/wordpress-rest-block-security-review/references/dynamic-block-output-escaping.md +42 -0
  312. package/skills/php/wordpress-rest-block-security-review/references/input-sanitize-output-escape.md +52 -0
  313. package/skills/php/wordpress-rest-block-security-review/references/rest-api-permission-callback.md +48 -0
  314. package/tests/fixtures/java-maestro-routing/expected/001-happy-application-server-exit.json +6 -0
  315. package/tests/fixtures/java-maestro-routing/expected/002-happy-concurrency-and-virtual-thread.json +6 -0
  316. package/tests/fixtures/java-maestro-routing/expected/003-happy-container-and-kubernetes-readiness.json +6 -0
  317. package/tests/fixtures/java-maestro-routing/expected/004-happy-database-migration-safety.json +6 -0
  318. package/tests/fixtures/java-maestro-routing/expected/005-happy-deserialization-and-parser-security.json +6 -0
  319. package/tests/fixtures/java-maestro-routing/expected/006-happy-framework-production-readiness.json +6 -0
  320. package/tests/fixtures/java-maestro-routing/expected/007-happy-jdk-lifecycle-and-upgrade.json +6 -0
  321. package/tests/fixtures/java-maestro-routing/expected/008-happy-jpa-hibernate-performance.json +6 -0
  322. package/tests/fixtures/java-maestro-routing/expected/009-happy-jvm-performance-and-gc.json +6 -0
  323. package/tests/fixtures/java-maestro-routing/expected/010-happy-kafka-reliability.json +6 -0
  324. package/tests/fixtures/java-maestro-routing/expected/011-happy-resilience-pattern.json +6 -0
  325. package/tests/fixtures/java-maestro-routing/expected/012-happy-spring-security.json +6 -0
  326. package/tests/fixtures/java-maestro-routing/expected/013-happy-test-architecture.json +6 -0
  327. package/tests/fixtures/java-maestro-routing/expected/014-happy-transaction-and-consistency.json +6 -0
  328. package/tests/fixtures/java-maestro-routing/expected/adv-ambiguous.json +4 -0
  329. package/tests/fixtures/java-maestro-routing/expected/adv-instruction-injection.json +6 -0
  330. package/tests/fixtures/java-maestro-routing/expected/adv-persona-replacement.json +6 -0
  331. package/tests/fixtures/java-maestro-routing/expected/adv-secrets-bait.json +6 -0
  332. package/tests/fixtures/java-maestro-routing/inputs/001-happy-application-server-exit.json +7 -0
  333. package/tests/fixtures/java-maestro-routing/inputs/002-happy-concurrency-and-virtual-thread.json +7 -0
  334. package/tests/fixtures/java-maestro-routing/inputs/003-happy-container-and-kubernetes-readiness.json +7 -0
  335. package/tests/fixtures/java-maestro-routing/inputs/004-happy-database-migration-safety.json +7 -0
  336. package/tests/fixtures/java-maestro-routing/inputs/005-happy-deserialization-and-parser-security.json +7 -0
  337. package/tests/fixtures/java-maestro-routing/inputs/006-happy-framework-production-readiness.json +7 -0
  338. package/tests/fixtures/java-maestro-routing/inputs/007-happy-jdk-lifecycle-and-upgrade.json +7 -0
  339. package/tests/fixtures/java-maestro-routing/inputs/008-happy-jpa-hibernate-performance.json +7 -0
  340. package/tests/fixtures/java-maestro-routing/inputs/009-happy-jvm-performance-and-gc.json +7 -0
  341. package/tests/fixtures/java-maestro-routing/inputs/010-happy-kafka-reliability.json +7 -0
  342. package/tests/fixtures/java-maestro-routing/inputs/011-happy-resilience-pattern.json +7 -0
  343. package/tests/fixtures/java-maestro-routing/inputs/012-happy-spring-security.json +7 -0
  344. package/tests/fixtures/java-maestro-routing/inputs/013-happy-test-architecture.json +7 -0
  345. package/tests/fixtures/java-maestro-routing/inputs/014-happy-transaction-and-consistency.json +7 -0
  346. package/tests/fixtures/java-maestro-routing/inputs/adv-ambiguous.json +7 -0
  347. package/tests/fixtures/java-maestro-routing/inputs/adv-instruction-injection.json +7 -0
  348. package/tests/fixtures/java-maestro-routing/inputs/adv-persona-replacement.json +7 -0
  349. package/tests/fixtures/java-maestro-routing/inputs/adv-secrets-bait.json +7 -0
  350. package/tests/fixtures/java-maestro-routing/taxonomy.json +177 -0
  351. package/tests/fixtures/php-maestro-routing/expected/001-happy-application-security.json +6 -0
  352. package/tests/fixtures/php-maestro-routing/expected/002-happy-composer-supply-chain.json +6 -0
  353. package/tests/fixtures/php-maestro-routing/expected/003-happy-runtime-upgrade-readiness.json +6 -0
  354. package/tests/fixtures/php-maestro-routing/expected/004-happy-wordpress-security.json +6 -0
  355. package/tests/fixtures/php-maestro-routing/expected/005-happy-unserialize-session.json +6 -0
  356. package/tests/fixtures/php-maestro-routing/expected/006-happy-fpm-opcache.json +6 -0
  357. package/tests/fixtures/php-maestro-routing/expected/007-happy-composer-audit.json +6 -0
  358. package/tests/fixtures/php-maestro-routing/expected/008-happy-wp-permission-callback.json +6 -0
  359. package/tests/fixtures/php-maestro-routing/expected/adv-ambiguous.json +4 -0
  360. package/tests/fixtures/php-maestro-routing/expected/adv-instruction-injection.json +6 -0
  361. package/tests/fixtures/php-maestro-routing/expected/adv-liveguard-db-migration-prod.json +4 -0
  362. package/tests/fixtures/php-maestro-routing/expected/adv-liveguard-deploy-prod.json +4 -0
  363. package/tests/fixtures/php-maestro-routing/expected/adv-persona-replacement.json +6 -0
  364. package/tests/fixtures/php-maestro-routing/expected/adv-secrets-bait.json +7 -0
  365. package/tests/fixtures/php-maestro-routing/inputs/001-happy-application-security.json +7 -0
  366. package/tests/fixtures/php-maestro-routing/inputs/002-happy-composer-supply-chain.json +7 -0
  367. package/tests/fixtures/php-maestro-routing/inputs/003-happy-runtime-upgrade-readiness.json +7 -0
  368. package/tests/fixtures/php-maestro-routing/inputs/004-happy-wordpress-security.json +7 -0
  369. package/tests/fixtures/php-maestro-routing/inputs/005-happy-unserialize-session.json +7 -0
  370. package/tests/fixtures/php-maestro-routing/inputs/006-happy-fpm-opcache.json +7 -0
  371. package/tests/fixtures/php-maestro-routing/inputs/007-happy-composer-audit.json +7 -0
  372. package/tests/fixtures/php-maestro-routing/inputs/008-happy-wp-permission-callback.json +7 -0
  373. package/tests/fixtures/php-maestro-routing/inputs/adv-ambiguous.json +7 -0
  374. package/tests/fixtures/php-maestro-routing/inputs/adv-instruction-injection.json +7 -0
  375. package/tests/fixtures/php-maestro-routing/inputs/adv-liveguard-db-migration-prod.json +7 -0
  376. package/tests/fixtures/php-maestro-routing/inputs/adv-liveguard-deploy-prod.json +7 -0
  377. package/tests/fixtures/php-maestro-routing/inputs/adv-persona-replacement.json +7 -0
  378. package/tests/fixtures/php-maestro-routing/inputs/adv-secrets-bait.json +7 -0
  379. package/tests/fixtures/php-maestro-routing/taxonomy.json +69 -0
  380. package/tests/validate-catalog.py +2 -0
@@ -0,0 +1,102 @@
1
+ # PHP version lifecycle
2
+
3
+ ## Why this matters
4
+
5
+ A PHP branch that has left php.net's supported window stops receiving fixes of
6
+ any kind once it reaches end of life (EOL) — including for actively exploited
7
+ vulnerabilities — while a branch in its security-only window still receives
8
+ critical security fixes but no bug fixes, and is itself counting down to its
9
+ own EOL. A service can look fully healthy at the application-code level (green
10
+ tests, current dependencies) while the runtime underneath it has already
11
+ crossed one of these boundaries. This file is the sole source the skill uses
12
+ for those dates; every version-lifecycle claim in a review must resolve to a
13
+ row below, and to no other memory or estimate.
14
+
15
+ ## NORMATIVE: php.net's support policy
16
+
17
+ Per php.net's Supported Versions page (`documentation-based`):
18
+
19
+ - Each release branch of PHP is fully supported for **two years** from its
20
+ initial stable release. During this period, reported bugs and security
21
+ issues are fixed and released in regular point releases.
22
+ - After that two-year active-support period, each branch is then supported
23
+ for **two additional years** for critical security issues only. Releases
24
+ during this window are made on an as-needed basis — there may be multiple
25
+ point releases, or none, depending on the number of reports.
26
+ - After the combined four-year window (two years active plus two years
27
+ security-only), a branch is **end of life (EOL)**: no further fixes of any
28
+ kind are published for it, including for actively exploited
29
+ vulnerabilities.
30
+
31
+ ## NORMATIVE: current per-branch dates
32
+
33
+ Per php.net's Supported Versions page, the currently listed branches and
34
+ their published dates are:
35
+
36
+ | Branch | Active support until | Security support until (EOL) |
37
+ |---|---|---|
38
+ | PHP 8.2 | 31 Dec 2024 | 31 Dec 2026 |
39
+ | PHP 8.3 | 31 Dec 2025 | 31 Dec 2027 |
40
+ | PHP 8.4 | 31 Dec 2026 | 31 Dec 2028 |
41
+ | PHP 8.5 | 31 Dec 2027 | 31 Dec 2029 |
42
+
43
+ Reading this table for a review:
44
+
45
+ - A branch is in **active support** if the current review's target/committed
46
+ version date is before its "Active support until" date.
47
+ - A branch is in **security-only support** if that date is on or after
48
+ "Active support until" but before "Security support until."
49
+ - A branch is **EOL** once that date reaches or passes "Security support
50
+ until" — no fixes of any kind are published past that point.
51
+
52
+ Any PHP version not listed in php.net's current supported-versions table
53
+ (either older than the branches php.net still lists, or a malformed/future
54
+ version string) has no dates in this file — say the evidence is missing
55
+ rather than inferring a status.
56
+
57
+ ## Reviewer evidence criteria
58
+
59
+ - Resolve the exact PHP version from the strongest available evidence:
60
+ a running-version banner or `phpversion()`/`php -v` output outranks a
61
+ Dockerfile/base-image tag, which outranks a loose Composer `require.php`
62
+ constraint (e.g. `^8.2` does not tell you which point release is actually
63
+ deployed, only the minimum branch). State which evidence tier the version
64
+ claim rests on.
65
+ - Match the resolved branch against the table above exactly; do not round a
66
+ point release to a different branch or assume a branch's status from a
67
+ prior review.
68
+ - Classify the branch precisely as active support, security-only (cite the
69
+ exact security-support-until date), or EOL (cite the exact date it was
70
+ reached) — never collapse these into an undifferentiated "outdated" label.
71
+ - Determine the branch's **current phase** by comparing this file's published
72
+ cutoff dates against the review date — the current date, or an explicitly
73
+ supplied review/support-horizon date when one is given. This file's
74
+ per-branch dates are the fixed ground truth (sourced from php.net, never
75
+ invented, rounded, or extrapolated); only the comparison against the review
76
+ date is a review-time judgment, so a branch correctly transitions from
77
+ active support to security-only to EOL as the review date passes each
78
+ published cutoff.
79
+ - For a security-only branch, compare its "Security support until" date
80
+ against both the review date and the review's stated release/support
81
+ horizon. If EOL has already been reached, or that date falls within the
82
+ horizon with no tracked upgrade plan, this is a blocking finding per the
83
+ skill's decision gates, not merely advisory.
84
+ - For an EOL branch, the finding is blocking unconditionally — there is no
85
+ "well-maintained otherwise" exception, since EOL means no fixes of any kind
86
+ are published, including for actively exploited vulnerabilities.
87
+
88
+ ## NORMATIVE vs. RECOMMENDATION
89
+
90
+ The support-policy structure and the per-branch dates above are NORMATIVE —
91
+ sourced directly from php.net and not to be altered, rounded, or
92
+ extrapolated. The recommended target version for an upgrade (e.g. "move to
93
+ the newest branch still in active support") is a RECOMMENDATION: name a
94
+ target that is currently in active support per the table above, but leave the
95
+ final choice, timeline, and any compatibility work to the owning engineering
96
+ team.
97
+
98
+ ## Sources
99
+
100
+ - [PHP: Supported Versions](https://www.php.net/supported-versions.php) — supports the two-year active-support / two-year security-only / EOL support-policy structure and the per-branch dates for PHP 8.2 through 8.5 above.
101
+
102
+ Last verified: 2026-07-16.
@@ -0,0 +1,111 @@
1
+ ---
2
+ name: php-session-upload-deserialization-review
3
+ description: Use this skill to statically review PHP code for object-injection risk from unserialize() on untrusted input, session fixation/hijacking from missing session_regenerate_id() or weak session cookie hardening, and unsafe file-upload handling that trusts the client or stores/executes uploads inside the webroot. Use when reviewing a PHP application for deserialization, authentication-session, or upload-handling security issues. Static review only; it never executes payloads, uploads, or requests against any system, and every unserialize()/session/upload claim is grounded in the current php.net manual rather than memory.
4
+ allowed-tools: Read Grep Glob
5
+ metadata:
6
+ author: "github: Raishin"
7
+ version: "0.1.0"
8
+ updated: "2026-07-16"
9
+ category: security
10
+ lifecycle: experimental
11
+ ---
12
+
13
+ # PHP Session, Upload, and Deserialization Review
14
+
15
+ ## Purpose
16
+
17
+ Review PHP source for the three failure modes where the language's own deserialization, session, and file-upload primitives are used in a way php.net's own manual explicitly warns against: `unserialize()` called on untrusted input (object injection, potentially remote code execution), a session that is not regenerated after a privilege change or that ships without cookie hardening (fixation/hijacking), and an upload handler that trusts the client or stores/executes accepted files inside the webroot.
18
+
19
+ ## When to use
20
+
21
+ Use this skill when the user asks to:
22
+
23
+ - review any code path that calls `unserialize()`, or a library/cache/session backend that transparently unserializes stored data, for object-injection risk;
24
+ - review whether a login, role-elevation, or password-reset path correctly regenerates the session id and whether session cookie hardening (`use_strict_mode`, `httponly`, `secure`, `samesite`) is configured;
25
+ - review a file-upload handler for client-trust, storage-location, or size/type/count-limit gaps.
26
+
27
+ ## When not to use
28
+
29
+ Do not use this skill for:
30
+
31
+ - designing or approving a backend authorization/permission model — this skill only checks whether a privilege change triggers session regeneration, not whether the privilege model itself is correct; hand that off to the owning backend/platform specialist.
32
+ - executing, crafting, or sending any deserialization payload, session-fixation request, or file upload against any live, sandbox, or staging system. This skill is static review only.
33
+ - issuing a compliance or audit attestation from an OWASP category mapping; the mapping is a classification aid, never a determination.
34
+
35
+ ## Preconditions
36
+
37
+ - The code paths that call `unserialize()`, plus the source of the data passed to each call (request body/query/cookie, cache backend, queue message, database column).
38
+ - The authentication/session-management code, specifically where `session_start()`, `session_regenerate_id()`, and `$_SESSION` writes occur relative to a login, role change, or password reset.
39
+ - The active `session.*` INI settings in scope (`session.use_strict_mode`, `session.cookie_httponly`, `session.cookie_secure`, `session.cookie_samesite`) from `php.ini`, `.htaccess`, or runtime `ini_set()` calls.
40
+ - The upload-handling code: how `$_FILES` is validated, where accepted files are stored, and the `upload_max_filesize`/`post_max_size`/`max_file_uploads` configuration in effect.
41
+ - The PHP version in scope (`session.cookie_samesite` requires PHP 7.3+; destructor-on-fatal-error behavior changed at PHP 5.3.10).
42
+
43
+ ## Lean operating rules
44
+
45
+ - Flag any `unserialize()` call on untrusted input regardless of `allowed_classes` — the manual's caution applies unconditionally, and `allowed_classes` narrows instantiable classes without making the call safe.
46
+ - Name the reachable magic-method surface (`__wakeup()`, `__unserialize()`, `__destruct()`) for any class an untrusted `unserialize()` call could instantiate; PHP invokes these automatically on the reconstructed object or during the shutdown sequence.
47
+ - Recommend `json_decode()`/`json_encode()` as the default remediation for untrusted data interchange unless serialized PHP objects are confirmed necessary.
48
+ - Require `session_regenerate_id(true)` before the authenticated flag is written to `$_SESSION` on every login/elevation/reset path; a regeneration call placed after that write is a finding, not a pass.
49
+ - Check `session.use_strict_mode`, `session.cookie_httponly`, `session.cookie_secure`, and `session.cookie_samesite` individually and explicitly; never infer hardening from defaults, since `use_strict_mode` is disabled by default.
50
+ - Require upload handlers to validate the file's actual content server-side (never the client-supplied `$_FILES[...]['type']` or filename alone), store accepted files outside any web-servable path, and enforce `upload_max_filesize`, `post_max_size`, and `max_file_uploads`.
51
+ - Never request, echo, store, or reproduce a secret, credential, session id, token, or PII found in reviewed code; redact-and-flag any such string.
52
+ - Label every claim `repo evidence` (seen in the reviewed code) or `documentation-based` (current php.net manual); never assert a documented API behavior from memory.
53
+
54
+ ## Context7 documentation protocol
55
+
56
+ This skill's `allowed-tools` is limited to `Read`, `Grep`, and `Glob` — it does not include a live documentation-lookup tool, so grounding is done against the bundled, php.net-sourced reference files rather than a runtime Context7 call. `unserialize()`, the `session.*` INI directives, and the upload-handling behaviors reviewed here are core-language documentation, not a third-party library whose API shifts release to release, so the bundled references (each fetched directly from php.net, with its own Sources section and verification date) are the grounding source of record. If a review surfaces a claim about PHP behavior not covered by the bundled references — a different function, a different INI directive, a different PHP version's behavior — do not assert it from memory; say the claim is unverified against a specific php.net page and escalate for direct verification rather than guessing.
57
+
58
+ ## Workflow
59
+
60
+ 1. Enumerate every `unserialize()` call site in scope and trace the data source of its argument; classify each as untrusted-input-reachable or not.
61
+ 2. For each untrusted-input-reachable `unserialize()` call, identify classes it could instantiate and check for `__wakeup()`, `__unserialize()`, and `__destruct()` magic methods that would fire automatically — see [Unserialize object injection](references/unserialize-object-injection.md).
62
+ 3. For each authentication/privilege-elevation path, confirm `session_regenerate_id(true)` is called before `$_SESSION` carries the authenticated flag, and check the four session-hardening directives — see [Session security](references/session-security.md).
63
+ 4. For each upload handler, confirm server-side content validation, non-webroot storage, and enforced size/type/count limits — see [File upload security](references/file-upload-security.md).
64
+ 5. Emit findings with evidence tiers, exploit/failure narratives, remediation, verification steps, and OWASP category mappings; hand off any authorization-model or infrastructure-scoped issue to the owning specialist.
65
+
66
+ ## Decision gates
67
+
68
+ - Block only on a demonstrated untrusted-input-reachable `unserialize()` call, a missing/misordered `session_regenerate_id()` call, a missing `session.use_strict_mode`, or an upload handler that trusts the client, stores inside the webroot, or lacks enforced limits.
69
+ - Every `unserialize()`, session-directive, or upload-limit claim cites the current php.net manual (`documentation-based`) or the reviewed code (`repo evidence`) — never memory.
70
+ - Every OWASP mapping names the specific edition and category cited and is labeled a classification aid, never a compliance determination.
71
+ - Every authorization-model-design or infrastructure-scoped finding is handed off, not adjudicated here.
72
+
73
+ ## Evidence classification
74
+
75
+ Label each finding `repo evidence` (seen directly in the reviewed code or configuration) or `documentation-based` (the current php.net manual). This skill does not use `context7-grounded` (no Context7 tool in scope) and does not use `inference` for a documented API behavior — an undocumented or unverifiable behavior claim must be flagged as unverified rather than guessed.
76
+
77
+ ## Security and privacy constraints
78
+
79
+ Static review only. Never request, transmit, store, or reproduce a secret, credential, session id, token, or PII found in reviewed code or configuration; treat any such string as a redact-and-flag finding. Never execute a deserialization payload, replay or forge a session id, upload a file, or send any request to a live, sandbox, or staging system. OWASP category mappings are classification aids, never compliance attestations.
80
+
81
+ ## Escalation conditions
82
+
83
+ Escalate to incident response on any evidence the failure is already live: an object-injection payload observed in logs, a reachable uploaded web shell, or an observed session id reused across a privilege boundary. Escalate backend authorization-model design and infrastructure-scoped findings (webroot layout, TLS termination) to their owning specialist rather than adjudicating them here.
84
+
85
+ ## References
86
+
87
+ Load these only when needed:
88
+
89
+ - [Unserialize object injection](references/unserialize-object-injection.md) — why `unserialize()` on untrusted input is unsafe regardless of `allowed_classes`, the magic-method attack surface, and the `json_decode()` remediation.
90
+ - [Session security](references/session-security.md) — `session_regenerate_id()` ordering around privilege changes and the four session cookie-hardening directives.
91
+ - [File upload security](references/file-upload-security.md) — client-trust, storage-location, and size/type/count-limit review criteria for upload handlers.
92
+
93
+ Each reference file carries its own Sources section citing the exact php.net (or OWASP) page backing its claims — there is no separate primary-source ledger file in this skill.
94
+
95
+ ## Response minimum
96
+
97
+ Return, at minimum:
98
+
99
+ - the call site/path in scope and, per finding, the failure class (`object-injection` / `session-fixation-hijacking` / `unsafe-upload`) and evidence tier;
100
+ - the exploit or failure narrative (how the reachable input reaches a wrong outcome);
101
+ - concrete remediation and an exact verification step;
102
+ - the OWASP category mapping, labeled as a classification aid;
103
+ - any authorization-model or infrastructure-scoped handoffs and incident-response escalation.
104
+
105
+ ## Anti-goals
106
+
107
+ - Do not treat `allowed_classes` as a mitigation for `unserialize()` on untrusted input; the manual's caution is unconditional.
108
+ - Do not design or approve a backend authorization/permission model; hand it off.
109
+ - Do not execute any payload, upload, or request against any live, sandbox, or staging system.
110
+ - Do not assert `unserialize()`, session-directive, or upload-limit behavior from memory; ground every such claim in the current php.net manual.
111
+ - Do not echo, store, or reproduce any secret, session id, token, or PII found during review.
@@ -0,0 +1,20 @@
1
+ {
2
+ "id": "php-session-upload-deserialization-review",
3
+ "name": "PHP Session, Upload & Deserialization Security Review",
4
+ "type": "skill",
5
+ "provider": "php",
6
+ "harnesses": ["claude-code", "cursor", "codex", "gemini", "kiro", "other"],
7
+ "summary": "Skill for reviewing PHP application-security seams: user-reachable unserialize() object injection (allowed_classes is insufficient), session fixation/hijacking hardening (session_regenerate_id, use_strict_mode, cookie flags), and unsafe file-upload handling, each mapped to an OWASP category and the php.net-documented fix.",
8
+ "source_type": "original",
9
+ "official_docs": [
10
+ "https://www.php.net/manual/en/function.unserialize.php",
11
+ "https://www.php.net/manual/en/session.security.php",
12
+ "https://www.php.net/manual/en/features.file-upload.common-pitfalls.php",
13
+ "https://owasp.org/www-project-top-ten/"
14
+ ],
15
+ "security_notes": "Static-review-only skill: Read/Grep/Glob, no execution and no network. Never runs deserialization payloads, uploads, or exploits against any live or staging system. Any credential- or PII-shaped string is a redact-and-flag finding, never echoed. Every unserialize()/session/upload claim is grounded in current php.net documentation, not memory.",
16
+ "last_verified": "2026-07-16",
17
+ "path": "skills/php/php-session-upload-deserialization-review",
18
+ "author": "github: Raishin",
19
+ "version": "0.1.0"
20
+ }
@@ -0,0 +1,119 @@
1
+ # File upload security
2
+
3
+ ## Why this matters
4
+
5
+ An upload handler is the one place in most PHP applications where a client
6
+ supplies content the server will store, and often later serve, on its own
7
+ filesystem. Every trust decision the manual warns against — believing the
8
+ client's stated MIME type, believing the client's filename, skipping the
9
+ configured size/count ceilings, or placing accepted content somewhere the
10
+ web server will execute it — turns a routine upload feature into a path for
11
+ an attacker to plant and run a web shell, exhaust server resources, or read
12
+ files the application never meant to expose.
13
+
14
+ ## NORMATIVE: configuration ceilings gate every upload
15
+
16
+ Per the php.net manual's common-pitfalls guidance for file uploads:
17
+
18
+ - **`upload_max_filesize`** caps the size PHP will accept per file: "The
19
+ `MAX_FILE_SIZE` item cannot specify a file size greater than the file size
20
+ that has been set in the `upload_max_filesize` in the php.ini file. The
21
+ default is 2 megabytes." A form-field `MAX_FILE_SIZE` hint is a
22
+ client-side convenience only; the server-enforced ceiling is
23
+ `upload_max_filesize`.
24
+ - **`post_max_size`** must accommodate the request as a whole: "If
25
+ `post_max_size` is set too small, large files cannot be uploaded. Make
26
+ sure you set `post_max_size` large enough." A `post_max_size` smaller than
27
+ `upload_max_filesize` silently caps effective upload size below what
28
+ `upload_max_filesize` alone suggests.
29
+ - **`max_file_uploads`** bounds how many files one request can carry: "The
30
+ `max_file_uploads` configuration setting controls the maximum number of
31
+ files that can [be] uploaded in one request. If more files are uploaded
32
+ than the limit, then `$_FILES` will stop processing files once the limit
33
+ is reached" — silently, not with an error the handler is guaranteed to
34
+ check for.
35
+ - **`memory_limit`**, **`max_execution_time`**, and **`max_input_time`** must
36
+ also be sized for uploads: the manual specifically notes `max_input_time`
37
+ "sets the maximum time, in seconds, the script is allowed to receive
38
+ input; this includes file uploads. For large or multiple files, or users
39
+ on slower connections, the default of `60` seconds may be exceeded,"
40
+ causing an otherwise-valid upload to fail partway through.
41
+
42
+ A review must confirm these are set deliberately (not left at silent
43
+ defaults that either reject legitimate uploads or, in the case of
44
+ `max_file_uploads`, silently truncate a batch without the handler noticing).
45
+
46
+ ## NORMATIVE: do not trust which file you operate on
47
+
48
+ The manual's common-pitfalls page states plainly: "Not validating which file
49
+ you operate on may mean that users can access sensitive information in
50
+ other directories." This is the manual's own framing of path-traversal and
51
+ client-trust risk in upload handling — a filename or path is untrusted input
52
+ like any other and must be validated, not built into a filesystem operation
53
+ directly. The manual separately cautions that "due to the large amount of
54
+ directory listing styles we cannot guarantee that files with exotic names
55
+ (like containing spaces) are handled properly," reinforcing that the
56
+ client-supplied filename cannot be relied on to behave predictably and
57
+ should not be used to construct a storage path or to make a security
58
+ decision (such as inferring file type from its extension).
59
+
60
+ ## RECOMMENDATION: validate content, not client claims; store outside the webroot
61
+
62
+ The manual's guidance above establishes the principle — validate the file
63
+ you actually operate on — but does not itself specify a validation
64
+ algorithm or a storage location; the following are this skill's operating
65
+ recommendations applying that principle, to be checked as reviewer evidence
66
+ criteria below rather than cited as separate manual quotations:
67
+
68
+ - Treat `$_FILES[...]['type']` (client-reported MIME type) and
69
+ `$_FILES[...]['name']` (client-reported filename) as untrusted metadata
70
+ only. A security decision — what kind of file this is, whether it is
71
+ acceptable — must be made from the file's actual content on the server,
72
+ not from either client-supplied field.
73
+ - Store accepted uploads outside any path the web server will serve
74
+ directly, and generate the stored filename server-side rather than
75
+ reusing the client-supplied name verbatim, closing both the
76
+ path-traversal risk above and the risk of an executable extension being
77
+ preserved into a servable location.
78
+ - Never `include()`, `require()`, or otherwise execute an uploaded file as
79
+ PHP code, and never configure the storage directory to be
80
+ script-executable by the web server.
81
+
82
+ ## Reviewer evidence criteria
83
+
84
+ For each upload handler in scope:
85
+
86
+ - Confirm `upload_max_filesize`, `post_max_size` (sized larger than
87
+ `upload_max_filesize`), and `max_file_uploads` are set to deliberate,
88
+ documented values rather than left at framework/PHP defaults without
89
+ review, and confirm the handler does not assume a client-side
90
+ `MAX_FILE_SIZE` hint is enforced.
91
+ - Confirm the handler checks the actual number of files processed against
92
+ what the client claims to have sent, given that `$_FILES` silently stops
93
+ populating once `max_file_uploads` is reached.
94
+ - Confirm the handler validates the file's real type/content server-side,
95
+ not `$_FILES[...]['type']` or the client filename's extension alone.
96
+ - Confirm accepted files are stored outside any web-servable path, with a
97
+ server-generated filename, not the client-supplied one used verbatim in
98
+ a filesystem path.
99
+ - Confirm no code path `include()`s, `require()`s, or otherwise executes an
100
+ uploaded file, and that the storage location is not configured as
101
+ script-executable.
102
+ - Treat trusting client-supplied MIME type/filename for a security decision,
103
+ storing inside the webroot, or having no enforced size/type/count limit as
104
+ a blocking finding.
105
+
106
+ ## Applicable versions
107
+
108
+ The `upload_max_filesize` default (2 megabytes) and the `max_file_uploads`
109
+ silent-truncation behavior described above are current php.net manual
110
+ guidance as of this review; re-verify against the live manual page before
111
+ citing an exact default value, since PHP distribution defaults (and
112
+ distro-specific `php.ini` overrides) can differ from the documented
113
+ upstream default.
114
+
115
+ ## Sources
116
+
117
+ - [PHP Manual — Common Pitfalls (file uploads)](https://www.php.net/manual/en/features.file-upload.common-pitfalls.php) — supports the `upload_max_filesize` default and `MAX_FILE_SIZE` client-hint framing, the `post_max_size` sizing guidance, the `max_file_uploads` silent-stop behavior, the `max_input_time` upload-duration caution, and the "not validating which file you operate on" and "exotic names" client-trust cautions.
118
+
119
+ Last verified: 2026-07-16.
@@ -0,0 +1,126 @@
1
+ # Session security
2
+
3
+ ## Why this matters
4
+
5
+ A session id is a bearer credential: whoever presents it is treated as the
6
+ user it belongs to. Two distinct failures let an attacker end up holding a
7
+ victim's session id: fixation, where the attacker sets the session id before
8
+ the victim authenticates and it is never replaced, and hijacking, where the
9
+ attacker steals an already-authenticated session id after the fact (via
10
+ script injection, packet sniffing, or physical access). php.net's own
11
+ session-security guidance treats both as core, not edge-case, concerns, and
12
+ documents specific configuration and code-ordering requirements to close
13
+ each path.
14
+
15
+ ## NORMATIVE: regenerate the session id on privilege change
16
+
17
+ Per the php.net manual's session-management-basics guidance:
18
+
19
+ - "Session IDs **must** be regenerated when user privileges are elevated,
20
+ such as after authenticating. `session_regenerate_id()` must be called
21
+ prior to setting the authentication information to `$_SESSION`."
22
+ `session_regenerate_id()` saves the current session data automatically, so
23
+ the call itself does not lose session state — but it must come **before**
24
+ the authenticated flag is written, so that only the new session id carries
25
+ it.
26
+ - More generally: "Session ID regeneration reduces the risk of stolen
27
+ session IDs, thus `session_regenerate_id()` must be called periodically.
28
+ E.g. Regenerate the session ID every 15 minutes for security sensitive
29
+ content."
30
+ - `session_regenerate_id()` does **not** delete the outdated session's data
31
+ by default. The manual is explicit: "`session_regenerate_id()` does not
32
+ delete outdated sessions by default. Obsolete authenticated sessions may
33
+ be present for use. Developers must prevent outdated sessions to be
34
+ consumed by anyone." A regeneration call without also invalidating the
35
+ prior session's stored data leaves a still-valid, still-authenticated old
36
+ session id usable by anyone who captured it before regeneration.
37
+
38
+ ## NORMATIVE: `session.use_strict_mode` is mandatory and off by default
39
+
40
+ Per the manual: "enabling `session.use_strict_mode` is mandatory for secure
41
+ sessions. It is disabled by default. This prevents the session module [from
42
+ using] an uninitialized session ID. Put differently, the session module only
43
+ accepts valid session IDs generated by the session module. It rejects any
44
+ session ID supplied by users." With strict mode enabled, "an uninitialized
45
+ session ID is rejected and a new one is created. This prevents an attack that
46
+ forces users to use a known session ID" — the core session-fixation vector,
47
+ where an attacker "may paste links or send emails that contain the session
48
+ ID" and hope the victim's session simply adopts it.
49
+
50
+ Because this directive is **disabled by default**, a review must check for
51
+ an explicit `session.use_strict_mode=1` (or equivalent `ini_set()` call) —
52
+ absence of an error or warning is not evidence it is on.
53
+
54
+ ## NORMATIVE: cookie-hardening directives
55
+
56
+ Per the php.net manual's session INI-settings guidance, four directives
57
+ harden the session cookie itself:
58
+
59
+ - **`session.cookie_httponly`** — "Refuses access to the session cookie from
60
+ JavaScript. This setting prevents cookies snatched by a JavaScript
61
+ injection." The manual states: "Almost all applications must use the
62
+ httponly attribute for the session ID cookie."
63
+ - **`session.cookie_secure`** — "Allow access to the session ID cookie only
64
+ when the protocol is HTTPS. If a website is only accessible via HTTPS, it
65
+ should enable this setting." (The manual separately notes HSTS should be
66
+ considered for HTTPS-only sites.)
67
+ - **`session.cookie_samesite`** — "As of PHP 7.3 the `SameSite` attribute can
68
+ be set for the session ID cookie. This attribute is a way to mitigate CSRF
69
+ (Cross Site Request Forgery) attacks." `Lax` allows the cookie on a
70
+ cross-site GET navigation; `Strict` does not send it cross-site at all —
71
+ the manual frames the choice as that accessibility trade-off, not a
72
+ recommendation of one value for every application.
73
+ - Session hijacking generally (not fixation) is mitigated, per the manual,
74
+ by transport: "There are several ways to leak an existing session ID to
75
+ third parties. E.g. JavaScript injections, session IDs in URLs, packet
76
+ sniffing, physical access to the device, etc... The solution is to
77
+ implement SSL/TLS on the server and make it mandatory for users" —
78
+ `session.cookie_secure` is the configuration lever that enforces this for
79
+ the session cookie specifically.
80
+
81
+ ## Reviewer evidence criteria
82
+
83
+ For every authentication, privilege-elevation, or password-reset path:
84
+
85
+ - Confirm `session_regenerate_id(true)` is called, and confirm it is called
86
+ **before** the code writes the authenticated/elevated-privilege flag into
87
+ `$_SESSION`. A call present anywhere in the function is not sufficient —
88
+ check the ordering.
89
+ - Confirm the prior session's data is invalidated or is not relied upon as
90
+ still-authenticated after regeneration; a regeneration call with the old
91
+ session id left independently valid and authenticated is a finding.
92
+
93
+ For the effective session configuration in scope (`php.ini`, `.htaccess`,
94
+ `ini_set()` calls, or a framework's session configuration layer):
95
+
96
+ - Confirm `session.use_strict_mode` is explicitly enabled; do not treat its
97
+ absence from configuration as acceptable, since it is disabled by default.
98
+ - Confirm `session.cookie_httponly` is enabled.
99
+ - Confirm `session.cookie_secure` is enabled for any application served over
100
+ HTTPS (and flag its absence as a finding for an HTTPS-only application).
101
+ - Confirm `session.cookie_samesite` is set to `Lax` or `Strict` (requires
102
+ PHP 7.3+); flag an unset value, and flag PHP < 7.3 as unable to set this
103
+ directive at all (a version-upgrade finding, not a configuration finding).
104
+
105
+ Treat a missing `session_regenerate_id()` call (or one ordered after the
106
+ authenticated flag is set) and a missing/disabled `session.use_strict_mode`
107
+ as blocking findings. Treat missing `cookie_httponly`, `cookie_secure`, or
108
+ `cookie_samesite` as findings that escalate to blocking when combined with
109
+ any independently confirmed session-id-leak or fixation path.
110
+
111
+ ## Applicable versions
112
+
113
+ `session.cookie_samesite` requires PHP 7.3 or later — on an earlier version
114
+ this is a version-upgrade finding rather than a configuration omission. The
115
+ other directives and the `session_regenerate_id()` ordering guidance are
116
+ current php.net manual guidance as of this review; re-verify against the
117
+ live manual page before citing behavior for a PHP version outside current
118
+ support.
119
+
120
+ ## Sources
121
+
122
+ - [PHP Manual — Session Management Basics](https://www.php.net/manual/en/features.session.security.management.php) — supports the `session_regenerate_id()` ordering requirement around privilege elevation, the periodic-regeneration guidance, and the "does not delete outdated sessions by default" caution.
123
+ - [PHP Manual — Securing Session INI Settings](https://www.php.net/manual/en/session.security.ini.php) — supports `session.use_strict_mode` being mandatory-but-disabled-by-default, `session.cookie_httponly`, `session.cookie_secure`, and `session.cookie_samesite` (PHP 7.3+) directive behavior.
124
+ - [PHP Manual — Sessions and Security (overview)](https://www.php.net/manual/en/session.security.php) — top-level page framing session security as core to web application security and pointing to the two subsection pages above.
125
+
126
+ Last verified: 2026-07-16.
@@ -0,0 +1,121 @@
1
+ # Unserialize object injection
2
+
3
+ ## Why this matters
4
+
5
+ `unserialize()` does not just decode data — it can rebuild arbitrary objects
6
+ and then automatically hand them control. If the serialized string an
7
+ attacker controls names a class the application has autoloaded (directly or
8
+ transitively), reconstructing that object can invoke its magic methods with
9
+ attacker-influenced property values, and one of those methods reaching a
10
+ dangerous sink (a file write, a command, a second `unserialize()`, a query)
11
+ is enough to turn a data-parsing call into code execution. This is PHP
12
+ object injection, and php.net's own manual treats it as unconditional: there
13
+ is no safe way to call `unserialize()` on untrusted input, only safer
14
+ alternatives to use instead.
15
+
16
+ ## NORMATIVE: php.net's unconditional caution
17
+
18
+ Per the php.net manual page for `unserialize()`:
19
+
20
+ - "Do not pass untrusted user input to `unserialize()` regardless of the
21
+ `options` value of `allowed_classes`. Unserialization can result in code
22
+ being loaded and executed due to object instantiation and autoloading, and
23
+ a malicious user may be able to exploit this."
24
+ - The manual's stated alternative for untrusted data interchange is "a safe,
25
+ standard data interchange format such as JSON (via `json_decode()` and
26
+ `json_encode()`)."
27
+ - After successfully reconstructing an object, PHP "will automatically
28
+ attempt to call the `__unserialize()` or `__wakeup()` methods (if one
29
+ exists)" — this invocation happens as part of `unserialize()` itself, not
30
+ as a separate step a caller can skip.
31
+
32
+ This is the single controlling fact for this review: the caution is not
33
+ scoped to "when `allowed_classes` is absent" — it applies **regardless of**
34
+ that option's value. A review must not treat `allowed_classes` as the fix.
35
+
36
+ ## RECOMMENDATION: what `allowed_classes` actually does, and does not do
37
+
38
+ `allowed_classes` restricts which class names `unserialize()` is willing to
39
+ instantiate (e.g. `unserialize($string, ['allowed_classes' => false])`
40
+ instantiates no objects at all, converting them to `__PHP_Incomplete_Class`
41
+ instead). Use it as defense-in-depth when a design genuinely requires
42
+ `unserialize()` over data that cannot be fully untrusted-input-free, but do
43
+ not present it to engineers as a fix for untrusted-input reachability — the
44
+ manual's caution stands regardless of the option, and per user-contributed
45
+ notes on the same manual page, `allowed_classes` does not follow class
46
+ inheritance (allowing an interface does not allow its implementers, and
47
+ subclasses of an allowed class do not automatically pass).
48
+
49
+ ## The wider magic-method attack surface: `__destruct()` too
50
+
51
+ Object-injection ("PHP Object Injection" / gadget-chain) exploitation is not
52
+ limited to `__wakeup()`/`__unserialize()`. Any class instantiated by the
53
+ `unserialize()` call is a live PHP object with its full lifecycle ahead of
54
+ it, including destruction. Per the php.net manual for destructors: "The
55
+ destructor method will be called as soon as there are no other references to
56
+ a particular object, or in any order during the shutdown sequence." This
57
+ means a reconstructed object with attacker-controlled properties can trigger
58
+ consequential logic in its `__destruct()` even if it has no `__wakeup()` or
59
+ `__unserialize()` at all — including at request shutdown, when no other code
60
+ runs after it. Two destructor-execution details a reviewer should carry
61
+ into any gadget-chain analysis, per the same page:
62
+ `__destruct()` calls made during shutdown happen "in any order" (no
63
+ guaranteed sequence among unrelated objects), and destructors are called
64
+ even when the script stops via `exit()`. When reviewing a class reachable
65
+ from `unserialize()`, check `__wakeup()`, `__unserialize()`, and
66
+ `__destruct()` — all three are automatic, attacker-triggerable entry points
67
+ once the object exists.
68
+
69
+ ## RECOMMENDATION: prefer `json_decode()` for untrusted data
70
+
71
+ Match the manual's own stated remediation: for any data interchange that
72
+ crosses a trust boundary (request body, query string, cookie, cache key
73
+ sourced from user input, a queue message an external party can influence),
74
+ use `json_decode()`/`json_encode()` rather than `serialize()`/`unserialize()`.
75
+ If a legacy format genuinely requires PHP's native serialization for
76
+ internal, fully-trusted data only, confirm the value never round-trips
77
+ through anything a client can influence, and consider the manual's mention
78
+ of `hash_hmac()`-based integrity verification for data an application stores
79
+ externally and later reads back, so that tampering can be detected before
80
+ `unserialize()` (or `json_decode()`) is ever called on it.
81
+
82
+ ## Reviewer evidence criteria
83
+
84
+ For each `unserialize()` call site:
85
+
86
+ - Identify the exact source of the string passed in. Untrusted sources
87
+ include request parameters, headers, cookies, uploaded file contents,
88
+ values read back from a cache/session/queue backend that a client can
89
+ influence, and any database column a client-facing write path can reach.
90
+ - If the source is untrusted, this is a blocking finding regardless of
91
+ whether `allowed_classes` is set, per the manual's unconditional caution.
92
+ - If `allowed_classes` is present, do not close the finding on that basis;
93
+ note it as partial defense-in-depth only, and still require remediation
94
+ toward `json_decode()` or a fully-trusted data path.
95
+ - For any class the call could instantiate (open allowlist, `false`, or a
96
+ named list), check for `__wakeup()`, `__unserialize()`, and `__destruct()`
97
+ definitions in that class and its parents; if any exists, name it as a
98
+ live attack-surface entry point in the finding, not just a theoretical one.
99
+ - Confirm the recommended remediation is `json_decode()`/`json_encode()`
100
+ (or an equivalent non-object-instantiating format) unless the review
101
+ independently confirms native PHP serialization is required and the data
102
+ never crosses a trust boundary.
103
+
104
+ ## Applicable versions
105
+
106
+ The `unserialize()` caution, the automatic `__unserialize()`/`__wakeup()`
107
+ invocation, and the `allowed_classes` behavior described above are current
108
+ php.net manual guidance as of this review; the destructor shutdown-ordering
109
+ and `exit()` behavior is also current manual guidance, with the manual
110
+ separately noting that destructors are not run on shutdown caused by a fatal
111
+ error as of PHP 5.3.10. Re-verify against the live manual pages before citing
112
+ an exact figure for a PHP version outside current support, since documented
113
+ behavior can be refined between manual revisions.
114
+
115
+ ## Sources
116
+
117
+ - [PHP Manual — `unserialize()`](https://www.php.net/manual/en/function.unserialize.php) — supports the unconditional caution against passing untrusted input to `unserialize()` regardless of `allowed_classes`, the automatic `__unserialize()`/`__wakeup()` invocation on reconstructed objects, and the `json_decode()`/`json_encode()` remediation recommendation.
118
+ - [PHP Manual — Destructors](https://www.php.net/manual/en/language.oop5.decon.php) — supports the `__destruct()` invocation timing (on last reference removal or in any order during shutdown), invocation even after `exit()`, and the PHP 5.3.10 fatal-error exception to shutdown-time destructor execution.
119
+ - [OWASP Top 10:2021 — A08:2021 Software and Data Integrity Failures](https://owasp.org/Top10/2021/A08_2021-Software_and_Data_Integrity_Failures/index.html) — supports the OWASP category mapping for insecure-deserialization findings (CWE-502: Deserialization of Untrusted Data is listed among this category's notable weaknesses). OWASP has since published a Top 10:2025 edition (https://owasp.org/Top10/2025/) that renumbers this category to A08:2025 – Software or Data Integrity Failures and moves Injection to A05:2025; cite the specific edition and number in any finding rather than assuming 2021 numbering is still current.
120
+
121
+ Last verified: 2026-07-16.