MCPcopy Index your code
hub / github.com/pgadmin-org/pgadmin4 / get

Method get

web/pgadmin/utils/session.py:327–399  ·  view source on GitHub ↗

Retrieve a managed session by session-id, verifying integrity and decrypting the body. File format: +-------------------------------------------------------+ | _HMAC_HEX_LEN bytes : hex HMAC over the ciphertext | +-------------------------------

(self, sid, digest)

Source from the content-addressed store, hash-verified

325 return ManagedSession(sid=sid)
326
327 def get(self, sid, digest):
328 """Retrieve a managed session by session-id, verifying integrity
329 and decrypting the body.
330
331 File format:
332 +-------------------------------------------------------+
333 | _HMAC_HEX_LEN bytes : hex HMAC over the ciphertext |
334 +-------------------------------------------------------+
335 | N bytes : Fernet(pickle((randval, digest, data))) |
336 +-------------------------------------------------------+
337
338 The HMAC is verified against the ciphertext BEFORE Fernet decrypt
339 and BEFORE pickle.loads, so a malicious file dropped in the
340 sessions directory cannot trigger arbitrary code execution via
341 __reduce__ during deserialization (encrypt-then-MAC; pickle.loads
342 only ever sees Fernet-decrypted plaintext from a server-written
343 file).
344 """
345 fname = safe_join(self.path, sid)
346 if fname is None or not os.path.exists(fname):
347 return self.new_session()
348
349 try:
350 with open(fname, 'rb') as f:
351 header = f.read(_HMAC_HEX_LEN)
352 body = f.read()
353 if len(header) != _HMAC_HEX_LEN or len(body) == 0:
354 # 0-byte placeholder from new_session(), or pre-fix legacy
355 # file shorter than the header. Silently invalidate; one-time
356 # re-login on upgrade is acceptable and expected.
357 return self.new_session()
358 expected = _compute_file_hmac(self.secret, body)
359 if not hmac.compare_digest(header, expected):
360 logger.warning(
361 "session file rejected: bad file-HMAC for sid=%s",
362 sid[:8] if sid else '<empty>',
363 )
364 return self.new_session()
365 # Body integrity verified — decrypt before deserializing.
366 try:
367 plaintext = _derive_session_fernet(
368 self.secret).decrypt(body)
369 except InvalidToken:
370 # Pre-Layer-1 (HMAC-only) session files: HMAC is still a
371 # valid HMAC over the legacy plain-pickle body, but
372 # Fernet.decrypt on raw pickle bytes raises InvalidToken.
373 # Silently invalidate; users see a one-time re-login on
374 # the upgrade that introduced this layer.
375 logger.warning(
376 "session file rejected: legacy unencrypted body for "
377 "sid=%s", sid[:8] if sid else '<empty>',
378 )
379 return self.new_session()
380 randval, hmac_digest, data = pickle.loads(plaintext)
381 except (pickle.UnpicklingError, EOFError, OSError, MemoryError,
382 ValueError, TypeError):
383 # Narrow catch: silently invalidate corrupted/unreadable files.
384 # Programming errors (AttributeError, NameError, etc.) propagate

Callers 1

runTestMethod · 0.95

Calls 6

new_sessionMethod · 0.95
_compute_file_hmacFunction · 0.85
_derive_session_fernetFunction · 0.85
ManagedSessionClass · 0.85
warningMethod · 0.80
existsMethod · 0.45

Tested by 1

runTestMethod · 0.76