Skip to content

fix: validate embedded app paths with filepath.IsLocal - #2721

Merged
dunglas merged 1 commit into
mainfrom
fix/embed-islocal
Oct 21, 2026
Merged

dunglas merged 1 commit into
mainfrom
fix/embed-islocal

Conversation

@dunglas

@dunglas dunglas commented Oct 16, 2026

Copy link
Copy Markdown
Member

Replaces the nativeRelPath helper copied from x/build with filepath.IsLocal, which rejects absolute paths, .. traversal, volume names and, on Windows, reserved names. The behavior is the same for valid archives and the code is shorter.

CodeQL recognizes filepath.IsLocal as a path sanitizer, which resolves https://github.com/php/frankenphp/security/code-scanning/1. The archive is embedded at build time, so this alert was not exploitable in practice.

Found while setting up CodeQL in #2720.

dunglas added a commit that referenced this pull request Oct 21, 2026
…own (#2724)

`tests/shutdown_test.sh` (added in
#2645) failed on
#2721 with `FAIL: PHP request
failed with curl exit code 55`
([job](https://github.com/php/frankenphp/actions/runs/38898098911/job/116963348236)).
The failure lines up with the last server log line, `servers shutting
down; grace period initiated`, logged when Caddy closes its listeners
after `shutdown_delay`.

Closing a listening socket resets the connections still waiting in its
accept queue. Depending on when the reset reaches curl, the request
fails with 52 (empty reply), 56 (receive error) or 55 (send error). The
test already treated 52 and 56 as `closing`, but not 55, which needs the
reset to arrive between `connect()` and the first `send()`.

Stressing the shutdown in a Linux container (40 restarts, 24 concurrent
clients, ~36k requests against `main`) produced 29 × 52 and 30 × 56 at
listener close and no other errors, so 55 is the same race with a
narrower window. The server can't prevent it, so the test now accepts 55
too. The checks that matter are unchanged: requests served during
`shutdown_delay`, in-flight requests drained, PHP shut down last. The
patched script passed 10/10 runs in the same container.
dunglas added a commit that referenced this pull request Oct 21, 2026
CodeQL has not analyzed the repository since October 2024. Default setup
is disabled, and its last C/C++ run failed because autobuild can't find
the PHP headers.

This adds an advanced setup workflow that installs ZTS PHP through the
existing `setup-php` action, exports `php-config --includes` as
`CGO_CFLAGS`, and builds both the root module and `caddy/` so the
tracers see the C and Go compilations. It covers `actions`, `c-cpp` and
`go` on pull requests, pushes to `main`, and weekly.

Notes:

- The Go build cache is disabled for this job: a warm cache skips the
compiler invocations CodeQL traces.
- `caddy/` is built from its own `working-directory` because the Go
tracer doesn't recognize `go -C`.
- CodeQL's Go extractor records files that use cgo (`frankenphp.go`,
`worker.go`, …) under their generated copies in `GOCACHE`, so Go alerts
in those files are dropped. C sources and pure Go files (including the
whole Caddy module) are covered.
- GitHub default setup must stay disabled, otherwise the two
configurations conflict.

Running the default suites locally on top of this branch reports two
issues, fixed separately:

- #2721 (`go/zipslip`,
https://github.com/php/frankenphp/security/code-scanning/1)
- #2722
(`go/incorrect-integer-conversion`, 7 occurrences in `caddy/`)
@dunglas
dunglas marked this pull request as ready for review October 21, 2026 10:47
@dunglas
dunglas merged commit 2c623e8 into main Oct 21, 2026
25 checks passed
@dunglas
dunglas deleted the fix/embed-islocal branch October 21, 2026 10:51
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.

1 participant