Class AdminBoundary
ConfigResource, LogsResource and ShutdownResource.
registration(String, String...) returns a ServletFilterRegistration that puts the three resources
behind their own CsrfBoundary. A write from another site's page is refused with 403 and an
"X-Request-Boundary" header naming the reason. So is a write that a browser could
have sent cross-site without a CORS preflight and that carries no Origin: a urlencoded, multipart or
text/plain POST, or a GET claiming another method through ?method= or an override
header. Reads are allowed.
The admin resources have no HTML forms or write links, so no page ever carries a token, and a browser write to them always fails. Writes come from REST clients and the command line as requests a browser could not send cross-site without a preflight, and the boundary admits those with no token:
curl -X PUT -H 'Content-Type: text/plain' -d 'newValue' http://localhost:10000/config/MySection/myKey curl -X DELETE http://localhost:10000/logs/old.log curl -X POST -H 'Content-Type: application/json' http://localhost:10000/shutdown
Every request, reads included, must name one of the allowed hosts in its Host header, or it is refused with
421. Unless other host names are given, only the loopback names LOOPBACK_HOSTS are answered, so a
page on a rebound DNS name cannot read the configuration or the logs. A server reached under any other name must
list that name.
The boundary answers only CSRF and DNS rebinding. It does not authenticate anyone, and a direct network caller passes it. The admin resources have no authentication of their own, so do not expose them on an untrusted network.
The filter is mapped on the request path as the servlet container normalizes it, while Juneau routes on the path
segments it receives. The two agree under the container's default URI handling (for Jetty 12,
UriCompliance.DEFAULT, which rejects ambiguous paths such as encoded separators and dot segments). A
container configured to accept ambiguous paths could route a request to an admin resource without the filter seeing
it, so keep the default, and verify any other container the same way.
Example:
In a Juneau microservice whose root resource mounts the three resources as children, contribute the registration
as a
See Also:
- Since:
- 10.0.0
-
Field Summary
FieldsModifier and TypeFieldDescriptionThe host names answered when none are given:localhost,127.0.0.1and[::1], on any port.static final intThe order the registration runs at: ahead of authentication, behind anything registered at the very front. -
Method Summary
Modifier and TypeMethodDescriptionstatic ServletFilterRegistrationregistration(String prefix, String... allowedHosts) A registration of a new CSRF boundary over the three admin resources.
-
Field Details
-
LOOPBACK_HOSTS
The host names answered when none are given:localhost,127.0.0.1and[::1], on any port. -
ORDER
The order the registration runs at: ahead of authentication, behind anything registered at the very front.- See Also:
-
-
Method Details
-
registration
A registration of a new CSRF boundary over the three admin resources.The registration maps each resource's path both exactly and as a prefix (
/configand/config/*, and so on: six patterns), forREQUESTdispatches only, atORDER. Each call builds its own filter, so the registration never shares an instance with another boundary. The boundary's token is per process; no admin page carries one.- Parameters:
prefix- The path the three resources are mounted under:"" when they are children of the root resource, otherwise a path such as"/admin" : one or more/-separated segments of letters, digits,.,_,~or-, none starting with., and no trailing/. A prefix the container would not match as written is refused, so the resources are never left uncovered. Must not benull .allowedHosts- The host names this server is reached under, without ports. A request to the admin resources under any otherHostis refused with421, reads included: this is the DNS-rebinding defence a server on plain HTTP needs. With none,LOOPBACK_HOSTSapplies. The list replaces the loopback names rather than adding to them. Must not benull , and no entry may benull or blank.- Returns:
- A new registration.
- Throws:
IllegalArgumentException- Ifprefixis malformed, orallowedHostsor an entry isnull , blank or not a bare host name.
-