@ipfy/homoglyph 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/NOTICE +45 -0
- package/README.md +143 -0
- package/dist/homoglyph.js +867 -0
- package/dist/homoglyph.min.js +1 -0
- package/dist/index.cjs +898 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.js +867 -0
- package/package.json +69 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 IPfy
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/NOTICE
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
This package includes derived Unicode Data Files.
|
|
2
|
+
|
|
3
|
+
UNICODE LICENSE V3
|
|
4
|
+
|
|
5
|
+
COPYRIGHT AND PERMISSION NOTICE
|
|
6
|
+
|
|
7
|
+
Copyright © 1991-2026 Unicode, Inc.
|
|
8
|
+
|
|
9
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
|
10
|
+
copy of data files and any associated documentation (the "Data Files") or
|
|
11
|
+
software and any associated documentation (the "Software") to deal in the
|
|
12
|
+
Data Files or Software without restriction, including without limitation
|
|
13
|
+
the rights to use, copy, modify, merge, publish, distribute, and/or sell
|
|
14
|
+
copies of the Data Files or Software, and to permit persons to whom the
|
|
15
|
+
Data Files or Software are furnished to do so, provided that either (a)
|
|
16
|
+
this copyright and permission notice appear with all copies of the Data
|
|
17
|
+
Files or Software, or (b) this copyright and permission notice appear in
|
|
18
|
+
associated Documentation.
|
|
19
|
+
|
|
20
|
+
THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
|
21
|
+
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
22
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
|
23
|
+
THIRD PARTY RIGHTS.
|
|
24
|
+
|
|
25
|
+
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE
|
|
26
|
+
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
27
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
28
|
+
WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE.
|
|
29
|
+
|
|
30
|
+
Except as contained in this notice, the name of a copyright holder shall
|
|
31
|
+
not be used in advertising or otherwise to promote the sale, use or other
|
|
32
|
+
dealings in these Data Files or Software without prior written
|
|
33
|
+
authorization of the copyright holder.
|
|
34
|
+
|
|
35
|
+
Unicode data used by Homoglyph:
|
|
36
|
+
|
|
37
|
+
- UTS #39 confusables.txt, Unicode 17.0.0
|
|
38
|
+
https://www.unicode.org/Public/security/17.0.0/confusables.txt
|
|
39
|
+
- UCD PropertyValueAliases.txt, Unicode 17.0.0
|
|
40
|
+
https://www.unicode.org/Public/17.0.0/ucd/PropertyValueAliases.txt
|
|
41
|
+
- UCD Scripts.txt, Unicode 17.0.0
|
|
42
|
+
- UCD ScriptExtensions.txt, Unicode 17.0.0
|
|
43
|
+
- UCD DerivedCoreProperties.txt, Unicode 17.0.0
|
|
44
|
+
|
|
45
|
+
Full Unicode terms: https://www.unicode.org/license.txt
|
package/README.md
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Homoglyph
|
|
2
|
+
|
|
3
|
+
Unicode-aware detection of visually confusable domain names.
|
|
4
|
+
|
|
5
|
+
Homoglyph is a multi-language, standards-based library for spotting **Unicode homoglyph / homograph** structure in **domain names**, using [Unicode UTS #39](https://www.unicode.org/reports/tr39/) **17.0.0**.
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
paypal.com
|
|
9
|
+
раypal.com
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Those strings are not the same domain. The second mixes Cyrillic letters that UTS #39 maps as confusable with Latin.
|
|
13
|
+
|
|
14
|
+
It is for developers who accept domains through email fields, URL fields, registration forms, and similar inputs.
|
|
15
|
+
|
|
16
|
+
## Implementations
|
|
17
|
+
|
|
18
|
+
One GitHub repository, [`ipfy/Homoglyph`](https://github.com/ipfy/Homoglyph), ships native packages:
|
|
19
|
+
|
|
20
|
+
| Language | Package | Install |
|
|
21
|
+
| --- | --- | --- |
|
|
22
|
+
| JavaScript | npm `@ipfy/homoglyph` | `npm install @ipfy/homoglyph` |
|
|
23
|
+
| Python | PyPI `ipfy-homoglyph` | `pip install ipfy-homoglyph` |
|
|
24
|
+
| PHP | Packagist `ipfy/homoglyph` | `composer require ipfy/homoglyph` |
|
|
25
|
+
|
|
26
|
+
All three implement the same Homoglyph specification (see `docs/DESIGN.md` and `docs/ARCHITECTURE.md`), the same Unicode 17.0.0 confusable data, and the shared corpus in `conformance/cases/`.
|
|
27
|
+
|
|
28
|
+
JavaScript additionally provides browser `warn()` / `reject()` helpers. Python and PHP provide the core `detect()` API only.
|
|
29
|
+
|
|
30
|
+
## What it is — and is not
|
|
31
|
+
|
|
32
|
+
The **security boundary is the domain**. Email local-parts and URL paths, queries, and fragments are not treated as hostname evidence.
|
|
33
|
+
|
|
34
|
+
| Observation | Meaning |
|
|
35
|
+
| --- | --- |
|
|
36
|
+
| Unicode in a domain | Not malicious. IDNs are legitimate. |
|
|
37
|
+
| Non-Latin | Not malicious. |
|
|
38
|
+
| Punycode / `xn--` | Not malicious. Valid A-labels are decoded, then analyzed. |
|
|
39
|
+
| Mixed script | Not automatically malicious. |
|
|
40
|
+
| `detected: true` | A UTS #39-relevant issue worth reporting |
|
|
41
|
+
| `rejectable: true` | High-confidence finding suitable for hard enforcement |
|
|
42
|
+
|
|
43
|
+
Homoglyph does **not** decide whether a domain is a phishing site. It is not a blacklist, reputation service, DNS client, or TLD policy engine.
|
|
44
|
+
|
|
45
|
+
## JavaScript (npm)
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npm install @ipfy/homoglyph
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
import Homoglyph from '@ipfy/homoglyph';
|
|
53
|
+
|
|
54
|
+
const result = Homoglyph.detect('раypal.com');
|
|
55
|
+
if (result.detected) {
|
|
56
|
+
console.log(result.reason, result.domain, result.rejectable);
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
CDN (IIFE, `globalThis.Homoglyph`):
|
|
61
|
+
|
|
62
|
+
```html
|
|
63
|
+
<script src="https://cdn.jsdelivr.net/npm/@ipfy/homoglyph/dist/homoglyph.min.js"></script>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Browser-only helpers: `Homoglyph.warn(input)` and `Homoglyph.reject(input)`. See below. There is no `init()`.
|
|
67
|
+
|
|
68
|
+
## Python (PyPI)
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
pip install ipfy-homoglyph
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
import homoglyph
|
|
76
|
+
|
|
77
|
+
result = homoglyph.detect("раypal.com")
|
|
78
|
+
if result.detected:
|
|
79
|
+
print(result.reason, result.domain, result.rejectable)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## PHP (Packagist)
|
|
83
|
+
|
|
84
|
+
Requires PHP 8.1+ and `ext-intl` (Unicode NFC/NFD via `Normalizer`).
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
composer require ipfy/homoglyph
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
```php
|
|
91
|
+
use IPfy\Homoglyph\Homoglyph;
|
|
92
|
+
|
|
93
|
+
$result = Homoglyph::detect('раypal.com');
|
|
94
|
+
if ($result->detected) {
|
|
95
|
+
echo $result->reason, ' ', $result->domain;
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Email and URL behavior
|
|
100
|
+
|
|
101
|
+
```text
|
|
102
|
+
user@раypal.com → analyze раypal.com
|
|
103
|
+
mаnοj@paypal.com → domain paypal.com; not rejectable
|
|
104
|
+
https://раypal.com/login → analyze раypal.com
|
|
105
|
+
https://example.com/раypal → path ignored
|
|
106
|
+
https://example.com/?q=раypal → query ignored
|
|
107
|
+
https://example.com/#раypal → fragment ignored
|
|
108
|
+
пример.com → labels analyzed independently (not mixed-script)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Punycode / IDNA
|
|
112
|
+
|
|
113
|
+
Valid `xn--` A-labels are **decoded** and then analyzed. Punycode itself is not evidence of malice. Successful Punycode decoding is **not** full IDNA validation.
|
|
114
|
+
|
|
115
|
+
## Unicode
|
|
116
|
+
|
|
117
|
+
| Item | Value |
|
|
118
|
+
| --- | --- |
|
|
119
|
+
| Unicode / UTS #39 | 17.0.0 |
|
|
120
|
+
| Source of truth | `unicode/` in this repository |
|
|
121
|
+
| Runtime download | none |
|
|
122
|
+
|
|
123
|
+
Refresh generated maps with `npm run generate` (writes JavaScript, Python, and PHP runtime data from the same files).
|
|
124
|
+
|
|
125
|
+
## JavaScript `warn()` / `reject()`
|
|
126
|
+
|
|
127
|
+
These exist only in the JavaScript browser build. They attach form metadata or constraint validation from `detect()`. Visitor-facing `reject()` messages are ordinary validation text, not “phishing” warnings.
|
|
128
|
+
|
|
129
|
+
## Development
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
npm install
|
|
133
|
+
npm run generate
|
|
134
|
+
npm test
|
|
135
|
+
npm run build
|
|
136
|
+
|
|
137
|
+
cd python && python -m build && pytest
|
|
138
|
+
cd php && composer install && vendor/bin/phpunit
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## License
|
|
142
|
+
|
|
143
|
+
MIT. Unicode data: Unicode License V3 (see `NOTICE`).
|