Skip to content

v3.1.0 hardening: PSL wildcard/exception rules, scheme rejection, namespaced helpers - #11

Merged
adrorocker merged 2 commits into
3.xfrom
security/v3.1.0-hardening
Aug 14, 2026
Merged

v3.1.0 hardening: PSL wildcard/exception rules, scheme rejection, namespaced helpers#11
adrorocker merged 2 commits into
3.xfrom
security/v3.1.0-hardening

Conversation

@adrorocker

@adrorocker adrorocker commented Aug 14, 2026

Copy link
Copy Markdown
Member

Summary

Full-audit hardening pass for v3.1.0. All existing behavior for previously-valid inputs is preserved; existing tests untouched and green.

Security / correctness

  • PSL wildcard (*) and exception (!) rules are now fully supported. findTldInHierarchy only did exact-label lookups, ignoring 200+ wildcard rules and all 8 exception rules — consumers could derive a wrong registrable domain (hazard for cookie scoping / host allowlisting). foo.bar.ck now resolves suffix bar.ck; www.ck resolves ck (exception prevails). Private section gains ! support too.
  • Non-http schemes now throw InvalidArgumentException instead of mis-parsing (ftp://a.com used to yield host ftp).
  • UTF-8 PSL labels no longer corrupted: section splitting no longer uses \R in byte mode (which also matches 0x85, a byte inside labels like 嘉里大酒店).
  • Parser hardening: NUL-byte end-of-rule sentinel (no collision with list content), NUL rule lines discarded, spec-correct line filtering replaces the fragile unset($lines[0]).

Changed

  • Helper functions moved to DomainValidity\Support; old global names kept as deprecated function_exists-guarded shims (fatal redeclaration risk gone, removal planned for v4.0).
  • Factory now final (matches docs); bogus @throws removed; exception code 500 dropped.
  • composer: hardcoded version field removed; psl:update script added.
  • CI: runs on 3.x pushes, checkout@v4, Dependabot added, PHPCS lints tests/.
  • Dev dep: php_codesniffer 3.13.5 → 3.13.6 (CVE-2026-67434).

Tests

40 → 88. New coverage: PSL parser, helpers, wildcard/exception rules, Host serialization, edge inputs (ports, userinfo, IP literals, trailing dots, empty string).

composer check (phpcs + phpstan level 8 + pest) green on PHP 8.2.

…me rejection, namespaced helpers

Security / correctness:

- Validator: implement Public Suffix List wildcard (*) and exception
  (!) rule handling per the PSL algorithm (prevailing rule is the
  exception rule if any, otherwise the longest match; an exception
  rule's suffix is the rule minus its leftmost label). Applies to both
  ICANN and private sections; the private check is label-wise and
  exception-aware.
- HostParser: detect any RFC 3986 scheme with an anchored pattern and
  throw InvalidArgumentException for non-http/https schemes instead of
  mis-parsing (ftp://a.com used to yield the host 'ftp'). Dropped the
  misleading exception code 500.
- PublicSuffixListParser: split section content on explicit newlines
  (\R in byte mode also matches 0x85, corrupting multi-byte UTF-8
  labels such as 嘉里大酒店); spec-correct rule-line filtering instead
  of unset($lines[0]); NUL-byte end-of-rule sentinel that cannot
  collide with list content; rule lines containing NUL are discarded.

Changed:

- Helper functions moved to DomainValidity\Support; the old global
  names remain as deprecated function_exists-guarded shims
  (src/functions_global.php), removing the fatal redeclaration risk.
- Factory is now final (matches documented API); bogus @throws removed.
- composer.json: hardcoded version field removed; psl:update script
  added to refresh the test-only PSL snapshot.
- CI: runs on pushes to 3.x, actions/checkout@v4, Dependabot for
  Composer and GitHub Actions; PHPCS now lints tests/.
- Dev deps: squizlabs/php_codesniffer 3.13.5 -> 3.13.6
  (CVE-2026-67434).

Tests: 40 -> 88; new coverage for the PSL parser, helper functions,
wildcard/exception rules, Host serialization, and edge-case inputs
(ports, userinfo, IP literals, trailing dots, empty input).

Docs: USAGE.md (wildcard/exception behavior, scheme policy, IDN
limitations), CHANGELOG.md 3.1.0 entry, SECURITY.md advisory note.
@adrorocker
adrorocker force-pushed the security/v3.1.0-hardening branch from 0f4697b to df310d1 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, so
dependencies were resolved against the wrong PHP version. Run composer
directly on the runner instead, where the matrix PHP is active.
@adrorocker
adrorocker merged commit f23aede into 3.x Aug 14, 2026
3 checks passed
@adrorocker
adrorocker deleted the security/v3.1.0-hardening branch August 14, 2026 17: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