Pure string analysis, no network call. Level 1 has two sub-rules:
L1A Feature triggers (weak)
domain_length > 20
num_digits ≥ 2
num_hyphen ≥ 1
num_dots > 2
entropy_sld ≥ 4.0 (Shannon entropy of the SLD)
L1A fails if 2 or more features trigger.
L1B Brand similarity (strong)
SLD compared against a curated brand list (Malaysian banks, e-wallets, gov services, global tech & finance).
- Levenshtein edit distance ≤ 2 against any brand
- Leetspeak canonicalization (
0→o, 1→l, 3→e, 4→a…)
- Exact brand matches are excluded
A brand-similarity match is a strong signal. Verdict becomes Phishing.
Live lookup against the public RDAP service for the registrable domain. Two severity levels:
- Strong
rdap_missing_flag == 1 (no record or incomplete)
- Weak
rdap_domain_age_days < 365 (very young)
- Weak
rdap_domain_age_days < 365 and rdap_days_to_expiry < 180
A strong trigger alone produces a Phishing verdict.
A weak trigger alone produces Suspicious.
Trusted TLD
Level 2 is skipped for domains under trusted TLDs - government
(.gov.my, .gov, .go.id…), education
(.edu.my, .ac.uk, .edu…), military
(.mil, .mil.my…), and international organisations
(.int, .un.org…). These domains frequently return
no RDAP data by policy, not because they are suspicious.
Verdict for trusted TLDs is determined by Level 1 only.
- Phishing L1B brand match or L2 strong trigger
- Suspicious L1A feature-fail or L2 weak trigger
- Legitimate No triggers fire
Leading www. is stripped before any analysis.
Trusted TLD domains skip Level 2 - verdict based on Level 1 only.