In my Play 2.5.x (Scala) web application I am using following technique to get absolute URL of the route (server name + uri):
controllers.routes.MyController.MyRoute.absoluteURL()
I recently found out that it uses Host header in the incoming http request to return absolute url. Use of Host header is not recommended as it's quite easy to do Host header injection attack.
Is there a secure way of getting the server name ?
Have a look at Play! implementation of CSRF attack protection and the Allowed Hosts configuration.
You can specify known hosts with the latter and it will reject requests from unknown hosts.
Related
The manual says this about the HTTP URL value of an http listener:
"Displays the generated HTTP URL for the HTTP Listener. This is not an actual
configurable setting, but is instead displayed for copy/paste convenience. Note
that the host in the URL will be the same as the host you used to connect to
the Administrator. The actual host that connecting clients use may be different
due to differing networking environments."
When I have used the feature in the past its value has always begun "http://localhost:" which would be great except this time it is auto-generating " http://'domainName':${Incoming_Pathology_Source_Port}/${Incoming_Pathology_Source_BaseContextPath}/"
For the first time, we are deploying Mirth inside a Kubernetes cluster, 'a different working environment'. (nginx accepts https and we want it pass the messages on as http to Mirth).
Is there any way I can take control of the URL or must I change the configuration of the cluster in some way.
All help/suggestions welcome.
I'm trying to obtain the beginning of the URL that a client used to access a webserver in Http4s. I.e. given a Request[F] I want to obtain the string "http://localhost:8080" or "https://my-app.company.com" depending on where the server is deployed.
In a server implementation with Http4s, when receiving a Request via something like
HttpRoutes.of[IO] {
case req =>
println(req.uri)
???
}
I only ever seem to get a relative URI, e.g. / or /foo/bar - the scheme and authority fields on the Uri are both None.
It looks like I can pull the localhost:8080 part from the Host header on the request, but I have no solution for the scheme (http:// or https://).
How can I fill in the correct value for request.uri.scheme? And is there a more appropriate way to obtain the host?
FWIW I'm using http4s 0.22
You can't get it while using Blaze as an HTTP server. There are workarounds. You can catch bound of a server:
By port:
[io-compute-4] INFO org.http4s.blaze.channel.nio1.NIO1SocketServerGroup - Service bound to address /[0:0:0:0:0:0:0:0]:8080
By schema:
[io-compute-4] INFO org.http4s.blaze.server.BlazeServerBuilder - http4s v1.0.0-M33 on blaze v1.0.0-M33 started at http://[::]:8080/
Or you can map 8080 to HTTP and 8081 to HTTPS and make pattern matching on it.
A bad workaround would be to add it as an HTTP header and read it via Headers
It legacy practice but many legacy software companies are still using this approach.
We have a site that we are trying to configure as a client in a SSO scenario, using WS Federation and SAML.
Our site sits behind a load balancer that is doing SSL offloading - the connection to the balancer is under https, but decrypted and forwarded (internally) to the actual site under http and port 81.
Somewhere the WS federation module is attempting to redirect us, but is building up the URL based on the port and incoming protocol to the website:
We request:
https://www.contoso.com/application
and are getting redirected to:
http://www.contoso.com:81/Application
Which doesn't work as the load balancer (correctly) won't respond on this port.
And it seems to be related to the casing of the virtual directory. Browsing to
https://www.contoso.com/Application
seems to work without issue.
(Note for completeness, attempting to browse to http://www.contoso.com/Application with no port will correctly redirect us to the SSL secured URL).
I am trying to find out:
a) Where this redirect is happening in the pipeline and
b) How to configure it to use the correct external address.
If anybody is able to point me in the right direction, I would very much appreciate it.
EDIT 14:19: Seems to be either the WsFederationAuthenticationModule or the SessionAuthenticationModule. These do a case sensitive comparison of the incoming url to what it expects and redirects otherwise:
https://brockallen.com/2013/02/08/beware-wif-session-authentication-module-sam-redirects-and-webapi-services-in-the-same-application/
So that seems to be happening, its a matter now of trying to get the site to behave nicely and redirect to the correct external url.
The following seems to be related and ultimately points to the culprit in the default CookieHandler:
Windows Identity Foundation and Port Forwarding
Looking at that code decompiled in VS, it compares HttpContext.Current.Request.Url against the targetUrl and will redirect to the expected 'cased' version otherwise (in our case including the errant port number).
It would seem that explicitly setting the path attribute of the cookie fixes this issue. Either an empty string or the virtual directory name seems to work:
<federationConfiguration>
<cookieHandler requireSsl="true" name="ContosoAuth" path="/Application/"/>
<wsFederation passiveRedirectEnabled="true" issuer="https://adfsSite" realm="https://www.contoso.com/Application/" reply="https://www.contoso.com/Application/Home" requireHttps="true"/>
</federationConfiguration>
I want to send request like this:
GET https://220.181.57.217/v1/groups
Host: test.restapi.foobar.com
But got this error:
error: SSLError: hostname '220.181.57.217' doesn't match 'test.restapi.foobar.com' while doing GET request to URL: https://220.181.57.217/v1/groups
According to rfc2616: Hypertext Transfer Protocol -- HTTP/1.1, it is due to how host is determined:
If Request-URI is an absoluteURI, the host is part of the
Request-URI. Any Host header field value in the request MUST be
ignored.
If the Request-URI is not an absoluteURI, and the request includes
a Host header field, the host is determined by the Host header
field value.
The reason for using IP in request URI is: in China, mobile dns resolution is not so good. Connect API server with IP is much better.
Is there a way to accomplish it?
Thanks!
check your GET URL,whether it has any ports number after IP,whther it is http or https protocol and your REST API path.
I hope i am at the right place asking this question, its regarding understanding of SNI
According to https://devcentral.f5.com/articles/ssl-profiles-part-7-server-name-indication#.U5wEnfmSzOz
"With the introduction of SNI, the client can indicate the name of the server to which he is attempting to connect as part of the "Client Hello" message in the handshake process"
My question is how does client like browser or any HTTP client (say java.net) send this server name in CLIENT HELLO?? Does client do by itself or you have to add it Programmatically to https request (e.g how in JAVA.net HttpsURLConnection)
Reading from http://www.ietf.org/rfc/rfc4366.txt
"Currently, the only server names supported are DNS hostnames"
so the hostname is the server_name sent by SNI complient client or any other name can be sent by the client..
I hope i am clear, do improve the question/wording if its unclear or let me know if its not clear
thanks
If you are using an https library, which you can give a URL and the library will fetch the contents of that URL for you, then the clean way to add SNI support is to perform it entirely within the library.
It is the library which parses the URL to find the hostname, the caller will never know which part of the URL is the hostname, so the caller couldn't tell the library which hostname to send in the SNI request. If the caller had to somehow figure out the hostname in order to tell this to the library, then that would be a poorly designed library.
You might look a level deeper in the software stack and find that an https library might be building on top of an SSL library. In such a case even the https library does not need to know about SNI. The https library would simply tell the SSL library, that it want a connection to a particular hostname. The SSL library would resolve the hostname to get IP address to connect to, the SSL library would also be performing the SSL handshake during which the client may send a hostname as part of SNI and the server send a hostname as part of a certificate for the client to verify.
During connection setup, the SSL client library need to use the hostname for three different purposes. It would be trivial to support the usage of three different hostnames for those three purposes. The https library already know the hostname, and passing that hostname three times to the SSL library rather than just one wouldn't be any significant amount of additional work. But it would hardly make sense to support this anyway.
In fact SNI could be entirely transparent to the https library. It would make sense to extend the SSL library with SNI support without changing the API to the https library. There is little reason to turn off SNI support in a client, which supports it. So defaulting to having SNI enabled makes sense.