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.
29 lines
1.4 KiB
C++
29 lines
1.4 KiB
C++
#include "SessionId.h"
|
|
#include "Exception.h"
|
|
#include <openssl/rand.h>
|
|
|
|
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() {
|
|
unsigned char randomBytes[20];
|
|
if(RAND_bytes(randomBytes, sizeof(randomBytes)) != 1)
|
|
throw coreutils::Exception("failed to generate a random session id.");
|
|
setSize(40);
|
|
sprintf(getData(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
|
randomBytes[0], randomBytes[1], randomBytes[2], randomBytes[3], randomBytes[4],
|
|
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]);
|
|
}
|
|
|
|
}
|