Fix SessionId: use RAND_bytes() instead of SHA1(time) - old IDs were guessable/collidable within the same second
SHA1("JETSESSION" + time(0)) meant two sessions started in the same second got the identical id, and the whole 160-bit value was derivable from a public, second-granularity input - not a real session identifier. Replaced with 20 bytes straight from OpenSSL RAND_bytes(), already linked via -lcrypto. Verified via a real jet-2.0 test: session get/set/persist across separate processes still works via the cookie, and two back-to-back new-session requests now get genuinely different ids.
This commit is contained in:
1 parent
8b2391b289
commit
7f6ebb0ea8
1 file changed
+18
-7
+18
-7
@@ -1,17 +1,28 @@
|
|||||||
#include "SessionId.h"
|
#include "SessionId.h"
|
||||||
#include <openssl/ssl.h>
|
#include "Exception.h"
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
|
||||||
namespace jet {
|
namespace jet {
|
||||||
|
|
||||||
|
// Previously SHA1("JETSESSION" + time(0)) - deterministic and
|
||||||
|
// guessable from the wall-clock second alone (two sessions started in
|
||||||
|
// the same second got the IDENTICAL id, and an attacker doesn't even
|
||||||
|
// need a collision - the whole value is computable from a public,
|
||||||
|
// narrow-range input). Confirmed via a real test: two separate
|
||||||
|
// jet-2.0 runs with no cookie, back to back, produced the same
|
||||||
|
// "fresh" session id. Replaced with 20 bytes straight from OpenSSL's
|
||||||
|
// CSPRNG - RAND_bytes() is already available via libcrypto, which
|
||||||
|
// every jet-2.0/jetc build already links against for other reasons.
|
||||||
SessionId::SessionId() {
|
SessionId::SessionId() {
|
||||||
unsigned char hashit[64];
|
unsigned char randomBytes[20];
|
||||||
unsigned char hash[SHA_DIGEST_LENGTH];
|
if(RAND_bytes(randomBytes, sizeof(randomBytes)) != 1)
|
||||||
|
throw coreutils::Exception("failed to generate a random session id.");
|
||||||
setSize(40);
|
setSize(40);
|
||||||
sprintf((char *)hashit, "JETSESSION%ld", time(0));
|
|
||||||
SHA1(hashit, strlen((char *)hashit), hash);
|
|
||||||
sprintf(getData(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
sprintf(getData(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||||
hash[0], hash[1], hash[2], hash[3], hash[4], hash[5], hash[6], hash[7], hash[8], hash[9],
|
randomBytes[0], randomBytes[1], randomBytes[2], randomBytes[3], randomBytes[4],
|
||||||
hash[10], hash[11], hash[12], hash[13], hash[14], hash[15], hash[16], hash[17], hash[18], hash[19]);
|
randomBytes[5], randomBytes[6], randomBytes[7], randomBytes[8], randomBytes[9],
|
||||||
|
randomBytes[10], randomBytes[11], randomBytes[12], randomBytes[13], randomBytes[14],
|
||||||
|
randomBytes[15], randomBytes[16], randomBytes[17], randomBytes[18], randomBytes[19]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user