Skip to content

[Bug]: Herd PHP binary hardcodes APP_ENV=local via getenv(), breaking PHPUnit CSRF bypass #1655

@dillingham

Description

@dillingham

Platform

macOS

Operating system version

macOS Sequoia 15.2 (24C101)

System architecture

ARM64 (M1, M2, etc)

Herd Version

1.26.0

PHP Version

8.5.1

Bug description

The bug: Herd's PHP binary hardcodes APP_ENV=local via putenv() at startup. This prevents PHPUnit's <env name="APP_ENV" value="testing"/> from working because the dotenv immutable repository reads getenv() first and finds local.

The fix for Herd: Don't set APP_ENV in the CLI binary at all (it's only useful for FPM/web context), or set it only when running under FPM, not CLI.

The workaround : Add <server name="APP_ENV" value="testing" force="true"/> to phpunit.xml, which overrides $_SERVER and gets picked up before the PutenvAdapter.

Steps to reproduce

 test('getenv APP_ENV should not be set by the PHP binary itself', function () {
      // Herd's PHP binary injects APP_ENV=local into getenv() before any code runs.
      // This prevents PHPUnit's <env> from taking effect because dotenv's
      // immutable repository reads getenv() first and locks in 'local'.
      expect(getenv('APP_ENV'))->toBe('testing');
  });                                       

Adding <server name="APP_ENV" value="testing" force="true"/> to phpunit.xml makes the test pass

  1. Create any Laravel project served by Herd
  2. Run php -r "echo getenv('APP_ENV');" — outputs local
  3. Run env -i HOME=$HOME PATH=$PATH php -r "echo getenv('APP_ENV') ?: 'not set';" — outputs not set (proving it's not in the shell environment)
  4. Run Herd's PHP with no ini files: "/Users/brian/Library/ApplicationSupport/Herd/bin/php" -n -r "echo getenv('APP_ENV') ?: 'not set';" — still outputs local
  5. Run php artisan test — all POST-based feature tests fail with 419 (CSRF token mismatch)

Relevant log output

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions