How is Session ID sent to Browser - session

Im learning Session Management and i have two questions for which i could not find answers on the web.
Once the user is authenticated, the Server creates the Session ID and sends it the client (user) in the form of a cookie. This cookie is then subsequently used in request the client sends to the server to identify himself among other users.
Now in HTTPS session, the requests sent between the client and server is secured, as requests from client are encrypted using the Public key and it can only be encrypted using the Private key which the server only has.
But initially when the server sends the cookie information to the client, it could be intercepted by anyone as even if this cookie which contais the session ID is encrypted using the Private key, it could be decrypted by anyone having the Public key. So, my question is :
1) how does the server make sure that the session ID created by the server is securely sent to the client.
2) I learnt the client sends the cookie for each request it makes to the server. In GET request, how does the client send the cookie information as GET does not include the body .

When HTTPS is used a secure connection is established before any HTTP requests are actually sent.
Transport Layer Security (TLS) and its predecessor SSL are not built on top of HTTP, but the other way around. They are one or two layers below HTTP in the OSI model. HTTP doesn't care whether the connection that it uses is encrypted or not. The browser just requests resources and sends header information such as cookies along with it.
You can check this yourself. Run a capture software like wireshark and look how the connection is established for a website using HTTP and HTTPS.

Related

How to set a different session cookie name for every connector?

Currently I set the session cookie name in an embedded Jetty via the follow code:
ServletContextHandler handler = new ServletContextHandler( ServletContextHandler.SESSIONS );
handler.setInitParameter( SessionHandler.__SessionCookieProperty, "SESSIONID" + port );
setHandler( handler );
But then all connectors use the same session cookie name. But I want different session cookie names on different connectors.
The cause of my problem is that
I have HTTP and HTTPS connectors
for a HTTPS connection a secure session cookie is send
It is not possible to override a secure cookie with an HTTP connection in the most browsers.
After a secure cookie from a HTTPS connection it is not possible to work on a HTTP connection anymore until all browser tabs are closed. Some peoples does not close it for weeks. The server send repeatedly new session cookies but the browser does not save it.
I can restart the server, remove the HTTPS connector. All will not work until a browser restart.
A simple fix would be to set different session cookies for different ports or for different protocols. Is this possible for with Jetty?

No persistent session when connecting to API on different host

I am sending a websocket connection to the API server on a different host:
new WebSocket("ws://localhost:3000")
Whereas my front end is hosted on localhost:8080.
Inside my API's websocket connection handler I'm able to set a key on the session (with Sinatra's enable :sessions) but every time I refresh the html page, the data is lost.
Is there some requirement for sessions that the front end share the same host as the server? Or is there some way I can get around this? By the way, the front end is running on a Webpack server (Node).
I also tried adding a cross_origin allowance for the API's root route http://localhost:3000 and then doing this in the client (this example in coffeescript):
$.get "http://localhost:3000", ->
new Websocket("ws://localhost:3000")
My thinking was that maybe the session needed to be "initialized" over http:// instead of ws:// but it didn't work either. The session didn't work for the $.get "http://localhost:3000" request either. Refreshing the page shows that the session clears each time.
As we've discussed in comments, you probably have a problem with 3rd party session cookies in the browser.
Here's a scheme that you could use to work around it.
Client makes webSocket connection for the first time.
Server sends a webSocket message back with sessionID in it.
Client stores sessionID in a first party cookie (e.g. a cookie in the host web page).
User hits refresh.
Web page checks to see if it has a webSocket session cookie in the cookies for the host page. If so, it constructs a URL for the webSocket connection that includes that session ID `new Websocket("ws://localhost:3000?session=xyslkfas")
When server accepts webSocket connection, it checks the query parameters to see if there is already a session being specified. If so and that session is still valid, it hooks up that connection to that session. If not, it creates a new session and goes back to step 2.

Session Persistence in Nginx for load balancing

In Nginx, there are three methods regarding session persistence: sticky cookie, sticky route and cookie learn.
Below is a brief explanation about how cookie learn method works, which extracted from Nginx Load Balance:
The cookie learn method. With this method, NGINX Plus first finds
session identifiers by inspecting requests and responses. Then NGINX
Plus “learns” which upstream server corresponds to which session
identifier. Generally, these identifiers are passed in a HTTP cookie.
If a request contains a session identifier already “learned”, NGINX
Plus will forward the request to the corresponding server.
My question is that what if two upstream server generated the same session_id, then how does the prxoy server know which upstream server it should send the request?

What is the difference between cookie and cookiejar?

Today I faced the term "cookiejar" (package net/http/cookiejar). I tried to gather some information regarding it, but got nothing intelligible came out. I know that cookie is key/value pairs that server sends to a client, eg: Set-Cookie: foo=10, browser stores it locally and then each subsequent request browser will send these cookies back to the server, eg: Cookie: foo=10.
Ok, but what about cookiejar? What is it and how does it look like?
As you described in your question, cookies are managed by browsers (HTTP clients) and they allow to store information on the clients' computers which are sent automatically by the browser on subsequent requests.
If your application acts as a client (you connect to remote HTTP servers using the net/http package), then there is no browser which would handle / manage the cookies. By this I mean storing/remembering cookies that arrive as Set-Cookie: response headers, and attaching them to subsequent outgoing requests being made to the same host/domain. Also cookies have expiration date which you would also have to check before deciding to include them in outgoing requests.
The http.Client type however allows you to set a value of type http.CookieJar, and if you do so, you will have automatic cookie management which otherwise would not exist or you would have to do it yourself. This enables you to do multiple requests with the net/http package that the server will see as part of the same session just as if they were made by a real browser, as often HTTP sessions (the session ids) are maintained using cookies.
The package net/http/cookiejar is a CookieJar implementation which you can use out of the box. Note that this implementation is in-memory only which means if you restart your application, the cookies will be lost.
So basically an HTTP cookie is a small piece of data sent from a website and stored in a user's web browser while the user is browsing that website.
Cookiejar is a Go interface of a simple cookie manager (to manage cookies from HTTP request and response headers) and an implementation of that interface.
In general it is a datastore where an application (browser or not) puts the cookies it uses during requests and responses. So it is really a jar for cookies.

Ensure WebSockets only connecting from known domain

How can I make sure only a script hosted on a specific list of domains is allowed to connect to my WebSocket application?
Or to prevent opinion based closevotes, is there a state-of-the-art or native way?
I do not intend to implement user authentication.
The mechanism for this with WebSocket is the origin header.
This HTTP header is set by browsers to the domain of the host that served the HTML that contained the JavaScript which opened the WebSocket connection.
A WebSocket server can inspect the origin header during the initial opening handshake of the WebSocket protocol. The server can then only allow proceeding of the connection if the origin matches a known whitelist.
The header cannot be modified from JavaScript, and all browsers are required by the RFC6455 specification to include it.
Caution: a non-browser WebSocket client can of course fake the origin header to any value it likes.
#oberstet gave you the right answer.
If you are worried about bots or programmatic HTTP agents, then you are going to have a bad time. Everything in a HTTP request can be spoofed. Your only option is to use cookies to attach a token with limited time validity that certify the user went through an allowed website to get that script. Get that cookie in the WebSocket handshake and decide if you allow it or not.
E.g.: When a user visit your site, or one of your sites, return a cookie with a symmetrically encrypted token based on the user IP address, User-Agent header, and Origin header; when the user initiates a WebSocket connection, if it is in the same 2nd domain, it will send the cookie, then if the data adds up allow the connection, otherwise, reject it. If the WS is in another domain, then you will have to forget about cookies and rely on a web socket message once the connection is established to check the validity of the connection.

Resources