Class SafeAddressGuard
Why. A URL the server fetches for someone else — a subscribed calendar, a sender's logo, an image an agent was given — would otherwise make the platform a client of whatever sits on its own network: an administration console on loopback, a database's HTTP port on a private address, the cloud metadata endpoint handing out credentials.
What it decides. The URL's shape — an allowed scheme, no credentials,
a host, an allowed port, and the address itself when the host is an IP
literal (checkTarget(java.net.URI)) — and the addresses its host resolves to
(resolveAllowed(java.lang.String)): loopback, link-local (the metadata
address 169.254.169.254 among them), private, carrier-grade NAT, multicast,
broadcast and reserved, unspecified, IETF assignments, benchmarking, IPv6
unique-local and site-local, and each of those spelled as an IPv4 address
inside an IPv6 one (mapped, compatible, NAT64, 6to4) are refused unless the
policy allows internal addresses.
Where the address is checked. resolveAllowed(java.lang.String) is the resolver
of SafeHttpFetcher's connection manager (GuardedDnsResolver),
so it judges the very addresses the client then connects to, for every
connection it opens — every redirect hop included. A name that resolved to a
public address when it was first seen and to a private one when the
connection opens (DNS rebinding) is refused at that connection, not trusted
from an earlier answer. An IP literal is judged twice: by checkTarget(java.net.URI)
before the request, so its refusal does not depend on how the HTTP client
resolves a literal host, and by the resolver when the connection opens.
What stays outside its reach: a public server that
itself relays the request inward, and the time a refused or unreachable
answer takes, which says something about a public host.
-
Field Summary
Fields -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptioncheckTarget(URI uri) Checks the shape of a URL about to be read — the one given, or the target of a redirect: absolute, an allowed scheme, no credentials, a host, an allowed port, not too long, no white space or control character; and, when the host is an IP literal, the address it names, under the same rules asresolveAllowed(java.lang.String).static booleanisBlocked(InetAddress address) Whether one address is outside what a fetched URL may point at.Reads a URL as it was given: trimmed, the fragment dropped, then checked bycheckTarget(java.net.URI).resolveAllowed(String host) Resolves a host and refuses it when ANY of its addresses is one the platform must not reach — a name answering one public and one loopback address is a name reaching loopback.
-
Field Details
-
MAX_URL_LENGTH
public static final int MAX_URL_LENGTHLongest URL accepted.- See Also:
-
-
Constructor Details
-
SafeAddressGuard
The guard of a policy.- Parameters:
policy- what may be read
-
-
Method Details
-
normalize
Reads a URL as it was given: trimmed, the fragment dropped, then checked bycheckTarget(java.net.URI). Nothing is resolved here.- Parameters:
url- the URL as given- Returns:
- the URL to read
- Throws:
SafeFetchException- with the reason it is refused
-
checkTarget
Checks the shape of a URL about to be read — the one given, or the target of a redirect: absolute, an allowed scheme, no credentials, a host, an allowed port, not too long, no white space or control character; and, when the host is an IP literal, the address it names, under the same rules asresolveAllowed(java.lang.String). A host name is not resolved here.- Parameters:
uri- the URL- Returns:
- the URL with its scheme lower-cased
- Throws:
SafeFetchException- with the reason it is refused
-
resolveAllowed
Resolves a host and refuses it when ANY of its addresses is one the platform must not reach — a name answering one public and one loopback address is a name reaching loopback. This is the HTTP client's resolver: its answer is what the client connects to.- Parameters:
host- the host, brackets of an IPv6 literal allowed- Returns:
- the addresses, every one allowed
- Throws:
RefusedAddressException- when an address is refusedUnknownHostException- when the host resolves to nothing
-
isBlocked
Whether one address is outside what a fetched URL may point at.The JDK predicates cover the any-local, loopback, link-local, site-local (RFC 1918 in IPv4, fec0::/10 in IPv6) and multicast addresses; the byte inspection covers the rest, and the IPv4 address an IPv6 address may carry, which is how
::ffff:127.0.0.1or64:ff9b::a9fe:a9fewould otherwise walk past a loopback or metadata check.- Parameters:
address- one resolved address- Returns:
- true when the platform must not reach it
-