URL de hash

Descripción general

Las listas de Web Risk constan de hash SHA256 de longitud variable. Para obtener más detalles, consulta List Contents. Para comparar una URL con una lista de Web Risk, ya sea de forma local o en el servidor, los clientes primero deben calcular el prefijo hash de esa URL.

Para calcular el prefijo de hash de una URL, sigue estos pasos:

  1. Canonicaliza la URL como se describe en canonicalización.
  2. Crea las expresiones de sufijo o prefijo para la URL como se describe en Expresiones de sufijo o prefijo.
  3. Calcula el hash de longitud total para cada expresión de sufijo/prefijo como se describe en Procesamientos de hash.
  4. Calcula el prefijo hash para cada hash de longitud total, como se describe en Cálculos de prefijos hash.

Ten en cuenta que estos pasos reflejan el proceso que utiliza el servidor de Web Risk para mantener las listas de Web Risk.

canonicalización

Para empezar, suponemos que el cliente analizó la URL y la hizo válida según el RFC 2396. Si la URL usa un nombre de dominio internacionalizado (IDN), el cliente debe convertirla a la representación ASCII de Punycode. La URL debe incluir un componente de ruta de acceso, es decir, debe tener una barra diagonal inicial (http://google.com/).

Primero, quita los caracteres de tabulación (0x09), CR (0x0d) y LF (0x0a) de la URL. No quites las secuencias de escape para estos caracteres, como %0a.

En segundo lugar, si la URL termina en un fragmento, quítalo. Por ejemplo, acorta http://google.com/#frag a http://google.com/.

En tercer lugar, quita los escapes del porcentaje de la URL hasta que no tenga más caracteres en los escapes.

Canonicaliza el nombre de host

Extrae el nombre de host de la URL y luego haz lo siguiente:

  1. Quita todos los puntos iniciales y finales.
  2. Reemplaza los puntos consecutivos por un solo punto.
  3. Si el nombre de host se puede analizar como una dirección IP, normalízalo a 4 valores decimales separados por puntos. El cliente debe controlar cualquier codificación legal de direcciones IP, incluidos los números octal, hexadecimal y menos de cuatro componentes.
  4. Pon en minúscula toda la string.

Canonicaliza la ruta de acceso

  1. Para resolver las secuencias /../ y /./ en la ruta, reemplaza /./ por / y quita /../ junto con el componente de ruta anterior.
  2. Reemplaza las ejecuciones de barras consecutivas por un solo carácter de barra.

No apliques estas canonicalizaciones de ruta a los parámetros de búsqueda.

En la URL, usa el carácter de escape de porcentaje para todos los caracteres que son <= ASCII 32, > = 127, # o %. Se deben usar caracteres hexadecimales en mayúsculas en los escapes.

A continuación, se incluyen pruebas para ayudar a validar una implementación de canonización.

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/prefix expressions

Después de que se canoniza la URL, el siguiente paso es crear las expresiones de sufijo o prefijo. Cada expresión de sufijo o prefijo consta de un sufijo de host (o host completo) y un prefijo de ruta (o ruta de acceso completa), como se muestra en estos ejemplos.

Expresión de sufijo o prefijo Expresión regular equivalente
a.b/mypath/ http\:\/\/.*\.a\.b\/mypath\/.*
c.d/full/path.html?myparam=a http\:\/\/.*.c\.d\/full\/path\.html?myparam=a

El cliente formará hasta 30 combinaciones posibles de sufijo de host y prefijo de ruta. Estas combinaciones solo usan los componentes de host y ruta de acceso de la URL. Se descartan el esquema, el nombre de usuario, la contraseña y el puerto. Si la URL incluye parámetros de consulta, al menos una combinación incluirá la ruta de acceso completa y los parámetros de consulta.

Para el host, el cliente intentará como máximo con cinco strings diferentes. Son:

  • Es el nombre de host exacto en la URL.
  • Hasta cuatro nombres de host que se forman a partir de los últimos cinco componentes y quitando de forma sucesiva el componente inicial. Se puede omitir el dominio de nivel superior. No se deben verificar estos nombres de host adicionales si el host es una dirección IP.

Para la ruta, el cliente intentará como máximo con seis strings diferentes. Son:

  • La ruta exacta de la URL, incluidos los parámetros de búsqueda.
  • La ruta exacta de la URL, sin parámetros de búsqueda.
  • Las cuatro rutas de acceso que se forman a partir de la raíz (/) y que se agregan de forma sucesiva a los componentes de la ruta, incluida una barra diagonal al final.

En los siguientes ejemplos, se ilustra el comportamiento de la verificación:

Para la URL http://a.b.c/1/2.html?param=1, el cliente intentará ejecutar las siguientes posibles 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/

Para la URL http://a.b.c.d.e.f.g/1.html, el cliente probará estas posibles 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/

Para la URL http://1.2.3.4/1/, el cliente probará estas posibles strings:

1.2.3.4/1/
1.2.3.4/

Cálculos de hash

Después de crear el conjunto de expresiones de sufijo o prefijo, el siguiente paso es calcular el hash SHA256 de longitud total para cada expresión. A continuación, se muestra una prueba de unidad en pseudo-C que puedes usar para validar tus cálculos de hash.

Ejemplos de 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]);

Cálculos de prefijo hash

Por último, el cliente debe calcular el prefijo hash para cada hash SHA256 de longitud total. Para el Web Risk, un prefijo hash consta de los 4 a 32 bytes más importantes de un hash SHA256.

Ejemplos de FIPS-180-2:

  • Ejemplo B1 del estándar FIPS-180-2
    • La entrada es “abc”.
    • El resumen de SHA256 es ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad.
    • El prefijo hash de 32 bits es ba7816bf.
  • Ejemplo B2 del estándar FIPS-180-2
    • La entrada es abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq.
    • El resumen de SHA256 es 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1.
    • El prefijo hash de 48 bits es 248d6a61 d206.