PHP may deserialize a PHAR archive when a file operation touches a phar:// path, even if the code only meant to check whether a file exists. If an attacker can place a crafted archive where the application later reads it, the file access becomes a deserialization trigger. That can activate a gadget chain and turn a normal validation step into code execution.
Why a file path can become an execution trigger in PHP
The risk comes from how PHP handles certain stream wrappers, especially phar://. A path that looks like ordinary file input can cause the runtime to inspect archive metadata, which means a simple existence check or file read may do more than the developer intended. If the application accepts attacker-influenced paths, the path itself can become an active input to code loading behaviour.
This matters because PHP applications often treat path validation as a low-risk gate before a later operation. In practice, the security boundary is the file operation, not the function name. When path handling is user-controlled, the application may be asked to resolve a resource that carries hidden parsing side effects. That is why path sanitisation, wrapper restrictions, and upload handling all intersect here.
For a useful mental model, treat the path as part of the attack surface rather than a passive string. The danger is not limited to obvious include or require statements. Any file operation that reaches the PHAR parser can become relevant if the attacker can influence the path and place or reference a crafted archive.
How a PHAR object turns a filesystem check into code execution
PHAR archives are especially dangerous because their metadata can be deserialized when PHP processes the archive. If that metadata contains an object chain built from classes available in the application, normal object loading rules may invoke magic methods and produce unintended behaviour. In an exploitation path, the attacker first gets a crafted archive into a location the application can later access, then waits for a filesystem call to trigger parsing.
That trigger can occur during operations that developers usually consider safe, such as file_exists(), is_file(), or related checks against a user-supplied path. The problem is not that every such call is inherently unsafe, but that the path scheme can shift the operation from a metadata check to a parser invocation. When the archive is under attacker control, the file system is no longer just reading bytes, it is interpreting structured content.
This is why gadget chains matter. The archive itself is only the delivery mechanism; the real execution path depends on available code paths in the application or its dependencies. If the application has a usable gadget chain, deserialization can move from object construction into file write, command execution, or other sensitive actions.
Why the safe fix is about trust boundaries, not just input filtering
Blocking obvious directory traversal patterns is necessary, but it does not fully address this class of issue. A path can be syntactically clean and still point at a wrapper or archive format with dangerous behaviour. The safer posture is to constrain which schemes are accepted, avoid passing untrusted paths into filesystem APIs, and separate user input from any location that could be interpreted as a protocol or archive reference.
Applications also need to consider where attacker-controlled files can land. Upload directories, temporary storage, cached assets, and integration drop zones become more sensitive when later code touches those paths. If the application ever reads back a file whose origin is not trusted, it should be treated as potentially active content rather than inert storage.
In practice, this is a lifecycle problem as much as a validation problem. The risky moment is often not upload itself, but the later read, probe, or health check that dereferences the stored path. Good design removes ambiguity by storing trusted metadata separately from file content and by ensuring that file handlers never cross into parsing modes unexpectedly.
Risk and Threat Considerations
User-controlled path handling can turn a routine filesystem action into a parsing and deserialization event, which creates an attacker-controlled execution path. The exposure becomes most serious when the application accepts uploaded or otherwise reachable files and later reuses those locations in validation, preview, or housekeeping logic.
Failure mechanism: A crafted PHAR archive is placed where the application will later touch it, and a filesystem function resolves the phar:// wrapper, causing metadata deserialization and possible gadget-chain execution.
Impact: The attacker can convert a harmless-looking path check into remote code execution, often without needing an obvious include or eval sink, which widens the exploit surface across ordinary file operations.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
OWASP ASVS, CIS Controls v8 and NIST SP 800-53 Rev 5 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| OWASP ASVS | V15 — Secure Coding and Architecture | User-controlled paths and parser-sensitive file handling are secure design issues. |
| V5 — File Handling | The issue arises when file handling accepts attacker-influenced paths or archives. | |
| V16 — Security Logging and Error Handling | Suspicious wrapper usage and archive parsing errors should be detectable and reviewable. | |
| Recommendation — Keep untrusted paths out of parser-sensitive filesystem operations and use trusted server-side mapping. Validate file sources and treat uploaded content as untrusted until safely handled. Log unexpected file-scheme inputs and alert on archive parsing failures in sensitive paths. | ||
| CIS Controls v8 | CIS-16 — Application Software Security | The weakness is an application-level file handling flaw that can enable RCE. |
| Recommendation — Review file access paths for unsafe wrapper use and remove parser-triggering inputs. | ||
| NIST SP 800-53 Rev 5 | SI-10 — Information Input Validation | Untrusted path input must be validated before it reaches filesystem parsing logic. |
| Recommendation — Validate path inputs against an allowlist before any filesystem call. | ||
Practitioner Guidance
What to verify: Review every place user input can influence a filesystem path, including “existence check” logic, upload post-processing, and cache or temp-file lookups. The key question is whether the path can be interpreted by PHP as anything other than a literal filesystem location.
Decision rule: If the application must accept a path-like value, only allow a tightly defined allowlist of local paths or identifiers, and reject any scheme-like syntax outright. If you cannot make that guarantee, move the file access behind a trusted server-side mapping layer.
What good looks like: File handling code reads only trusted locations, uploaded content is never reinterpreted as executable archive metadata, and dangerous wrapper behaviour is disabled or avoided by design rather than by convention.
Practitioner takeaway: The exploit is not “file upload plus bad validation” in the abstract, it is uncontrolled interpretation of a path by the runtime, so the safest control is to keep untrusted input out of parser-sensitive file operations altogether.
Related resources from NHI Mgmt Group
- Why does user-controlled data in a Spring view name create a remote code execution risk?
- Why does remote code execution create such high operational risk for servers and applications?
- Why does arbitrary file writing through a custom map create remote code execution risk on Windows?
- Why does a file download endpoint create path traversal risk when it accepts user-controlled input?
Deepen Your Knowledge
Reviewed and updated by the NHIMG editorial team on September 26, 2026.
NHI Mgmt Group — the #1 independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org