2013-01-14 10 views
7

voglio per convalidare l'url di dominio in php che possono essere in formato nome di dominio internazionalizzati come in greco nome di dominio = http: //παράδειγμα.δοκιμή È loro un modo per convalidarlo con regolare espressione?come convalidare i nomi di dominio internazionalizzati

+1

"Convalida" come in "verificare se è accettabile per DNS" (fallimenti sarebbe piuttosto raro) o come in "controlla se esiste effettivamente in DNS" (fallimenti sarebbero comuni, dato fattore casuale). – tripleee

+0

Che cosa è valido? È solo 'http: //' seguito da alcuni caratteri, poi un '. 'Seguito da alcuni caratteri? –

+0

Voglio solo verificare se il DNS è valido o meno. C'è qualche regex che può aiutarmi qui. L'URL potrebbe contenere caratteri di altre lingue come il tedesco. per esempio. Yahoo.com. Sto usando questa espressione regolare, ma non funzionerà solo per caratteri alfanumerici./^ [A-z \ d] [a-z \ d -] {0,62} $/i. Come posso formare regex che ha anche il carattere in altre lingue, – user1969981

risposta

2

Questi sono domini idn, vorrei prima convertirlo alla versione puny code e quindi ai domini validate.

Ma se ti piace davvero a convalidare un da regex

<?php 

$domain = 'παράδειγμα.gr'; 
$regex = '#^([\w-]+://?|www[\.])?([^\-\s\,\;\:\+\/\\\?\^\`\=\&\%\"\'\*\#\<\>]*)\.[a-z]{2,7}$#'; 
if (preg_match($regex, $domain)) { 
    echo "VALID"; 
} 

Ma questo si lascia che si esegue in falsi possitives, perché è davvero complessa per convalidare un dominio IDN Ho provato a verificare che nessun caratteri non validi sono all'interno, ma l'elenco NON è completo.

Meglio convertire bevore al codice punny

$regex = '#^([\w-]+://?|www[\.])?[a-z0-9]+[a-z0-9\-\.]*[a-z0-9]+\.[a-z]{2,7}$#'; 
if (preg_match($regex, idn_to_ascii($domain))) { 
    echo "VALID"; 
} 

E se ulteriore desidera verificare se il dominio potrebbe essere risolto prova:

$regex = '#^([\w-]+://?|www[\.])?[a-z0-9]+[a-z0-9\-\.]*[a-z0-9]+\.[a-z]{2,7}$#'; 
$punny_domain = idn_to_ascii($domain); 
if (preg_match($regex, $punny_domain)) { 
    if (gethostbyname($punny_domain) != $punny_domain) { 
     echo "VALID"; 
    } 
} 
1

Si tratta di un cosiddetto IDN domain. I client che supportano i domini IDN lo normalizzano utilizzando lo standard IDNA2008 come specificato in RFC 5890, quindi sostituiscono i caratteri Unicode rimanenti utilizzando la codifica Punycode come definito in RFC 3492 prima dell'invio per la risoluzione DNS.

Per specifica, letteralmente ogni carattere nel set di caratteri UTF-8 è valido per l'utilizzo in un dominio IDN, ma ogni autorità di dominio di primo livello può definire caratteri validi all'interno del set di caratteri Unicode, quindi sarà difficile da create and maintain a real regex.

Se si desidera accettare domini IDN nella propria applicazione, è necessario utilizzare internamente la versione codificata. PHP extension intl porta due funzioni per en- e decodificare i nomi di dominio IDN

echo idn_to_ascii('täst.de'); 

xn--tst-qla.de

dopo la codifica, il dominio, passerà qualsiasi traditional regex check

Semplice validazione:

$url = "http://example.com/"; 
if (preg_match('/^(http|https|ftp):\/\/([A-Z0-9][A-Z0-9_-]*(?:\.[A-Z0-9][A-Z0-9_-]*)+):?(\d+)?\/?/i', $url)) { 
    echo 'OK'; 
} else { 
    echo 'Invalid URL.'; 
} 

EDIT:

Se volete una vera DNS verfification è possibile utilizzare dns_get_record (PHP 5) o gethostbyaddr

esempio

$domain = 'ελληνικά.idn.icann.org'; 
$idnDomain = idn_to_ascii($domain); 

if ($dnsResult = dns_get_record($idnDomain, DNS_ANY)) 
{ 
    echo $idnDomain , "\n"; 
    print_r($dnsResult); 
} 
else 
{ 
    echo "failed to lookup domain\n"; 
} 

Risultato:

xn--hxargifdar.idn.icann.org 
Array 
(
    [0] => Array 
    (
     [host] => xn--hxargifdar.idn.icann.org 
     [class] => IN 
     [ttl] => 21456 
     [type] => A 
     [ip] => 199.7.85.10 
    ) 
    [1] => Array 
    (
     [host] => xn--hxargifdar.idn.icann.org 
     [class] => IN 
     [ttl] => 21600 
     [type] => AAAA 
     [ipv6] => 2620::2830:230:0:0:0:10 
    ) 
) 
+2

I * think * Ho trovato un errore * important * nella tua risposta. Tu dici: "Per specifica, letteralmente ogni carattere nel set di caratteri UTF-8 è valido per l'uso in un dominio IDN" (mentre parli di IDNA2008 e RFC5890). * TUTTAVIA * (a mio modo di vedere), IDNA2008 ora non ammette circa ottomila caratteri che erano validi, compresi tutti i caratteri maiuscoli, varianti a mezza/intera, simboli e segni di punteggiatura (in precedenza permessi in IDNA2003 e al momento ancora lavoro nella maggior parte delle implementazioni). Vedi http://www.unicode.org/faq/idn.html e http://tools.ietf.org/html/rfc5892. Oppure l'ho letto male? – GitaarLAB

+1

@Gitaar grazie, sì hai ragione. Questo è nuovo per me, ma ha assolutamente senso, perché i nomi dei domini non fanno distinzione tra maiuscole e minuscole e potrebbero essere riservati caratteri di punteggiatura (ad esempio delimitatore di dominio 'punto', delimitatore stringa di query' '', ecc. –

2

Se si desidera creare il proprio libirary, è necessario utilizzare la tabella di codepoints consentiti (IANA — Repository of IDN Practices, IDN Character Validation Guidance, IDNA Parameters) e la tabella di proprietà Unicode Script (UNIDATA/Scripts.txt).

Gmail adotta la specifica "H ighly Restricted" del Consorzio Unicode (Protecting Gmail in a global world). Sono consentite le seguenti combinazioni di script Unicode.

  • sceneggiatura singolo
  • Latina + Han + Hiragana + Katakana
  • Latina + Han + Bopomofo
  • Latina + Han + Hangul

Potrebbe essere necessario pagare attension di proprietà di script speciale valori (Comune, Ereditato, Sconosciuto) poiché alcuni caratteri hanno proprietà multiple o proprietà errate.

Ad esempio, U + 3099 (COMBINAZIONE KATAKANA-HIRAGANA VOICED SOUND MARK) ha due progetti ("Katakana" e "Hiragana") e la funzione PCRE lo classifica come "Inherited". Un altro esempio è U + x2A708. Althogh la proprietà di script corretta di U + 2A708 (comibination di U + 30C8 KATAKANA LETTER TO e U + 30E2 KATAKANA LETTER MO) è "Katakana", La specifica Unicode erroneamente classificarla come "Han".

Potrebbe essere necessario considerare IDN homograph attack. IDN policy di Google Chrome adotta the blacklist chars.

Il mio consiglio è di utilizzare Zend \ Validator \ Nomehost. Questa libreria utilizza the table of permitted code points per giapponese e cinese.

Se si utilizza Symfony, è consigliabile aggiornare l'app della versione alla 2.5 che adotta egulias/email-validatornd (Manual). È necessario ulteriore convalida se la stringa è una sequenza di byte ben formata. Vedere il mio report a> per i dettagli.

Non dimenticare l'iniezione XSS e SQL. Il seguente indirizzo è un indirizzo email valido basato su RFC5322.

// From Japanese tutorial 
// http://blog.tokumaru.org/2013/11/xsssqlrfc5322.html 
"><script>alert('or/**/1=1#')</script>"@example.jp 

penso che sia in dubbio per l'utilizzo idn_to_ascii per la convalida dal idn_to_ascii passa quasi tutti i caratteri.

for ($i = 0; $i < 0x110000; ++$i) { 
    $c = utf8_chr($i); 

    if ($c !== '' && false !== idn_to_ascii($c)) { 
     $number = strtoupper(dechex($i)); 
     $length = strlen($number); 

     if ($i < 0x10000) { 
      $number = str_repeat('0', 4 - $length).$number; 
     } 

     $idn = $c.'example.com'; 

     echo 'U+'.$number.' '; 
     echo ' '.$idn.' '. idn_to_ascii($idn); 
     echo PHP_EOL; 
    } 
} 

function utf8_chr($code_point) { 

    if ($code_point < 0 || 0x10FFFF < $code_point || (0xD800 <= $code_point && $code_point <= 0xDFFF)) { 
     return ''; 
    } 

    if ($code_point < 0x80) { 
     $hex[0] = $code_point; 
     $ret = chr($hex[0]); 
    } else if ($code_point < 0x800) { 
     $hex[0] = 0x1C0 | $code_point >> 6; 
     $hex[1] = 0x80 | $code_point & 0x3F; 
     $ret = chr($hex[0]).chr($hex[1]); 
    } else if ($code_point < 0x10000) { 
     $hex[0] = 0xE0 | $code_point >> 12; 
     $hex[1] = 0x80 | $code_point >> 6 & 0x3F; 
     $hex[2] = 0x80 | $code_point & 0x3F; 
     $ret = chr($hex[0]).chr($hex[1]).chr($hex[2]); 
    } else { 
     $hex[0] = 0xF0 | $code_point >> 18; 
     $hex[1] = 0x80 | $code_point >> 12 & 0x3F; 
     $hex[2] = 0x80 | $code_point >> 6 & 0x3F; 
     $hex[3] = 0x80 | $code_point & 0x3F; 
     $ret = chr($hex[0]).chr($hex[1]).chr($hex[2]).chr($hex[3]); 
    } 

    return $ret; 
} 

Se si desidera convalidare il dominio mediante le proprietà Script Unicode, utilizzare le funzioni PCRE.

Il seguente codice mostra come ottenere il nome della proprietà di script Unicode. Se si desidera che il per Unicode Script in JavaScript, utilizzare mathiasbynens/unicode-data.

function get_unicode_script_name($c) { 

    // http://php.net/manual/regexp.reference.unicode.php 
    $names = [ 
    'Arabic', 'Armenian', 'Avestan', 'Balinese', 'Bamum', 'Batak', 'Bengali', 
    'Bopomofo', 'Brahmi', 'Braille', 'Buginese', 'Buhid', 'Canadian_Aboriginal', 
    'Carian', 'Chakma', 'Cham', 'Cherokee', 'Common', 'Coptic', 'Cuneiform', 
    'Cypriot', 'Cyrillic', 'Deseret', 'Devanagari', 'Egyptian_Hieroglyphs', 
    'Ethiopic', 'Georgian', 'Glagolitic', 'Gothic', 'Greek', 'Gujarati', 
    'Gurmukhi', 'Han', 'Hangul', 'Hanunoo', 'Hebrew', 'Hiragana', 'Imperial_Aramaic', 
    'Inherited', 'Inscriptional_Pahlavi', 'Inscriptional_Parthian', 'Javanese', 
    'Kaithi', 'Kannada', 'Katakana', 'Kayah_Li', 'Kharoshthi', 'Khmer', 'Lao', 'Latin', 
    'Lepcha', 'Limbu', 'Linear_B', 'Lisu', 'Lycian', 'Lydian', 'Malayalam', 'Mandaic', 
    'Meetei_Mayek', 'Meroitic_Cursive', 'Meroitic_Hieroglyphs', 'Miao', 'Mongolian', 
    'Myanmar', 'New_Tai_Lue', 'Nko', 'Ogham', 'Old_Italic', 'Old_Persian', 
    'Old_South_Arabian', 'Old_Turkic', 'Ol_Chiki', 'Oriya', 'Osmanya', 'Phags_Pa', 
    'Phoenician', 'Rejang', 'Runic', 'Samaritan', 'Saurashtra', 'Sharada', 'Shavian', 
    'Sinhala', 'Sora_Sompeng', 'Sundanese', 'Syloti_Nagri', 'Syriac', 'Tagalog', 
    'Tagbanwa', 'Tai_Le', 'Tai_Tham', 'Tai_Viet', 'Takri', 'Tamil', 'Telugu', 'Thaana', 
    'Thai', 'Tibetan', 'Tifinagh', 'Ugaritic', 'Vai', 'Yi' 
    ]; 

    $ret = []; 

    foreach ($names as $name) { 

    $pattern = '/\p{'.$name.'}/u'; 

    if (preg_match($pattern, $c)) { 
     return $name; 
    } 
    } 

    return ''; 
} 
Problemi correlati