


HTTPS is the standard technology adopted on Internet to create a secure communication channel between web applications and their users.

In Wicket we can easily protect our pages with HTTPS mounting a special request mapper called _HttpsMapper_ and using annotation _RequireHttps_ with those pages we want to serve over this protocol. Both these two entities are in package _org.apache.wicket.protocol.https_.

_HttpsMapper_ wraps an existing mapper and redirects incoming requests to HTTPS if the related response must render a page annotated with _RequireHttps_. Most of the times the wrapped mapper will be the root one, just like we saw before for _CryptoMapper_ in <<urls.adoc#_generating_structured_and_clear_urls,paragraph 10.6>>.

Another parameter needed to build a _HttpsMapper_ is an instance of class _HttpsConfig_. This class allows us to specify which ports must be used for HTTPS and HTTP. By default the port numbers used by these two protocols are respectively 443 and 80.

The following code is taken from project _HttpsProtocolExample_ and illustrates how to enable HTTPS in our applications:

[source,java]
----
//Application class code...
@Override
public void init(){   
   setRootRequestMapper(new HttpsMapper(getRootRequestMapper(), 
                                       new HttpsConfig(8080, 8443)));
}
----

Now we can use annotation _RequireHttps_ to specify which pages must be served using HTTPS:

[source,java]
----
@RequireHttps
public class HomePage extends WebPage {
    public HomePage(final PageParameters parameters) {
    	super(parameters);	
    }
}
----

If we want to protect many pages with HTTPS without adding annotation _RequireHttps_ to each of them, we can annotate a marker interface or a base page class and implement/extend it in any page we want to make secure:

[source,java]
----
// Marker interface:
@RequireHttps
public interface IMarker {
}

// Base class:
@RequireHttps
public class BaseClass extends WebPage {
//Page code...
}

// Secure page inheriting from BaseClass:
public class HttpsPage extends BaseClass {
//Page code...
}

// Secure page implementing IMarker:
public class HttpsPage implements IMarker {
//Page code...
}
----

=== The redirect host comes from the container

When _HttpsMapper_ builds the redirect that switches a request to HTTPS, the hostname it uses is the one reported by the servlet container - _HttpServletRequest.getServerName()_, which is the _Host_ header of the incoming request. The same is true of every absolute URL Wicket renders, and of the target URI that Wicket's resource-isolation policies compare incoming _Origin_ and _Referer_ headers against.

Wicket trusts this value as its own identity and performs no hostname validation of its own: only the deployment knows which hostnames are canonical, so the framework cannot decide this for us. Making sure that only expected _Host_ values ever reach the application is therefore part of deploying a Wicket application, not something the framework does for us:

* configure the container or virtual host to reject requests carrying an unrecognised _Host_, returning a 400 or 404 instead of routing them to the application;
* when TLS is terminated at a reverse proxy, have the proxy set _Host_ to the canonical name rather than passing on whatever the client sent;
* avoid exposing a Wicket application through a catch-all or default virtual host that accepts any _Host_;
* serve the application over HTTPS and enable HSTS, so that the plain HTTP requests _HttpsMapper_ exists to upgrade are not part of the normal flow.

On a deployment that does accept arbitrary _Host_ values, redirects and absolute URLs will contain the host the client supplied. Note that this is not a way for an attacker to reach an origin they did not already control - a browser derives the _Host_ header from the URL it is fetching, so the host in the response is always the authority the client had already connected to. It does, however, weaken the _Origin_ and _Referer_ checks mentioned above, which is the better reason to get the container configuration right.

Wicket also ignores the _X-Forwarded-For_ and _X-Forwarded-Proto_ headers unless we explicitly install _XForwardedRequestWrapperFactory_, which should only be enabled when a trusted proxy in front of the application strips any client-supplied copies of them. Note that Wicket does not implement _X-Forwarded-Host_ at all; the host always comes from the container.

