HTTPS key negotiation and tunneling over HTTP using Javascript - encryption

HTTPS is widely used for security online. It offers security and integrity, but not authentication. To ensure the client is not talking to a man-in-the-middle, we have digital certificates and the PKI. It all works very well, except in the situation where the following criteria apply:
The server and client do not share a common, trusted root CA, therefore they cannot validate each other's certificates
Circumstances (eg. firewall, permissions, etc) do not permit the use of regular HTTPS protocol
The question is: can we still send secure, authenticated messages between the client and server, perhaps using Javascript?
Something along the lines of:
Client sends regular HTTP request to server
Server responds with page containing Javascript code
Client's Javascript asynchronously sends data to the server used to negotiate
Server runs some sort of script (eg. PHP) to establish the tunnel
Client and server communicate over the encrypted tunnel
I can see it being possible to send messages with security and integrity in this manner, but is it possible to authenticate without making use of the PKI, perhaps by exploiting the fact that the server can dynamically rewrite the Javascript sent to the client?

There is an issue in your step 2 - Server responds with page containing Javascript code :
how do you know someone sitting on wire is not modifying this Javascript since it is being transferred in plaintext? Basically, when X wants to authenticate Y, X should know something about Y- it could be public information such as public key/certificate or shared secret that it could verify

Related

What does ecxactly http do?

I understand that HTTP is a protocol that allows information to be transferred between a client and a server. At the moment, this protocol is used everywhere: when we're opening needed web page, downloading music, videos, applications...
MDN
HTTP is a protocol for fetching resources such as HTML documents. It is the foundation of any data exchange on the Web and it is a client-server protocol, which means requests are initiated by the recipient, usually the Web browser. A complete document is reconstructed from the different sub-documents fetched, for instance, text, layout description, images, videos, scripts, and more.
But it's not entirely clear to me what exactly HTTP does during this information transfer. If, as I read, a protocol is essentially a set of rules, then does it mean that HTTP just setting up rules for passing information between server and client? If so, what are these rules and what are they for?
Hypertext Transfer Protocol is a communications protocol. It is used to send and receive webpages and files on the internet. It is now coordinated by the W3C. HTTP version 1.1 is the most common used.
HTTP works by using a user agent to connect to a server. The user agent could be a web browser or spider. The server must be located using a URL or URI. This always contains http:// at the start. It normally connects to port 80 on a computer.
A more secure version of HTTP is called HTTPS (Hypertext Transfer Protocol Secure). This contains https:// at the beginning of the URL. It encrypts all the information that is sent and received. This can stop malicious users such as hackers from stealing the information and is often used on payment websites. HTTPS uses port 443 for communication instead of port 80.

How can a third person read the HTTP request headers, if those are transported via HTTP (insecure)?

My question is about networking. I'm just looking for a simple answer, yet I couldn't find one after 1 hour research. I know there are techniques such as Wi-Fi Hotspot, man-in-the-middle-attack, local network, echo switch, etc. But I couldn't find an answer to my specific question.
Let's say, client A wants to communicate with server B, and server B says client A must authenticate himself via HTTP basic authentication first. My question is, what happens if client A sends the authentication credentials via HTTP layer (insecure), who can read the HTTP headers that the client A sends to server B over the internet? Would it be easy to do that? Like placing a breakpoint between two arbitrary routers, which help to transfer the packets across the internet, in order to read those headers? How does it work in general?
Thank you!
PS.: I am not trying to learn and do it. I just want to know, how dangerous it would be, if the HTTP basic auth is made via the insecure HTTP layer.
Who can read the HTTP headers that the client A sends to server B over
the internet?
Your Network Provider (e.g Wi-fi hotspot Provider).
Your Domain Name System server (DNS, as 192.168.1.1).
Your Internet Service Provider (ISP).
Your Virtual Private Network if using one (VPN server).
Yourself Or a Virus.
and here comes the HTTPS (HTTP + SSL Encryption)
SSL is about communicating in a language that you and the server only understand.
How dangerous it would be if the HTTP basic auth is made via the insecure HTTP layer?
Well, from above, You can totally get that a simple virus or even a public Wi-fi Hotspot Device can capture and see all of your data if the communication was done in a plain HTTP Socket.
A Simple packet may contain all of your Device information including its basic contents as your passwords, credit cards information, The HTML form for the signup/login that you've just completed with all its data, VoIP Calls and messages being sent to the server + upcoming/received ones.
that's why we need SSL encryption and the server should have a valid SSL certificate too.
By the way, your device may have sent thousands of packets while you read this now!
Capturing the packets that your device sends or even the packets that other devices on your network send can be done through any packet capturing tool or software as Wireshark.

Canonical handling of HTTPS request when SSL not supported

If a client is requesting a domain that does not have a valid CA signed certificate and the server not intend on supporting HTTPS but does support HTTP for this domain, what is the best way to handle this in the web server. Note, the server does handle requests for SSL (HTTPS) on other domains so it is listening on 443.
Example where this would apply is for multi sub-domains where the sub-domains are dynamically created and thus making it extremely difficult to register CA signed certificates.
I've seen people try to respond with HTTP error codes but these seem moot as the client (browser) will first verify the certificate and will present the hard warning to the user before processing any HTTP. Therefore the client will only see the error code if they "proceed" past the cert warning.
Is there a canonical way of handling this scenario?
There is no canonical way for this scenario. Clients don't automatically downgrade to HTTP if HTTPS is broken and it would be a very bad idea to change clients in this regard - all what an attacker would need to do to attack HTTPS would be to infer with the HTTPS traffic to make a client downgrade to unprotected HTTP traffic.
Thus, you need to make sure that the client either does not try to attempt to access URL's which do not work properly (i.e. don't publish such URL's) or to make sure that you have a working certificate for these subdomains, i.e. adapt the processes for creation of subdomains so that they not only have an IP address but also a valid certificate (maybe use wildcard certificates).
Considering these websites don't have to work with SSL, the webserver should close all SSL connections for them in a proper way.
There is no canonical way for this, but RFC 5246 implicitly suggests to interrupt the handshake on the server side by using the user_cancel + close_notify alerts. How to achieve this is another question, it will be a configuration of the default SSL virtual host.
user_canceled
This handshake is being canceled for some reason unrelated to a
protocol failure. If the user cancels an operation after the
handshake is complete, just closing the connection by sending a
close_notify is more appropriate. This alert should be followed
by a close_notify. This message is generally a warning.
If you are dealing with subdomains, you probably can use a wildcard certificate for all of your subdomains.
Adding the CA certificate to your client will remove the warning (that's what companies do, no worry).
When hosting with Apache, for example, you can use VirtualDocumentRoot to add domains without editing your configuration. Have a look at the solution provided here : Virtual Hosting in SSL with VirtualDocumentRoot

HTTP client acting as a pseudo-server

Let's say I am going to deploy a server application that's likely to be placed behind a NAT/firewall and I don't want to ask users to tweak their NAT port mapping. In other words, connections to the server are impossible, but my app is a server application by nature, i.e. it sends back objects per URI.
Now, I'm thinking about initiating connections from the server periodically to see what requests are there to be responded to. I'm going to use HTTP via port 80 as something that would likely be working through NAT/firewall from virtually anywhere.
The question is, are there any standard considerations and common practices of implementing a client that can act as a server at the application level, specifically using HTTP? Any special HTTP headers? Design patterns?
E.g. I am thinking about the following scheme:
The client (which is my logical server) sends a dummy HTTP request to the server
The server responds back with non-standard headers X-Request-URI:, X-Host:, X-If-Modified-Since: etc, in other words, request headers wrapped into X-xxx as they are not standard in this situation; also requests to keep the connection alive
The client responds with a POST request that sends the requested object; again, uses wrapped headers (e.g. X-Status:, etc)
Unless there is a more "standard" way of doing something like this, do you think my approach is plausible?
Edit: an interesting discussion took place on reddit here
I've done something similar. This is very common. Client initiate the connection to the Server and keep the connection ALIVE. If the session is shut-down, client would re-initiate. When the session is up, Server can push anything to the client since it's client initiated.

stateless protocol and stateful protocol

How to understand stateless protocol and stateful protocol? HTTP is a stateless protocol and FTP is a stateful protocol. For the web applications requiring a lot of interactions, the underlying protocol should be stateful ones. Is my understanding right?
HTTP is a stateless protocol, in other word the server will forget everything related to client/browser state. Although web applications have made it virtually look like stateful.
A stateless protocol can be forced to behave as if it were stateful. This can be accomplished if the server sends the state to the client, and if the client to sends it back again to the server, every time.
There are three ways this may be accomplished in HTTP:
a) One is cookies, in which case the state is sent and returned in HTTP headers.
b) The second is URL extension, in which case the state is sent as part of the URL as request.
c) The third is "hidden form fields", in which the state is sent to the client as part of the response, and returned to the server as part of a form's hidden data
SCALABILITY AND HIGH AVAILABILITY
One of the major reasons why HTTP scales so well is its Statelessness. Stateless protocol eases the replication concerns, as the state itself doesn't need to be stored on the server.
Stateful protocols are logically heavy to implement in Internet reliably. Stateless servers are also easily scalable, while for stateful servers scalablity is problematic. Stateless request can be sent to any node, at any time, while with Stateful this is not a case.
HTTP as Stateless protocol increases availability for stateless web applications, which otherwise would be difficult or impossible to implement. If there is connection lost, there is no state that is lost, simple request resend will resolve the problem. Stateless requests are also cacheable.
see more here
Since you're asking about a Web application, the protocol will always be stateless -- the protocol for the Web is http (or https), and that's all she wrote.
I think what you're thinking of is providing a state mechanism in your Web application itself. The typical approach to this is that you create a unique identifier for the user's session in your Web application (a sessionID of one form or another is the common practice) which is handed back and forth between browser and server. That's typically done in a cookie, though it can be done, with a bit more hassle for you depending on your platform/framework, on the URL as well.
Your server-side code stores stateful information (again, typically called the user's session) however it wants to using the sessionID to look it up. The http traffic simply hands back the sessionID. As long as that identifier is there, each http transaction is completely independent of all others, hence the protocol traffic itself is stateless.
HTTP is a stateless protocol. All the web-based applications are also stateless.
When a request is send to the server, a connection is established between client and server. The server receives the request, processes the request and sends back the response and then, the connection will be closed.
If another request will be sent, after that, it will be treated as a new request and a new connection will be established.
In order to make HTTP stateful, we use session management techniques.
So that, it uses the data coming from previous request while processing present request i.e, it uses the same connection for a series of client server interactions.
The session management techniques are:
hidden form field
cookie
session
URL-rewriting
Anything that forgets whatever it did in past is stateless, such as http
Anything that can keep the history is statefull, such as database
Http is a stateless protocol, that's why it forgets the user information.
We make http as statefull protocol using jsonWebToken(JWT) i.e. on each request going to server, server will first verify the user using JWT.
Your question is spot on, and yes, it would be great if your web transactions with your bank were done over a stateful connection. Alas, HTTP is stateless due to a quirky bug in FTP and a 12 socket limit in the partial socket table in BSD of 1989. Marcus Ranum explained it all here.
So HTTP throws away the state it inherits from TCP and has to recreate state at the application layer in the form of cookies. Crappy internet security is the result.
The Seif project proposes to fix all that using "secure JSON over TCP". DNS and certificate authorities are not required. The protocol and seifnode.js are finished and on github with an MIT license.
HTTP doesn't 'inherit' from TCP, but rather uses it for a transport. HTTP uses TCP for a stateful connection, but then disconnects. Later it will connect again, if needed. So, while you browse through a web site you create many different connections. Each one of those connections is stateful, but the conversation as a whole is not, since you are dropping the connection with every conversation.
From this link
Basically yes, but you have no choice but use HTTP which is where websites are served in. So you have to deal with compromises to make HTTP stateful, aka session management. Possibilities are basically passing on a session id through each call in the URL so you know when you're talking to someone you've talked about before, or via cookies, which achieve the same goal without cluttering the url. However, most modern web development languages take care of that for you; if you google for the language of your choice + "session management" you should get some ideas of how it's done.

Resources