With a session store on the server, what does session secret do? - session

I understand if one saves sessions to cookies, you need to encrypt them with a secret else malicious clients could modify their session at will. This design is still bad for many reasons popularly discussed.
However, if one saves sessions on the server (I happen to use a Memcache store via Rack:Session:Dalli) , I understand all the client gets is a cookie with a key the server uses to lookup their session from the store. I still set a session secret. But I don't understand what it does anymore.

Encrypting a large random number results in essentially another large random number. In other words, if there is no meaning ascribed to the information (its just a random number), then there is no security benefit to encryption. If the ID you're storing has some information embedded in it, like a certain bit set or only a certain subset of IDs are used, then encryption is useful.
The length of the session ID is important. Obviously, the longer the ID, the more resistant it is to brute forcing. The expected number of simultaneous user sessions is also a factor, as the number of sessions reduces the number of brute force attempts needed to find a valid session ID. For example, two simultaneous sessions reduces the effective strength of the ID by one bit (a 128 bit key becomes as effective as a 127 bit key would be with one session only). An Amazon-scale website with (say) 1,000,000 simultaneous sessions would effectively lose 20 bits of its session key strength.
If you need to defend against brute force attacks, implement a middleware to check for that. Adding information to the session id, like an application-unique string, can make detecting a brute-force attack easier (and requires session id encryption). Note that this does not enhance the security of the key itself, and is basically wasted effort unless the app takes some action when presented with an improper session id.
Whatever you do, just make sure to use SSL and set the cookie to https only. Time out the session server-side, and don't rely on cookie expiration and the good will of the client browser.
TL;DR: If only using cookies for session ID storage, encryption is not necessary if a good RNG is used. Use SSL and set the cookie secure attribute.

Related

How can I send a secret to a server, and validate it, without risking bruteforcing of the hash?

I want to send a secret to a server, say the domain the current browser is visiting, but I don't want the server to know what the website address is, only if the server has a matching record for this specific domain.
I was thinking of simply hashing the domain-name on the client, and using then comparing hashes on the server, but in my late night of thinking, so to say, I can't think of a way to prevent the server from using the same hashing algorithm to "reverse" or "brute force" it's way to the answer.
So say the server was compromised, it has a hashed value + an identifier such as an IP. Now it could simply brute force all the dirties websites in the world, to see what website would return the same hash.
I was thinking of SRP (Secure Remote Password) -- not sure if that would make any real difference in this case.
Good night.

Does EX second impact performance in Redis?

I tried googling something similar , but wasn't habel to find something on the topic
I'm just curious, does it matter how big the number of seconds are set in a key impact performance in redis?
For example:
set mykey "foobarValue" EX 100 VS set mykey "foobarValue" EX 2592000
To answer this question, we need to see how Redis works.
Redis maintains tables of a key, value pair with an expiry time, so each entry can be translated to
<Key: <Value, Expiry> >
There can be other metadata associated with this as well. During GET, SET, DEL, EXPIRE etc operations Redis calculates the hash of the given key(s) and tries to perform the operation. Since it's a hash table, it needs to prob during any operation, while probing it may encounter some expired keys. If you have subscribed for "Keyspace notification" then notification would be sent and the given entry is removed/updated based on the operation being performed. It also does rehashing, during rehashing it might find expired keys as well. Redis also runs background tasks to cleanup expire keys, that means if TTL is too small then more keys would be expired, as this process is random, so more event would be generated.
https://github.com/antirez/redis/blob/a92921da135e38eedd89138e15fe9fd1ffdd9b48/src/expire.c#L98
It does have a small performance issue when TTL is small since it needs to free the memory and fix some pointers. But it can so happen that you're running out of memory since expired keys are also present in the database. Similarly, if you use higher expiry time then the given key would present in the system for a longer time, that can create memory issue.
Setting smaller TTL has also more cache miss for the client application, so client will have performance issues as well.

Password security in sessions

Instead of stroing plain text passwords, we use a strong hashing function with high computation cost and random salt to thwart rainbow attacks etc.
But when a user is in a session, typically his or her username is stored along with a hash of their password as a cookie to authenticate the sesssion. If the user's browser cookie space is compromised, doesn't an attacker obtain an easier target of cracking the username+ session hash, instead of username + pass hash?
In Django for example, passwords are hashed with PBKDF2 or bcrypt, but session hashes use a less complex HMAC and no random salt. Is this a security issue? If yes, what is the right way to handle sessions?
For each session, I suggest to use dedicated SessionID - random long 128bit value. And, keep session key as:
username:SessionID:hash
where
hash = sha1(SessionID|username|client_IP|secret_server_side_password);
Every time, when you receive cookie, you need again compute hash, and compare with received one.
As result, this cookie is useless after session is closed (mismatch SessionID).
Moreover, if cookie will be stolen from active session, server can
figure out attack with stolen cookie from another computer, because of client_IP from real client will be different to actual client_IP.
Of course, if ClientIP is changed, session automatically will be disconnected.
Alternative - using authentication system, based on client's
SSL certificates, for example - emcSSL.

Using `Rack::Session::Pool` over `Rack::Session::Cookie`

What are the different use cases of Rack::Session::Pool and Rack::Session::Cookie?
As far as I understand (correct me if I'm wrong):
Cookie stores all the session key:value pairs directly within the cookie (marshalled)
Pool only stores an id in the cookie, and maintains the rest of the session hash within #pool
So: what are the implications/reasons for choosing one over the other? what's #pool? Why does Pool need to expose a different public interface from Cookie? Why is the documentation so lacking?
You are right, Session::Cookie marshaling and store sessions in cookies.
Session::Pool instead keeps sessions in memory.
Pool has some advantages:
- faster, no marshaling needed
- you can keep any objects with it(read ones that can not be marshaled)
But when you restart your app all sessions are lost.
With Cookie instead you will have restart-persistent sessions at the price of marshaling.
Alternatives - Session::Memcache, Session::Mongo

PHP Hackers and the POST array

I was told that it was easy but people to view the contents inside the $_POST[] array, is it really that easy? How do hackers do this and how do I prevent it? Should I start storing more items in the SESSION[] array instead?
POST[]ing Extra Values
The POST array is populated entirely by data transmitted from the client and everything inside it should be suspect. So don't take a number out of a postback request and set someone's account balance to it.
Also, "POST" is just a type of HTTP request, which means it's sent in plain text. Don't ask clients to send you login passwords over POST unless you wrap the HTTP stream with SSL (use https:// and configure your webserver properly) because you don't control the network between the client and your server. Major websites often don't do this (for performance reasons) but all online banks have done this for at least 10 years.
Think that POST data are sended from the browser with the HTTP request in plain text.
People that can snif your network or execute a Man in the Midle hack, can view this.
With a firefox extension like Tamper Data, the user can change the POST data before sending it to the server.
Never thrust POST data, always validate it in the server side.
From my comment on your earlier question:
A hacker can see the fields and values that are submitted through your form using easily available software tools, and then re POST them as he/she wishes.
Regarding MD5:
md5 isn't an encryption algorithm, it's a hashing algorithm. It'll turn any string into a 16-byte hash. In theory:
If you have two objects, a and b, and md5(a) == md5(b), then a == b
If you have md5(a) you can't figure out a.
These are the implicit assumptions when working with hashes, although they're never actually true - number one is clearly not true because if you hash 2^16 + 1 different strings then by the Pigeonhole Principle there must be two different strings with the same hash. The second one is also obviously not true because an attacker can search the range of md5 values for the hash, although for modern cryptographic-secure hashes (not md5) this is infeasible.
Getting to your question, you could just ask the client for the md5 hash of the user's password (you'd need client side javascript to calculate this) but that's a terrible idea. If all you expect from the user is the md5 of her password, then that's all an attacker needs to know, and you're sending it in plain text. What you could do is send the client a nonce. This is like a challenge. For the client to prove she knows her password, she can send you a hash of the nonce and her password concatenated. The idea is that any attacker can't answer the challenge becuase he only knows the nonce, and after the nonce-password hash is transmitted it's too late for him because you've already received it and aren't expecting an answer to that nonce again. Property 2 ensures that he can't extract the password from the hash.
This is vulnerable to the attacker stealing the challenge response and getting it to you before the client does. You can have a lot of fun making up a whole cryptosystem with multi-round communication (counter-intuitively it's actually possible to send hashes back and forth and securely authenticate) but soon you're just implementing HTTPS which someone else has already done for you :)

Resources