mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-09-02 16:07:15 +00:00
Chore: consolidate pickle hmac signing (#13899)
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import hmac
|
||||
import pickle
|
||||
from hashlib import sha256
|
||||
from typing import Any
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
HMAC_SIZE = sha256().digest_size
|
||||
|
||||
|
||||
class SignedPickleError(ValueError):
|
||||
"""Raised when a signed pickle payload cannot be authenticated."""
|
||||
|
||||
|
||||
def _get_signing_key() -> bytes:
|
||||
return settings.SECRET_KEY.encode()
|
||||
|
||||
|
||||
def signed_pickle_dumps(obj: object) -> bytes:
|
||||
data = pickle.dumps(obj, protocol=pickle.HIGHEST_PROTOCOL)
|
||||
signature = hmac.new(_get_signing_key(), data, sha256).digest()
|
||||
return signature + data
|
||||
|
||||
|
||||
def signed_pickle_loads(payload: bytes) -> Any:
|
||||
if len(payload) <= HMAC_SIZE:
|
||||
msg = "Signed-pickle payload too short"
|
||||
raise SignedPickleError(msg)
|
||||
|
||||
signature = payload[:HMAC_SIZE]
|
||||
data = payload[HMAC_SIZE:]
|
||||
expected = hmac.new(_get_signing_key(), data, sha256).digest()
|
||||
if not hmac.compare_digest(signature, expected):
|
||||
msg = "Signed-pickle HMAC verification failed; payload may have been tampered with"
|
||||
raise SignedPickleError(msg)
|
||||
|
||||
return pickle.loads(data)
|
||||
Reference in New Issue
Block a user