What is the session's "secret" option?
I don't know anything about cryptography. I'm wondering what the session secret is.
I see code like this:
app.use(express.session({
store: mongoStore({
url: app.set('db-uri')
}),
secret: 'topsecret'
}));
What is the开发者_运维知识库 secret and should I change it?
Yes, you should change it. A session secret in connect is simply used to compute the hash. Without the string, access to the session would essentially be "denied". Take a look at the connect docs, that should help a little bit.
The secret is used to hash the session with HMAC:
https://github.com/senchalabs/connect/blob/master/lib/middleware/session.js#L256
The session is then protected against session hijacking by checking the fingerprint against the hash with the secret:
https://github.com/senchalabs/connect/blob/master/lib/middleware/session.js#L281-L287
Motivation for this answer
The other answers address "Should I change it?" and provide a surface-level explanation on "What is it?" As someone who just started using express-session
, I was curious and in my reading found much disagreement over whether having a secret like this is valuable and how much.
Many people discussing this topic seem to be security novices like myself. However, I came across this answer with a comprehensive explanation of the intended effect of the secret and some of the possibilities. You should read the whole answer, but I will try to summarize.
What does the secret protect against?
The type of attack in question here is session hijacking. Typically, this involves the attacker acquiring the session ID of a valid user, thereby being able to emulate that user's session and allowing the attacker to access information or act on the victim's behalf.
How can you protect against session hijacking?
A good start is to use a session ID that is suffienciently long and random, as it inhibits an attacker's ability to guess the ID. As noted by the other answer's author:
It is also critical that session ids are not generated using a predictable algorithm such as a counter because if such logic exists, the attacker is no longer guessing but generating session ids.
As an example: if an attacker finds out that your session IDs are sequential (e.g. 1, 2, 3), then if they discover a session ID of 2 then they can reasonably assume 1 and 3 are session IDs as well.
What does express-session
's secret do?
The Express session middleware...calculates a hash over the combination of the session id and a secret. Since calculating the hash requires possession of the secret, an attacker will not be able to generate valid session ids without guessing the secret (or just trying to guess the hash).
So the secret is used to create a hash that is long and random. If the session ID is already sufficiently long and random, then using a secret in this manner is largely redundant. As other users have pointed out, at the end of the day, the attacker is just guessing one long and random instead of another.
But don't be so quick to dismiss the use of hashing!
express-session
is a public package
An important feature of the Express session middleware is its support for user-generated session ids. This allows developer to deploy the middleware in an existing environment where session ids are generated by an existing entity which might reside on a completely different platform. Without adding a hash to the user-provided session ids, the burden of building a secure system moves from the expert (the module author) to the user (which is likely to be a security novice). Applying a hash is a much better approach than forcing an internal session id generator.
If an inexperienced user instead defines their own insecure session ID generator (e.g. say, something sequential as discussed above), hashing it will ameliorate that security flaw.
As the author notes elsewhere:
Also, this is a generic module assuming as it's core requirement a wide range of users. It absolutely has to assume that some people will use it poorly (e.g. increment ids) and accommodate that. This is also common practice when building modules for a wide audience.
Don't put all your eggs in one basket
Hashing using a secret is one layer of security, and can help cover flaws in other layers. What if your random session ID generator has a bug that can be exploited? What if you accidentally use RNG.pseudoRandomNumber()
instead of RNG.strongRandomNumber()
when coding? What if one of your dependencies breaks or is compromised? Once again, hashing helps patch those flaws.
There are other benefits
You can detect the difference between expired/unallocated IDs and invalid (maliciously generated) IDs:
By including an integrity component in the session id (via a hash or signature), the server can immediately tell the difference between an expired session, an unallocated session id, and an invalid session. Even if you just log invalid authentication attempts (and you should), you would want to log an expired session differently than an invalid one.
You can build a tamper-resistant timestamp into the ID:
While cookies come with an expiration policy, there is no way to ensure it is actually obeyed. (...) A common best practice is to include a timestamp in every credential issued, which can be as simple as adding a timestamp suffix to the randomly generate session id. However, in order to rely on this timestamp, we must be able to verify it was not tempered with and the way to accomplish that is with a hash or signature. (...) Adding a timestamp to the session id allows the server to quickly handle expired sessions without having to make an expensive database lookup.
You can immediately invalidate many IDs if something goes wrong:
Because generating a hash or signature requires a server-side secret or key, replacing the secret will immediately cause all session ids to fail validation. By using different secrets for different types of session ids, entire classes of sessions can be segregated and managed. Without such a mechanism, the application itself has to make a computed decision about the state of each session or perform mass database updates.
In Conclusion
The having a secret (and using it to hash) provides many benefits:
- It protects users from themselves
- It adds an extra layer of defense
- (With a custom session ID generator) It allows detecting malicious behavior
- (With a custom session ID generator) It allows bundling a timestamp into the ID
- It provides a kill switch
And once again, I would like to credit this answer for everything in this post. I am just a curious onlooker!
精彩评论