Browse Source

Adds setting CELERY_ACCEPT_CONTENT: A whitelist of serializers/content-types to accept

Ask Solem 12 years ago
parent
commit
4c682b570d

+ 6 - 2
celery/app/amqp.py

@@ -300,11 +300,15 @@ class TaskPublisher(TaskProducer):
 class TaskConsumer(Consumer):
 class TaskConsumer(Consumer):
     app = None
     app = None
 
 
-    def __init__(self, channel, queues=None, app=None, **kw):
+    def __init__(self, channel, queues=None, app=None, accept=None, **kw):
         self.app = app or self.app
         self.app = app or self.app
+        if accept is None:
+            accept = self.app.conf.CELERY_ACCEPT_CONTENT
         super(TaskConsumer, self).__init__(
         super(TaskConsumer, self).__init__(
             channel,
             channel,
-            queues or self.app.amqp.queues.consume_from.values(), **kw
+            queues or self.app.amqp.queues.consume_from.values(),
+            accept=accept,
+            **kw
         )
         )
 
 
 
 

+ 2 - 1
celery/app/control.py

@@ -92,7 +92,8 @@ class Control(object):
 
 
     def __init__(self, app=None):
     def __init__(self, app=None):
         self.app = app_or_default(app)
         self.app = app_or_default(app)
-        self.mailbox = self.Mailbox('celery', type='fanout')
+        self.mailbox = self.Mailbox('celery', type='fanout',
+                                    accept=self.app.conf.CELERY_ACCEPT_CONTENT)
 
 
     @cached_property
     @cached_property
     def inspect(self):
     def inspect(self):

+ 1 - 0
celery/app/defaults.py

@@ -90,6 +90,7 @@ NAMESPACES = {
         'WRITE_CONSISTENCY': Option(type='string'),
         'WRITE_CONSISTENCY': Option(type='string'),
     },
     },
     'CELERY': {
     'CELERY': {
+        'ACCEPT_CONTENT': Option(None, type='any'),
         'ACKS_LATE': Option(False, type='bool'),
         'ACKS_LATE': Option(False, type='bool'),
         'ALWAYS_EAGER': Option(False, type='bool'),
         'ALWAYS_EAGER': Option(False, type='bool'),
         'AMQP_TASK_RESULT_EXPIRES': Option(
         'AMQP_TASK_RESULT_EXPIRES': Option(

+ 2 - 1
celery/events/__init__.py

@@ -211,7 +211,8 @@ class EventReceiver(object):
     def consumer(self, wakeup=True):
     def consumer(self, wakeup=True):
         """Create event consumer."""
         """Create event consumer."""
         consumer = Consumer(self.connection,
         consumer = Consumer(self.connection,
-                            queues=[self.queue], no_ack=True)
+                            queues=[self.queue], no_ack=True,
+                            accept=['application/json'])
         consumer.register_callback(self._receive)
         consumer.register_callback(self._receive)
         consumer.consume()
         consumer.consume()
 
 

+ 22 - 0
docs/configuration.rst

@@ -790,6 +790,28 @@ persistent messages.
 Broker Settings
 Broker Settings
 ---------------
 ---------------
 
 
+.. setting:: CELERY_ACCEPT_CONTENT
+
+CELERY_ACCEPT_CONTENT
+~~~~~~~~~~~~~~~~~~~~~
+
+A whitelist of content-types/serializers to allow.
+
+If a message is received that is not in this list then
+the message will be discarded with an error.
+
+By default any content type is enabled (including pickle and yaml)
+so make sure untrusted parties do not have access to your broker.
+See :ref:`guide-security` for more.
+
+Example::
+
+    # using serializer name
+    CELERY_ACCEPT_CONTENT = ['json']
+
+    # or the actual content-type (MIME)
+    CELERY_ACCEPT_CONTENT = ['application/json']
+
 .. setting:: BROKER_TRANSPORT
 .. setting:: BROKER_TRANSPORT
 
 
 BROKER_TRANSPORT
 BROKER_TRANSPORT

+ 17 - 1
docs/userguide/security.rst

@@ -100,7 +100,23 @@ unauthenticated.
 
 
 .. [*] http://nadiana.com/python-pickle-insecure
 .. [*] http://nadiana.com/python-pickle-insecure
 
 
-Celery comes with a special `auth` serializer that validates
+You can disable untrusted content by specifying
+a whitelist of accepted content-types in the :setting:`CELERY_ACCEPT_CONTENT`
+setting:
+
+.. code-block:: python
+
+    CELERY_ACCEPT_CONTENT = ['json']
+
+
+This accepts a list of serializer names and content-types, so you could
+also specify the content type for json:
+
+.. code-block:: python
+
+    CELERY_ACCEPT_CONTENT = ['application/json']
+
+Celery also comes with a special `auth` serializer that validates
 communication between Celery clients and workers, making sure
 communication between Celery clients and workers, making sure
 that messages originates from trusted sources.
 that messages originates from trusted sources.
 Using `Public-key cryptography` the `auth` serializer can verify the
 Using `Public-key cryptography` the `auth` serializer can verify the