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).

Comments

jmcerda created an issue. See original summary.

jmcerda’s picture

Status: Active » Needs review
StatusFileSize
new3.25 KB

Implemented: 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 /private itself. Three regression tests use literal /private/etc, /private/tmp and /private paths — 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.

  • jmcerda committed 6f32ab9a on 1.x
    Issue #3613237: Reject macOS /private variants of dangerous roots
    
    On...
jmcerda’s picture

Status: Needs review » Fixed

Shipped in 1.1.0.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.