Skip to content

Commit d72c660

Browse files
refactor: add hmac_signed_serializer for celery.
1 parent ab87d11 commit d72c660

File tree

3 files changed

+44
-4
lines changed

3 files changed

+44
-4
lines changed

apps/maxkb/settings/lib.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,9 @@
7171
CELERY_result_backend = CELERY_BROKER_URL
7272
CELERY_timezone = CONFIG.get_time_zone()
7373
CELERY_ENABLE_UTC = False
74-
CELERY_task_serializer = 'pickle'
75-
CELERY_result_serializer = 'pickle'
76-
CELERY_accept_content = ['json', 'pickle']
74+
CELERY_task_serializer = 'hmac_signed_serializer'
75+
CELERY_result_serializer = 'hmac_signed_serializer'
76+
CELERY_accept_content = ['json', 'hmac_signed_serializer']
7777
CELERY_RESULT_EXPIRES = 600
7878
CELERY_WORKER_TASK_LOG_FORMAT = '%(asctime).19s %(message)s'
7979
CELERY_WORKER_LOG_FORMAT = '%(asctime).19s %(message)s'

apps/ops/celery/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
33
import os
44

55
from celery import Celery
6-
from celery.schedules import crontab
76
from kombu import Exchange, Queue
87
from maxkb import settings
98
from .heartbeat import *
9+
from .hmac_signed_serializer import register_hmac_signed_serializer
1010

1111
# set the default Django settings module for the 'celery' program.
1212
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'maxkb.settings')
1313

14+
register_hmac_signed_serializer()
15+
1416
app = Celery('MaxKB')
1517

1618
configs = {k: v for k, v in settings.__dict__.items() if k.startswith('CELERY')}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import hmac
2+
import hashlib
3+
import pickle
4+
import os
5+
import socket
6+
from kombu.serialization import register
7+
8+
_local_secret_key = os.environ.get('MAXKB_HMAC_SIGNED_SERIALIZER_SECRET_KEY', 'default_hmac_signed_serializer_secret_key:' + os.getenv('MAXKB_VERSION', socket.gethostname()))
9+
try:
10+
from xpack import get_md5
11+
_local_secret_key = get_md5()
12+
except ImportError:
13+
pass
14+
15+
def secure_dumps(obj):
16+
data = pickle.dumps(obj)
17+
signature = hmac.new(_local_secret_key.encode(), data, hashlib.sha256).digest()
18+
return signature + data
19+
20+
def secure_loads(signed_data):
21+
if len(signed_data) < 32:
22+
raise ValueError("Invalid signed data packet")
23+
signature = signed_data[:32]
24+
payload = signed_data[32:]
25+
expected_signature = hmac.new(_local_secret_key.encode(), payload, hashlib.sha256).digest()
26+
if hmac.compare_digest(signature, expected_signature):
27+
return pickle.loads(payload)
28+
else:
29+
raise ValueError("Security Alert: Task signature mismatch! Potential tampering detected.")
30+
31+
def register_hmac_signed_serializer():
32+
register(
33+
'hmac_signed_serializer',
34+
secure_dumps,
35+
secure_loads,
36+
content_type='application/x-spickle',
37+
content_encoding='binary'
38+
)

0 commit comments

Comments
 (0)