URL hash

Ringkasan

Daftar Web Risk terdiri dari hash SHA256 dengan panjang variabel. Untuk mengetahui detail selengkapnya, lihat Membuat Daftar Isi. Untuk memeriksa URL terhadap daftar Web Risk, baik secara lokal maupun di server, klien harus terlebih dahulu menghitung awalan hash URL tersebut.

Untuk menghitung awalan hash URL, ikuti langkah-langkah berikut:

  1. Melakukan kanonikalisasi URL seperti yang dijelaskan dalam Kanonikalisasi.
  2. Buat ekspresi akhiran/awalan untuk URL seperti yang dijelaskan di bagian Ekspresi Akhiran/Awalan.
  3. Hitung hash lengkap untuk setiap ekspresi akhiran/awalan seperti yang dijelaskan dalam Komputasi hash.
  4. Hitung awalan hash untuk setiap hash lengkap, seperti yang dijelaskan dalam Komputasi awalan hash.

Perhatikan bahwa langkah-langkah ini mencerminkan proses yang digunakan server Web Risk untuk mengelola daftar Web Risk.

Kanonikalisasi

Untuk memulai, kami asumsikan bahwa klien telah menguraikan URL dan menjadikannya valid sesuai dengan RFC 2396. Jika URL menggunakan nama domain internasional (IDN), klien harus mengonversi URL ke representasi Punycode ASCII. URL harus menyertakan komponen jalur; yaitu, URL harus memiliki garis miring di awal (http://google.com/).

Pertama, hapus karakter tab (0x09), CR (0x0d), dan LF (0x0a) dari URL. Jangan hapus urutan escape untuk karakter ini, seperti %0a.

Kedua, jika URL berakhir dengan fragmen, hapus fragmen tersebut. Misalnya, persingkat http://google.com/#frag menjadi http://google.com/.

Ketiga, hapus berulang kali karakter persentase dari URL hingga tidak ada lagi karakter persentase yang di-escape.

Untuk melakukan kanonikalisasi nama host

Ekstrak nama host dari URL, lalu:

  1. Hapus semua titik di depan dan di belakang.
  2. Ganti titik yang berurutan dengan satu titik.
  3. Jika nama host dapat diuraikan sebagai alamat IP, normalkan menjadi 4 nilai desimal yang dipisahkan titik. Klien harus menangani encoding alamat IP resmi, termasuk oktal, hex, dan kurang dari empat komponen.
  4. Gunakan huruf kecil untuk seluruh string.

Untuk melakukan kanonikalisasi jalur

  1. Selesaikan urutan /../ dan /./ di jalur dengan mengganti /./ dengan /, dan menghapus /../ beserta komponen jalur sebelumnya.
  2. Mengganti garis miring berturut-turut dengan satu karakter garis miring.

Jangan terapkan kanonikalisasi jalur ini ke parameter kueri.

Pada URL, gunakan persen-escape semua karakter yang merupakan <= ASCII 32, >= 127, #, atau %. Escape harus menggunakan karakter heksa huruf besar.

Berikut ini pengujian untuk membantu memvalidasi penerapan kanonikalisasi.

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";

Ekspresi akhiran/awalan

Setelah URL dikanonikalisasi, langkah berikutnya adalah membuat ekspresi akhiran/awalan. Setiap ekspresi akhiran/awalan terdiri dari akhiran host (atau host lengkap) dan awalan jalur (atau jalur lengkap) seperti yang ditunjukkan dalam contoh ini.

Ekspresi Akhiran/Awalan Ekspresi Reguler Setara
a.b/mypath/ http\:\/\/.*\.a\.b\/mypath\/.*
c.d/full/path.html?myparam=a http\:\/\/.*.c\.d\/full\/path\.html?myparam=a

Klien akan membentuk hingga 30 kombinasi akhiran host dan awalan jalur yang berbeda. Kombinasi ini hanya menggunakan komponen host dan jalur URL. Skema, nama pengguna, sandi, dan port akan dihapus. Jika URL menyertakan parameter kueri, setidaknya satu kombinasi akan menyertakan jalur lengkap dan parameter kueri.

Untuk host, klien akan mencoba maksimal lima string berbeda. API tersebut adalah:

  • Nama host yang tepat di URL.
  • Maksimal empat nama host yang dibuat dengan memulai dari lima komponen terakhir dan menghapus komponen utamanya secara berurutan. Domain level teratas dapat dilewati. Nama host tambahan ini tidak boleh diperiksa jika host-nya adalah alamat IP.

Untuk jalur, klien akan mencoba maksimal enam string berbeda. API tersebut adalah:

  • Jalur URL yang tepat, termasuk parameter kueri.
  • Jalur URL persis, tanpa parameter kueri.
  • Empat jalur yang dibentuk dengan memulai dari root (/) dan menambahkan komponen jalur secara berurutan, termasuk garis miring.

Contoh berikut menggambarkan perilaku pemeriksaan:

Untuk URL http://a.b.c/1/2.html?param=1, klien akan mencoba string yang mungkin berikut ini:

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/

Untuk URL http://a.b.c.d.e.f.g/1.html, klien akan mencoba string yang mungkin berikut ini:

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/

Untuk URL http://1.2.3.4/1/, klien akan mencoba string yang mungkin berikut ini:

1.2.3.4/1/
1.2.3.4/

Komputasi {i>hash<i}

Setelah kumpulan ekspresi akhiran/awalan dibuat, langkah berikutnya adalah menghitung hash SHA256 panjang penuh untuk setiap ekspresi. Di bawah ini adalah pengujian unit dalam pseudo-C yang dapat Anda gunakan untuk memvalidasi komputasi hash.

Contoh dari 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]);

Komputasi awalan hash

Terakhir, klien harus menghitung awalan hash untuk setiap hash SHA256 lengkap. Untuk Web Risk, awalan hash terdiri dari hash SHA256 berukuran 4-32 byte yang paling signifikan.

Contoh dari FIPS-180-2:

  • Contoh B1 dari FIPS-180-2
    • Inputnya adalah "abc".
    • Ringkasan SHA256 adalah ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad.
    • Awalan hash 32-bit adalah ba7816bf.
  • Contoh B2 dari FIPS-180-2
    • Inputnya adalah abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq.
    • Ringkasan SHA256 adalah 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1.
    • Awalan hash 48-bit adalah 248d6a61 d206.