Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,39 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [3.0.1] - 2026-05-01

### Security

- `Host::tld()` no longer builds a PCRE pattern from a publicly-settable
value. The previous implementation only escaped `.` characters, so any
other PCRE metacharacter in the supplied TLD (e.g. `* + ? | ^ $ ( )
[ ] { } \`) was inserted into a dynamic regex unescaped, allowing
unintended match behavior, PCRE compile errors, and a small ReDoS
surface. The suffix is now removed with `str_ends_with` + `substr` —
no regex, nothing to escape.
- `HostParser` now uses `str_starts_with` for scheme detection. The
previous `strpos(...) !== false` check matched the literals
`http://` / `https://` anywhere in the input, so URLs containing
those substrings in their path or query (e.g.
`evil.example.com/?u=http://x`) were mis-classified as
already-schemed and skipped the `http://` prefix needed by
`parse_url`.

### Deprecated

- **v3.0.0 is deprecated** due to the issues above. All consumers should
upgrade to **v3.0.1**. See `SECURITY.md` for the supported-versions
matrix.

### Docs

- New `docs/USAGE.md` — full usage guide, secure PSL fetch pattern,
caching strategy, complete API reference, worked examples, error
handling.
- README slimmed down to a landing page that links to the usage guide,
security policy, and changelog.

## [3.0.0] - 2026-01-31

### Breaking Changes
Expand Down
49 changes: 36 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,58 @@
<img src="./.art/domainvalidity.png" width="200">
</p>

# Doma(in)Validity PHP package.
# Doma(in)Validity PHP package

Light PHP package to validate domains.
Light PHP package to validate domains using the Mozilla
[Public Suffix List](https://publicsuffix.org/).

[Doma(in)Validity](https://api.domainvalidity.dev/) was born because I found myself searching online about how to check if a domain was valid. I always ended up using regular expressions that were too complex to account for several scenarios (mainly the TLD having different formats), it was just a pain in the butt because I always had to go back to that code to fix the regex to account for an edge case that I didn't think about.
[Doma(in)Validity](https://api.domainvalidity.dev/) was born because the
usual "validate a domain" regex grows new edge cases every time you
look away — multi-level TLDs (`co.uk`, `com.mx`), IDN labels, private
suffixes (`*.amazonaws.com`). This package outsources the hard part to
the PSL.

### Requirements
## Requirements

- PHP >= 8.2.0 (for v3.x)
- PHP >= 8.1.0 (for v2.x)
- PHP **>= 8.2.0** (for v3.x)
- PHP **>= 8.1.0** (for v2.x)

## Installation

You can install the package via composer:

```bash
composer require domainvalidity/php-domain-validator
```

## Usage
## Quick start

```php
use DomainValidity\Factory;

$contents = file_get_contents('https://publicsuffix.org/list/public_suffix_list.dat');

$validator = Factory::make($contents);
$psl = file_get_contents('path/to/public_suffix_list.dat');
$validator = Factory::make($psl);

$host = $validator->validate('www.domainvalidity.dev');

$host->isValid(); // true
$host->tld(); // 'dev'
$host->domain(); // 'domainvalidity.dev'
$host->toString(); // 'www.domainvalidity.dev'
```

> **Note:** You should cache the contents of the public suffix list and download them no more than once per day, as it is not updated more than a few times per week; more frequent downloading is pointless.
> Cache the Public Suffix List and refresh at most once per day. It is
> updated only a few times per week, so more frequent fetching is
> wasteful. See the usage guide below for a secure, cached fetch
> pattern.

## Documentation

- **[`docs/USAGE.md`](docs/USAGE.md)** — full usage guide, secure PSL
fetching, caching strategy, complete API reference, worked examples,
and error-handling model.
- **[`SECURITY.md`](SECURITY.md)** — supported versions and how to
report vulnerabilities.
- **[`CHANGELOG.md`](CHANGELOG.md)** — release history.

## License

MIT — see [`LICENSE`](LICENSE).
13 changes: 12 additions & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,21 @@

| Version | Supported |
| ------- | ------------------ |
| 3.x | :white_check_mark: |
| 3.0.1+ | :white_check_mark: |
| 3.0.0 | :x: (deprecated — see below) |
| 2.x | :white_check_mark: |
| 1.x | :x: |

## Known insecure versions

- **v3.0.0** — contained two defects in the host/TLD parsing path:
a regex-construction issue in `Host::tld()` that escaped only `.`
characters, and a substring-match scheme detection in `HostParser`
that mis-classified URLs containing `http://` later in their
path/query. Both are fixed in **v3.0.1**. We recommend upgrading
immediately. No exploit details are published; see `CHANGELOG.md`
for the high-level description.

## Reporting a Vulnerability

If you discover a security vulnerability within this package, please send an email to Alejandro Morelos at info@domainvalidity.dev. All security vulnerabilities will be promptly addressed.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "domainvalidity/php-domain-validator",
"version": "3.0.0",
"version": "3.0.1",
"description": "Light PHP package to validate domains.",
"type": "library",
"license": "MIT",
Expand Down
Loading
Loading