I am trying to insert a header on all HTTPS requests that passes my proxy server.
I read that HTTPS request headers can not be tampered with.
Is there any way that I can insert a header on HTTPS requests?
Only if the proxy is the endpoint of the TLS connection with the client (i.e. the proxy decrypts the requests). Otherwise it won't actually see any HTTP headers at all, just TCP sessions containing encrypted data.
It is common for a reverse proxy local to the web server(s) to terminate TLS connections for performance - the Web server can dedicate more resources to serving applications because it doesn't need to spend CPU cycles on de/encryption.
If you do this, your server certificate must identify the proxy server, not the web server. Otherwise clients will get a warning about the identity of the server differing from the certificate identity.
If you don't control or trust the infrastructure between the proxy and your server you could re-encrypt the ongoing requests.
Unless you are willing to terminate the SSL connection on your proxy, no you can't. This is one of the main goals of SSL. The data and that includes the headers are encrypted from the client to the server.
If you decide to terminate / intercept the SSL connection on your proxy, the clients will get a warning in their browsers. If you are in charge of all the browsers of all the clients you would be able to install a custom certificate and the clients wouldn't get warned anymore.
Related
Good afternoon everyone,
I'm having some issues with my HTTP server. I've made my own HTTP server (A lightweight HTTP server due some circumstances and needings) that I want to implement on a software I have. This HTTP API also is used to allow HTTPS, but my main issue comes actually with HTTP.
One issue I'm facing is retrieving HTTPS connections on the HTTP server. Using HTTPS as the server and HTTP as the connection from the client gets denied, as the Handshake fails and gives an Exception to the server. The problem using the HTTP server with an HTTPS client is that this connections keeps running, but the message is encrypted. As it's encrypted, I can't read the information and get details like the Content-Length, so the server is waiting for an end that will never come as it can't read correctly the data.
I was wondering if there's a way in Java to detect if the client is using encrypted responses to deny this connections instead of trying to read them. The main issue with this sockets is that they aren't detected as SSLSockets, they are normal sockets that can't decrypt the information in the InputStream.
Thank you in advance.
Are you aware that HTTP and HTTPS are usually served on different port numbers? So 80 is for HTTP and 443 for HTTPS. For non-privileged ports often 8000 and 8443 are used. A client that connects using TLS on a HTTP-only port is faulty, and your HTTP server should easily detect non-HTTP traffic:
If the first word received isn't one of the HTTP verbs supported by your server, such as GET, HEAD, POST, PUT, OPTIONS, etc. your server should send a 400 or 408 response (408 is request timeout, your server should only wait a reasonable amout of time for the request header) and then close the connection.
As a Proxy Program sitting in between Server and Browser , how can we notify a browser to use either http1.1 or http2.0 protocol
The answer depends on whether your "proxy" is a forward proxy configured on the browser, or a reverse proxy configured on the server.
In the first case (forward proxy), because the target scheme is https, the browser will issue a HTTP CONNECT to the forward proxy and the forward proxy will create a tunnel to the server.
Once the tunnel is created, the browser and the server will communicate directly with the forward proxy only forwarding bytes in both directions.
In this case, client and server will negotiate directly the protocol via ALPN because they communicate directly, with the forward proxy only forwarding bytes (but not inspecting or otherwise changing them).
Therefore in this case you don't need to inform the client of anything, because client and server communicate directly.
In the second case (reverse proxy) the browser will connect to the reverse proxy thinking it's its final destination.
For a request to https://example.com, the DNS will resolve the reverse proxy address, and the reverse proxy must offer a valid certificate for example.com.
If the reverse proxy needs to forward the request to a server, then it does not matter what protocol it will use, since the client will never be aware of this communication between the reverse proxy and the server.
If the reverse proxy supports only HTTP/1.1 and the server supports HTTP/2, then the reverse proxy cannot tell the client that the server supports HTTP/2 because the client never talks directly to the server: the client only sees the reverse proxy and because the reverse proxy only supports HTTP/1.1 then they will never be able to speak HTTP/2, even if the server does.
If the reverse proxy supports both HTTP/1.1 and HTTP/2, then the client and the reverse proxy will speak HTTP/2. It does not matter what protocol the reverse proxy speaks to the server: it can be HTTP/1.1, HTTP/2, FastCGI, etc. But the protocol that the reverse proxy uses with the server is of no interest to the client because the client will never be able to talk directly to the server.
The client only ever speaks to the reverse proxy, so the protocol that they negotiate is the only one that matters to the client.
In this case also you don't need to inform the client of anything, because the client can only communicate with the proxy and can only use the protocol that it negotiated with the proxy.
I have ActiveMQ (JMS) and want to connect multiple clients.
To support SSL security in Java clients, Apache ActiveMQ provides ssl support.
ActiveMQ how-do-i-use-ssl. If you want to verify client certificates, you need to take extra work for every client.
Is a client certificate necessary?
Customers can install the clients themselves, so it is not possible for me to create a certificate for every client.
Is my client connection then secure?
I have a HTTP server with runs with HTTP and HTTPS, written using Javas NIO and SSL libraries. In HTTPS mode it can communicate with or without the client certificate. However, I would like to perform renegotiation. Here the client will connect with HTTPS, browse resources and then when they hit a highly secure resource the server challenges the client for its certificate. I have been having a few problems with this and need to know what the workflow should be. Here is what I have observed with both IE 9 and Chrome.
1) When the client requests the secure resource, I respond to the HTTP request in full. I then challenge the client for their cert upon completion with
engine.setNeedClientAuth(true);
engine.beginHandshake();
The result is a TCP FIN from the client (it closes its side of the connection), and the renegotiation fails.
2) When the client requests the secure resource, I challenge for the cert before responding. In this scenario the exchange occurs, both browsers will popup a request for the cert, however as soon as it pops up the prompt a TCP FIN is sent from the client and renegotiation terminates. The client then sends another request which eventually has the certificate, at times I have to challenge twice.
So my question here is, what is supposed to happen? Is the initial browser connection supposed to remain open, or is termination like this normal?
NOTE: Another very interesting observation here is that, in scenario 2, when the browser closes the TCP connection, it then reconnects after you choose the certificate. It does not however repost the request, it just sits there and expects the server to respond? In NIO terminology its sits waiting on an OP_READ, which means there is no data on the socket input buffer. Do the browsers expect a response to the original message that it terminated the connection for??
Strange that there is absolutely no documentation or a specification for this workflow, yet for all the browsers I've tested they seem to follow this workflow.
(1) is insecure and therefore pointless to discuss further. You've already leaked the information before you even ask for the credentials.
(2) is the correct way to do this. The client shouldn't be closing the connection if it is configured to allow renegotiation. Due to an SSL security problem last year or so there was temporarily a phase where SSL renegotiation was disallowed by default. You may be running into this. In that case you should be issuing an HTTP redirect first, and closing the connection at your end to force the client to use a new connection, and the new connection should ask for a client certificate. How you arrange that in your code is up to you.
i am here looking for resources or sample code for proxy server which can handle both http and https requests written in java. i searched google and found lot of data on how to handle http requests but not https.
A proxy cannot handle HTTPS and still provide end to end security. It is not possible using SSL/TLS which is what HTTPS is built on.
And a proxy that doesn't provide end-to-end security only has limited utility. So I'm not surprised you can't find an existing implementation.
I'm assuming that you want a normal HTTPS proxy here, that is a proxy that will not look into the request but merely relay all the traffic to the actual HTTPS server after the user-agent has used the HTTP CONNECT method. This is how HTTP proxy servers are normally used for HTTPS requests by browsers.
I haven't tried, but you could look at Jetty and its ConnectHandler.