URLs hashen

Überblick

Die Web Risk-Listen bestehen aus SHA 256-Hashes mit variabler Länge. Weitere Informationen finden Sie unter Inhalte auflisten. Um eine URL lokal oder auf dem Server mit einer Web-Risk-Liste zu vergleichen, müssen Clients zuerst das Hash-Präfix dieser URL berechnen.

So berechnen Sie das Hash-Präfix einer URL:

  1. Kanonisieren Sie die URL wie unter Kanonisierung beschrieben.
  2. Erstellen Sie die Suffix-/Präfixausdrücke für die URL, wie unter Suffix-/Präfixausdrücke beschrieben.
  3. Berechnen Sie den vollständigen Hash für jeden Suffix-/Präfixausdruck, wie unter Hash-Berechnungen beschrieben.
  4. Berechnen Sie das Hash-Präfix für jeden Hash in voller Länge, wie unter Hash-Präfixberechnungen beschrieben.

Beachten Sie, dass diese Schritte den Prozess widerspiegeln, den der Web Risk-Server zum Verwalten der Web Risk-Listen verwendet.

Kanonisierung

Zu Anfang wird davon ausgegangen, dass der Client die URL geparst und gemäß RFC 2396 gültig gemacht hat. Wenn die URL einen internationalisierten Domainnamen (IDN) verwendet, sollte der Client die URL in die ASCII-Point-Code-Darstellung konvertieren. Die URL muss eine Pfadkomponente enthalten. Das heißt, sie muss einen Schrägstrich (http://google.com/) haben.

Entfernen Sie zuerst die Zeichen (0x09), CR (0x0d) und LF (0x0a) aus der URL. Entfernen Sie für diese Zeichen keine Escape-Sequenzen wie %0a.

Zweitens: Wenn die URL in einem Fragment endet, entfernen Sie das Fragment. Kürzen Sie beispielsweise http://google.com/#frag auf http://google.com/.

Drittens: Entfernen Sie Prozent-Escape-Zeichen solange aus der URL, bis keine Prozent-Escape-Zeichen mehr vorhanden sind.

So kanonisieren Sie den Hostnamen

Extrahieren Sie den Hostnamen aus der URL und führen Sie dann folgende Schritte aus:

  1. Entfernen Sie alle vor- und nachgestellten Punkte.
  2. Ersetzen Sie aufeinanderfolgende Punkte durch einen einzelnen Punkt.
  3. Wenn der Hostname als IP-Adresse geparst werden kann, normalisieren Sie ihn auf vier durch Kommas getrennte Dezimalwerte. Der Client sollte mit jeder zulässigen IP-Adresskodierung umgehen, einschließlich oktal, hex und weniger als vier Komponenten.
  4. Verwenden Sie Kleinbuchstaben für den gesamten String.

So kanonisieren Sie den Pfad

  1. Lösen Sie die Sequenzen /../ und /./ im Pfad auf, indem Sie /./ durch / ersetzen und /../ zusammen mit der vorherigen Pfadkomponente entfernen.
  2. Ersetzen Sie aufeinanderfolgende Schrägstriche durch einen Schrägstrich.

Wenden Sie diese Pfadkanonisierung nicht auf die Suchparameter an.

Setzen Sie in der URL alle Zeichen mit dem Escape-Zeichen in Prozent um, die so aussehen: <= ASCII 32, >= 127, # oder %. Die Escape-Zeichen müssen aus Großbuchstaben bestehen.

Im Folgenden finden Sie Tests zur Validierung einer Kanonisierungsimplementierung.

Canonicalize("http://host/%25%32%35") = "http://host/%25";
Canonicalize("http://host/%25%32%35%25%32%35") = "http://host/%25%25";
Canonicalize("http://host/%2525252525252525") = "http://host/%25";
Canonicalize("http://host/asdf%25%32%35asd") = "http://host/asdf%25asd";
Canonicalize("http://host/%%%25%32%35asd%%") = "http://host/%25%25%25asd%25%25";
Canonicalize("http://www.google.com/") = "http://www.google.com/";
Canonicalize("http://%31%36%38%2e%31%38%38%2e%39%39%2e%32%36/%2E%73%65%63%75%72%65/%77%77%77%2E%65%62%61%79%2E%63%6F%6D/") = "http://168.188.99.26/.secure/www.ebay.com/";
Canonicalize("http://195.127.0.11/uploads/%20%20%20%20/.verify/.eBaysecure=updateuserdataxplimnbqmn-xplmvalidateinfoswqpcmlx=hgplmcx/") = "http://195.127.0.11/uploads/%20%20%20%20/.verify/.eBaysecure=updateuserdataxplimnbqmn-xplmvalidateinfoswqpcmlx=hgplmcx/";
Canonicalize("http://host%23.com/%257Ea%2521b%2540c%2523d%2524e%25f%255E00%252611%252A22%252833%252944_55%252B") = "http://host%23.com/~a!b@c%23d$e%25f^00&11*22(33)44_55+";
Canonicalize("http://3279880203/blah") = "http://195.127.0.11/blah";
Canonicalize("http://www.google.com/blah/..") = "http://www.google.com/";
Canonicalize("www.google.com/") = "http://www.google.com/";
Canonicalize("www.google.com") = "http://www.google.com/";
Canonicalize("http://www.evil.com/blah#frag") = "http://www.evil.com/blah";
Canonicalize("http://www.GOOgle.com/") = "http://www.google.com/";
Canonicalize("http://www.google.com.../") = "http://www.google.com/";
Canonicalize("http://www.google.com/foo\tbar\rbaz\n2") ="http://www.google.com/foobarbaz2";
Canonicalize("http://www.google.com/q?") = "http://www.google.com/q?";
Canonicalize("http://www.google.com/q?r?") = "http://www.google.com/q?r?";
Canonicalize("http://www.google.com/q?r?s") = "http://www.google.com/q?r?s";
Canonicalize("http://evil.com/foo#bar#baz") = "http://evil.com/foo";
Canonicalize("http://evil.com/foo;") = "http://evil.com/foo;";
Canonicalize("http://evil.com/foo?bar;") = "http://evil.com/foo?bar;";
Canonicalize("http://\x01\x80.com/") = "http://%01%80.com/";
Canonicalize("http://notrailingslash.com") = "http://notrailingslash.com/";
Canonicalize("http://www.gotaport.com:1234/") = "http://www.gotaport.com/";
Canonicalize("  http://www.google.com/  ") = "http://www.google.com/";
Canonicalize("http:// leadingspace.com/") = "http://%20leadingspace.com/";
Canonicalize("http://%20leadingspace.com/") = "http://%20leadingspace.com/";
Canonicalize("%20leadingspace.com/") = "http://%20leadingspace.com/";
Canonicalize("https://www.securesite.com/") = "https://www.securesite.com/";
Canonicalize("http://host.com/ab%23cd") = "http://host.com/ab%23cd";
Canonicalize("http://host.com//twoslashes?more//slashes") = "http://host.com/twoslashes?more//slashes";

Suffix-/Präfixausdrücke

Nachdem die URL kanonisiert wurde, müssen Sie als Nächstes die Suffix-/Präfixausdrücke erstellen. Jeder Suffix-/Präfixausdruck besteht aus einem Hostsuffix (oder vollständigem Host) und einem Pfadpräfix (oder vollständigem Pfad), wie in diesen Beispielen gezeigt.

Suffix/Präfixausdruck Entsprechender regulärer Ausdruck
a.b/mypath/ http\:\/\/.*\.a\.b\/mypath\/.*
c.d/full/path.html?myparam=a http\:\/\/.*.c\.d\/full\/path\.html?myparam=a

Der Client bildet bis zu 30 verschiedene Kombinationen aus Hostsuffix und Pfadpräfix. Diese Kombinationen verwenden nur die Host- und Pfadkomponenten der URL. Schema, Nutzername, Passwort und Port werden verworfen. Wenn die URL Suchparameter enthält, enthält mindestens eine Kombination den vollständigen Pfad und die Suchparameter.

Für den Host versucht der Client höchstens fünf verschiedene Strings. Sie sind:

  • Der genaue Hostname in der URL.
  • Bis zu vier Hostnamen, die mit den letzten fünf Komponenten beginnen und die führende Komponente nacheinander entfernen. Die Top-Level-Domain kann übersprungen werden. Diese zusätzlichen Hostnamen sollten nicht überprüft werden, wenn der Host eine IP-Adresse ist.

Für den Pfad versucht der Client höchstens sechs verschiedene Strings. Sie sind:

  • Der genaue Pfad der URL, einschließlich der Suchparameter.
  • Der genaue Pfad der URL ohne Abfrageparameter.
  • Die vier Pfade, die durch den Start am Stamm (/) und das aufeinanderfolgende Anhängen von Pfadkomponenten entstehen, einschließlich eines abschließenden Schrägstrichs.

Die folgenden Beispiele veranschaulichen das Überprüfungsverhalten:

Für die URL http://a.b.c/1/2.html?param=1 versucht der Client diese möglichen Strings:

a.b.c/1/2.html?param=1
a.b.c/1/2.html
a.b.c/
a.b.c/1/
b.c/1/2.html?param=1
b.c/1/2.html
b.c/
b.c/1/

Für die URL http://a.b.c.d.e.f.g/1.html versucht der Client diese möglichen Strings:

a.b.c.d.e.f.g/1.html
a.b.c.d.e.f.g/
(Note: skip b.c.d.e.f.g, since we'll take only the last five hostname components, and the full hostname)
c.d.e.f.g/1.html
c.d.e.f.g/
d.e.f.g/1.html
d.e.f.g/
e.f.g/1.html
e.f.g/
f.g/1.html
f.g/

Für die URL http://1.2.3.4/1/ versucht der Client diese möglichen Strings:

1.2.3.4/1/
1.2.3.4/

Hash-Berechnungen

Nachdem der Satz von Suffix-/Präfixausdrücken erstellt wurde, besteht der nächste Schritt darin, den SHA 256-Hash in voller Länge für jeden Ausdruck zu berechnen. Im Folgenden finden Sie einen Einheitentest in Pseudo-C, mit dem Sie Ihre Hash-Berechnungen prüfen können.

Beispiel FIPS-180-2:


// Example B1 from FIPS-180-2
string input1 = "abc";
string output1 = TruncatedSha256Prefix(input1, 32);
int expected1[] = { 0xba, 0x78, 0x16, 0xbf };
assert(output1.size() == 4);  // 4 bytes == 32 bits
for (int i = 0; i < output1.size(); i++) assert(output1[i] == expected1[i]);

// Example B2 from FIPS-180-2
string input2 = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
string output2 = TruncatedSha256Prefix(input2, 48);
int expected2[] = { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06 };
assert(output2.size() == 6);
for (int i = 0; i < output2.size(); i++) assert(output2[i] == expected2[i]);

// Example B3 from FIPS-180-2
string input3(1000000, 'a');  // 'a' repeated a million times
string output3 = TruncatedSha256Prefix(input3, 96);
int expected3[] = { 0xcd, 0xc7, 0x6e, 0x5c, 0x99, 0x14, 0xfb, 0x92,
                    0x81, 0xa1, 0xc7, 0xe2 };
assert(output3.size() == 12);
for (int i = 0; i < output3.size(); i++) assert(output3[i] == expected3[i]);

Hash-Präfixberechnungen

Schließlich muss der Client das Hash-Präfix für jeden SHA 256-Hash in voller Länge berechnen. Bei Web Risk besteht ein Hash-Präfix aus den wichtigsten 4–32 Byte eines SHA 256-Hash.

Beispiel FIPS-180-2:

  • Beispiel B1 des FIPS-180-2
    • Die Eingabe ist "abc".
    • SHA 256-Digest ist ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad.
    • Das 32-Bit-Hash-Präfix ist ba7816bf.
  • Beispiel B2 des FIPS-180-2
    • Dafür muss abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq eingegeben werden.
    • SHA 256-Digest ist 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1.
    • Das 48-Bit-Hash-Präfix ist 248d6a61 d206.