java.lang.Object
org.eclipse.jetty.util.component.AbstractLifeCycle
org.eclipse.jetty.util.component.ContainerLifeCycle
org.eclipse.jetty.server.handler.AbstractHandler
org.eclipse.jetty.server.handler.AbstractHandlerContainer
org.eclipse.jetty.server.handler.HandlerWrapper
org.eclipse.jetty.server.handler.gzip.GzipHandler
net.i2p.router.web.HostCheckHandler
- All Implemented Interfaces:
Handler, org.eclipse.jetty.server.handler.gzip.GzipFactory, HandlerContainer, Container, Destroyable, Dumpable, LifeCycle
public class HostCheckHandlerextends org.eclipse.jetty.server.handler.gzip.GzipHandler
Block certain Host headers to prevent DNS rebinding attacks.
This Handler wraps the ContextHandlerCollection, which handles all the webapps (not just routerconsole). Therefore, this protects all the webapps.
Nested Class Summary
Nested classes/interfaces inherited from class AbstractLifeCycle
AbstractLifeCycle.AbstractLifeCycleListenerNested classes/interfaces inherited from interface Container
Container.InheritedListener, Container.ListenerNested classes/interfaces inherited from interface LifeCycle
LifeCycle.ListenerField Summary
FieldsModifier and TypeFieldDescriptionprivate final I2PAppContextThe context reading the settings.Host names the console answers on.private final PortMapperGives the console's configured addresses.private static final StringProperty enabling response compression.private static final StringProperty asking for HTTP requests to be redirected.Fields inherited from class org.eclipse.jetty.server.handler.gzip.GzipHandler
DEFAULT_MIN_GZIP_SIZE, DEFLATE, GZIPFields inherited from class HandlerWrapper
_handlerFields inherited from class AbstractLifeCycle
FAILED, RUNNING, STARTED, STARTING, STOP_ON_FAILURE, STOPPED, STOPPINGConstructor Summary
ConstructorsMethod Summary
Modifier and TypeMethodDescriptionprivate booleanShould we allow a request with this Host header?private booleanallowOrigin(HttpServletRequest request) Validate Origin header for POST requests.private static StringextractHost(String hostPort) Extract host from "host:port" or "[ipv6]:port".private static intextractPort(String hostPort, int defaultPort) Extract port from "host:port" or "[ipv6]:port", default to defaultPort if not found.private static StringStrip [] and port from a host header.voidhandle(String pathInContext, Request baseRequest, HttpServletRequest httpRequest, HttpServletResponse httpResponse) Block by Host header, redirect HTTP to HTTPS, pass everything else to the delegate.(package private) static booleanisLoopbackName(String host) True when the host is a textual loopback name: an IPv4 address in 127/8, the IPv6 loopback in its written forms, or "localhost".(package private) static booleanoriginAllowed(String origin, String hostHeader, boolean secure) Decide whether an Origin header is acceptable for a request to the given Host header.private static intParse a port written in a header value.private static voidsendRedirect(int httpsPort, HttpServletRequest httpRequest, HttpServletResponse httpResponse) Redirect to HTTPS.voidsetListenHosts(Set<String> hosts) Set the legal hosts.Methods inherited from class org.eclipse.jetty.server.handler.gzip.GzipHandler
addExcludedAgentPatterns, addExcludedMethods, addExcludedMimeTypes, addExcludedPaths, addIncludedAgentPatterns, addIncludedMethods, addIncludedMimeTypes, addIncludedPaths, doStart, getCheckGzExists, getCompressionLevel, getDeflater, getDispatcherTypes, getExcludedAgentPatterns, getExcludedMethods, getExcludedMimeTypes, getExcludedPaths, getIncludedAgentPatterns, getIncludedMethods, getIncludedMimeTypes, getIncludedPaths, getMinGzipSize, getVaryField, isAgentGzipable, isMimeTypeGzipable, isPathGzipable, isSyncFlush, recycle, setCheckGzExists, setCompressionLevel, setDispatcherTypes, setDispatcherTypes, setExcludedAgentPatterns, setExcludedMethods, setExcludedMimeTypes, setExcludedPaths, setIncludedAgentPatterns, setIncludedMethods, setIncludedMimeTypes, setIncludedPaths, setMinGzipSize, setSyncFlushMethods inherited from class HandlerWrapper
destroy, expandChildren, getHandler, getHandlers, insertHandler, setHandlerMethods inherited from class AbstractHandlerContainer
expandHandler, findContainerOf, getChildHandlerByClass, getChildHandlers, getChildHandlersByClass, setServerMethods inherited from class AbstractHandler
doStop, dumpThis, getServerMethods inherited from class ContainerLifeCycle
addBean, addBean, addBean, addEventListener, addManaged, contains, dump, dump, dump, dump, dump, dumpBeans, dumpObject, dumpStdErr, getBean, getBeans, getBeans, isManaged, manage, removeBean, removeBeans, removeEventListener, setBeans, setStopTimeout, start, stop, unmanage, updateBean, updateBean, updateBeansMethods inherited from class AbstractLifeCycle
addLifeCycleListener, getState, getState, getStopTimeout, isFailed, isRunning, isStarted, isStarting, isStopped, isStopping, removeLifeCycleListener, start, stop
Field Details
_context
The context reading the settings._portMapper
Gives the console's configured addresses._listenHosts
PROP_REDIRECT
Property asking for HTTP requests to be redirected.- See Also:
PROP_GZIP
Property enabling response compression.- See Also:
Constructor Details
HostCheckHandler
MUST callsetListenHosts(Set)afterwards.- Parameters:
ctx- the context used to resolve console ports, properties and logging
Method Details
setListenHosts
handle
public void handle(String pathInContext, Request baseRequest, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException Block by Host header, redirect HTTP to HTTPS, pass everything else to the delegate.- Specified by:
handlein interfaceHandler- Overrides:
handlein classorg.eclipse.jetty.server.handler.gzip.GzipHandler- Throws:
IOExceptionServletException
allowHost
Should we allow a request with this Host header?ref: https://en.wikipedia.org/wiki/DNS_rebinding
- Parameters:
host- the HTTP Host header, null ok- Returns:
- true if OK
getHost
allowOrigin
Validate Origin header for POST requests. Allows requests with matching Origin (same-origin), or no Origin header. Rejects cross-origin POST requests to prevent CSRF attacks.- Parameters:
request- the HTTP request- Returns:
- true if allowed
originAllowed
Decide whether an Origin header is acceptable for a request to the given Host header. Same-origin is allowed, as is a request where both sides are loopback and the ports match; anything else is rejected.Both sides are compared as literal text. Neither header is ever resolved through DNS: a hostname whose A record points at 127.0.0.1 (DNS rebinding) is not loopback here, which is what keeps the localhost allowance from becoming a CSRF bypass. Resolving attacker-supplied host names on the request thread would also hand a slow or hostile resolver control of the Jetty thread pool.
- Parameters:
origin- the Origin header value, null or empty for a same-origin form POST that carries no OriginhostHeader- the Host header value, "host" or "host:port", IPv6 addresses bracketedsecure- true when the request arrived over TLS, used only for the default port when the Host header omits one- Returns:
- true if the request is allowed
isLoopbackName
True when the host is a textual loopback name: an IPv4 address in 127/8, the IPv6 loopback in its written forms, or "localhost". No DNS lookup is performed, so a hostname that happens to resolve to a loopback address is not accepted.- Parameters:
host- the host to test, null-safe- Returns:
- true if the name itself denotes the local host
extractHost
extractPort
Extract port from "host:port" or "[ipv6]:port", default to defaultPort if not found.- Parameters:
hostPort- the header value to splitdefaultPort- the port to assume when the value carries none- Returns:
- the port, or -1 if a port was present but is not a number, so a malformed header fails the comparison instead of throwing
parsePort
Parse a port written in a header value.- Parameters:
s- the digits after the colon- Returns:
- the port, or -1 if it is not a valid port number
sendRedirect
private static void sendRedirect(int httpsPort, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException Redirect to HTTPS.- Parameters:
httpsPort- the port to redirect the browser tohttpRequest- the request whose server name, URI and query string form the targethttpResponse- the response given the 307 status and Location header- Throws:
IOException- if the response output stream cannot be opened