Skip to content

v2.0.4: backport v3.0.1/v3.1.0 security hardening to 2.x - #12

Merged
adrorocker merged 4 commits into
2.xfrom
security/2.x-backport
Aug 14, 2026
Merged

v2.0.4: backport v3.0.1/v3.1.0 security hardening to 2.x#12
adrorocker merged 4 commits into
2.xfrom
security/2.x-backport

Conversation

@adrorocker

@adrorocker adrorocker commented Aug 14, 2026

Copy link
Copy Markdown
Member

Summary

Backport of the v3.0.1 and v3.1.0 (#11) security fixes to the 2.x maintenance branch, ported to its flat-list structure — Validator's constructor signature and PublicSuffixListParser::parse() output are unchanged, so 2.x BC is intact.

Fixes

  • Host::tld(): dynamic-regex suffix removal (only . escaped → PCRE metacharacter injection, compile errors, small ReDoS surface) replaced with str_ends_with/substr.
  • HostParser: strpos substring scheme detection replaced with an anchored RFC 3986 pattern — URLs carrying http:// in path/query no longer mis-parse, and non-http/https schemes throw InvalidArgumentException instead of yielding a bogus host (ftp://a.com → host ftp).
  • PSL wildcard (*) and exception (!) rules now handled per the PSL algorithm (exception prevails, otherwise longest match).
  • checkIfIsPrivate() (2.x-only defect): strpos substring matching could mark unrelated hosts as private; replaced with label-wise suffix matching, wildcard- and exception-aware.

Tests

SecurityTest and WildcardExceptionTest ported from 3.x. 33 → 56 tests; pest, phpstan and phpcs all green.

SECURITY.md marks v2.0.0–v2.0.3 as insecure and points to v2.0.4.

Backports for v2.0.4:

- Host::tld(): replace dynamic-regex suffix removal (only '.' was
  escaped) with str_ends_with/substr string operations.
- HostParser: detect schemes with an anchored RFC 3986 pattern instead
  of strpos substring matching; URLs carrying http:// in path/query are
  no longer mis-classified, and non-http/https schemes now throw
  InvalidArgumentException instead of mis-parsing (ftp://a.com used to
  yield the host 'ftp').
- Validator: implement Public Suffix List wildcard (*) and exception
  (!) rule handling; the prevailing rule is the exception rule if any,
  otherwise the longest match.
- Validator::checkIfIsPrivate(): replace substring matching (which
  could mark unrelated hosts as private) with label-wise suffix
  matching, including wildcard and exception rules.
- Tests: port SecurityTest and WildcardExceptionTest regression
  coverage from 3.x.
- SECURITY.md: document affected versions.
@adrorocker
adrorocker force-pushed the security/2.x-backport branch from eedcedb to 1acadb9 Compare August 14, 2026 17:11
php-actions/composer@v6 runs composer inside its own container (PHP
8.5), ignoring the version selected by shivammathur/setup-php. The
Pest 2 dependency stack cannot resolve on PHP 8.5, so every matrix job
failed during install. Run composer directly on the runner instead,
where the matrix PHP is active. Also bumps actions/checkout to v4.
var-dumper ^7.0 requires PHP >=8.2, contradicting this branch's ^8.1.0
support. The old CI never caught it because the composer action
resolved dependencies with its container's newer PHP.
… resolution

Composer's advisory blocking refuses every phpunit <=10.5.61, while
every Pest 2.x release hard-caps phpunit inside that range via its
conflict rules — making the Pest 2 dev stack unresolvable on any PHP
version, and PHP 8.1 in particular. The advisory affects the test
runner only (dev dependency, never shipped); ignoring this single ID
lets the solver pick pest 2.36.0 + phpunit 10.5.36 + paratest 7.3.1 on
PHP 8.1 and newer sets elsewhere.
@adrorocker
adrorocker merged commit 3ed5ee5 into 2.x Aug 14, 2026
4 checks passed
@adrorocker
adrorocker deleted the security/2.x-backport branch August 14, 2026 17:52
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