Problem/Motivation
On macOS, /etc, /tmp and /var are symlinks into /private, so realpath('/etc') returns /private/etc. PathGuard::validate() compares the resolved path against its ALWAYS_REJECT list (/, /etc, /usr, /var, /tmp, /root, /home), and /private/etc matches nothing — the dangerous-root check silently passes on macOS hosts. --output-dir=/etc --allow-external is rejected on Linux but accepted on a Mac.
Steps to reproduce
On macOS, run the unit suite: PathGuardTest::testAllowExternalStillRejectsDangerousRoots fails (no exception thrown). On Linux it passes — which is why CI never caught it.
Proposed resolution
Strip a leading /private from the resolved path before comparing against ALWAYS_REJECT, and reject /private itself. Add cross-platform regression coverage using /private/etc and /private/tmp literals, which exercise the same code path on both platforms (on Linux they fall through realpath() to lexical normalisation).
| Comment | File | Size | Author |
|---|---|---|---|
| #2 | graphql_compose_codegen-pathguard-macos-3613237-2.patch | 3.25 KB | jmcerda |
Comments
Comment #2
jmcerdaImplemented: https://github.com/Wilkes-Liberty/graphql_compose_codegen/pull/20 (branch
3613237-pathguard-macos, targeting 1.x). Patch against 1.x attached.PathGuard::validate() now compares the
/private-stripped form of the resolved path against ALWAYS_REJECT as well, and rejects/privateitself. Three regression tests use literal/private/etc,/private/tmpand/privatepaths — on Linux these fall through realpath() to lexical normalisation and exercise the identical comparison, so CI covers the fix even though the misbehaviour was macOS-only.Unit suite green on macOS and Linux; phpcs and phpstan pass.
Comment #4
jmcerdaShipped in 1.1.0.