This section contains detailed specifications of how clients check URLs.
Canonicalization of URLs
Before any URLs are checked, the client is expected to perform some canonicalization on that URL.
To begin, we assume that the client has parsed the URL and made it valid according to RFC 2396. If the URL uses an internationalized domain name (IDN), the client should convert the URL to the ASCII Punycode representation. The URL must include a path component; that is, it must have at least one slash following the domain (http://google.com/
instead of http://google.com
).
First, remove tab (0x09), CR (0x0d), and LF (0x0a) characters from the URL. Do not remove escape sequences for these characters (e.g. %0a
).
Second, if the URL ends in a fragment, remove the fragment. For example, shorten http://google.com/#frag
to http://google.com/
.
Third, repeatedly percent-unescape the URL until it has no more percent-escapes. (This may render the URL invalid.)
To canonicalize the hostname:
Extract the hostname from the URL and then:
- Remove all leading and trailing dots.
- Replace consecutive dots with a single dot.
- If the hostname can be parsed as an IPv4 address, normalize it to 4 dot-separated decimal values. The client should handle any legal IP-address encoding, including octal, hex, and fewer than four components.
- If the hostname can be parsed as a bracketed IPv6 address, normalize it by removing unnecessary leading zeroes in the components and collapsing zero components by using the double-colon syntax. For example
[2001:0db8:0000::1]
should be transformed into[2001:db8::1]
. If the hostname is one of the two following special IPv6 address types, transform them into IPv4:- An IPv4-mapped IPv6 address, such as
[::ffff:1.2.3.4]
, which should be transformed into1.2.3.4
; - A NAT64 address using the well-known prefix 64:ff9b::/96, such as
[64:ff9b::1.2.3.4]
, which should be transformed into1.2.3.4
.
- An IPv4-mapped IPv6 address, such as
- Lowercase the whole string.
To canonicalize the path:
- Resolve the sequences
/../
and/./
in the path by replacing/./
with/
, and removing/../
along with the preceding path component. - Replace runs of consecutive slashes with a single slash character.
Do not apply these path canonicalizations to the query parameters.
In the URL, percent-escape all characters that are <= ASCII 32, >= 127, #
, or %
. The escapes should use uppercase hex characters.
Host-Suffix Path-Prefix Expressions
Once the URL is canonicalized, the next step is to create the suffix/prefix expressions. Each suffix/prefix expression consists of a host suffix (or full host) and a path prefix (or full path).
The client will form up to 30 different possible host suffix and path prefix combinations. These combinations use only the host and path components of the URL. The scheme, username, password, and port are discarded. If the URL includes query parameters, then at least one combination will include the full path and query parameters.
For the host, the client will try at most five different strings. They are:
- If the hostname is not an IPv4 or IPv6 literal, up to four hostnames formed by starting with the eTLD+1 domain and adding successive leading components. The determination of eTLD+1 should be based on the Public Suffix List. For example,
a.b.example.com
would result in the eTLD+1 domain ofexample.com
as well as the host with one additional host componentb.example.com
. - The exact hostname in the URL. Following the previous example,
a.b.example.com
would be checked.
For the path, the client will try at most six different strings. They are:
- The exact path of the URL, including query parameters.
- The exact path of the URL, without query parameters.
- The four paths formed by starting at the root (/) and successively appending path components, including a trailing slash.
The following examples illustrate the check behavior:
For the URL http://a.b.com/1/2.html?param=1
, the client will try these possible strings:
a.b.com/1/2.html?param=1
a.b.com/1/2.html
a.b.com/
a.b.com/1/
b.com/1/2.html?param=1
b.com/1/2.html
b.com/
b.com/1/
For the URL http://a.b.c.d.e.f.com/1.html
, the client will try these possible strings:
a.b.c.d.e.f.com/1.html
a.b.c.d.e.f.com/
c.d.e.f.com/1.html
c.d.e.f.com/
d.e.f.com/1.html
d.e.f.com/
e.f.com/1.html
e.f.com/
f.com/1.html
f.com/
(Note: skip b.c.d.e.f.com
, since we'll take only the last five hostname components, and the full hostname.)
For the URL http://1.2.3.4/1/
, the client will try these possible strings:
1.2.3.4/1/
1.2.3.4/
For the URL http://example.co.uk/1
, the client will try these possible strings:
example.co.uk/1
example.co.uk/
Hashing
Google Safe Browsing exclusively uses SHA256 as the hash function. This hash function should be applied to the above expressions.
The full 32-byte hash will, depending on the circumstances, be truncated to 4 bytes, 8 bytes, or 16 bytes:
When using the hashes.search method, we currently require the hashes in the request to be truncated to exactly 4 bytes. Sending additional bytes in this request will compromise user privacy.
When downloading the lists for the local database using the hashList.get method or the hashLists.batchGet method, the length of the hashes sent by the server is encoded within the naming convention of the lists that contain suffix indicating hash length. See Available Lists section for more details.