mirror of https://github.com/celery/kombu.git
Improve docs about pickle serailization and disabled by defaualt
This commit is contained in:
parent
df1438c18f
commit
493da61205
52
Changelog
52
Changelog
|
@ -18,11 +18,57 @@
|
||||||
|
|
||||||
- pickle, yaml and msgpack deserialization is now disabled by default.
|
- pickle, yaml and msgpack deserialization is now disabled by default.
|
||||||
|
|
||||||
To enable insecure serializers you have to call:
|
This means that Kombu will by default refuse to handle any content type other
|
||||||
|
than json.
|
||||||
|
|
||||||
|
Pickle is known to be a security concern as it will happily
|
||||||
|
load any object that is embedded in a pickle payload, and payloads
|
||||||
|
can be crafted to do almost anything you want. The default
|
||||||
|
serializer in Kombu is json but it also supports a number
|
||||||
|
of other serialization formats that it will evaluate if received:
|
||||||
|
including pickle.
|
||||||
|
|
||||||
|
It was always assumed that users were educated about the security
|
||||||
|
implications of pickle, but in hindsight we don't think users
|
||||||
|
should be expected to secure their services if we have the ability to
|
||||||
|
be secure by default.
|
||||||
|
|
||||||
|
By disabling any content type that the user did not explicitly
|
||||||
|
want enabled we ensure that the user must be conscious when they
|
||||||
|
add pickle as a serialization format to support.
|
||||||
|
|
||||||
|
The other built-in serializers (yaml and msgpack) are also disabled
|
||||||
|
even though they aren't considered insecure [#f1]_ at this point.
|
||||||
|
Instead they're disabled so that if a security flaw is found in one of these
|
||||||
|
libraries in the future, you will only be affected if you have
|
||||||
|
explicitly enabled them.
|
||||||
|
|
||||||
|
To have your consumer accept formats other than json you have to
|
||||||
|
explicitly add the wanted formats to a white-list of accepted
|
||||||
|
content types::
|
||||||
|
|
||||||
|
>>> c = Consumer(conn, accept=['json', 'pickle', 'msgpack'])
|
||||||
|
|
||||||
|
or when using synchronous access::
|
||||||
|
|
||||||
|
>>> msg = queue.get(accept=['json', 'pickle', 'msgpack'])
|
||||||
|
|
||||||
|
The ``accept`` argument was first supported for consumers in version
|
||||||
|
2.5.10, and first supported by ``Queue.get`` in version 2.5.15
|
||||||
|
so to stay compatible with previous versions you can enable
|
||||||
|
the previous behavior:
|
||||||
|
|
||||||
>>> from kombu import enable_insecure_serializers
|
>>> from kombu import enable_insecure_serializers
|
||||||
>>> enable_insecure_serializers()
|
>>> enable_insecure_serializers()
|
||||||
|
|
||||||
|
But note that this has global effect, so be very careful should you use it.
|
||||||
|
|
||||||
|
.. rubric:: Footnotes
|
||||||
|
|
||||||
|
.. [#f1] The PyYAML library has a :func:`yaml.load` function with some of the
|
||||||
|
same security implications as pickle, but Kombu uses the
|
||||||
|
:func:`yaml.safe_load` function which is not known to be affected.
|
||||||
|
|
||||||
- kombu.async: Experimental event loop implementation.
|
- kombu.async: Experimental event loop implementation.
|
||||||
|
|
||||||
This code was previously in Celery but was moved here
|
This code was previously in Celery but was moved here
|
||||||
|
@ -38,7 +84,7 @@
|
||||||
Contributed by Mark Lavin.
|
Contributed by Mark Lavin.
|
||||||
|
|
||||||
- ``StdConnectionError`` and ``StdChannelError`` is removed
|
- ``StdConnectionError`` and ``StdChannelError`` is removed
|
||||||
and ``:exc:`amqp.ConnectionError` and :exc:`amqp.ChannelError` is used
|
and :exc:`amqp.ConnectionError` and :exc:`amqp.ChannelError` is used
|
||||||
instead.
|
instead.
|
||||||
|
|
||||||
- Message object implementation has moved to :class:`kombu.message.Message`.
|
- Message object implementation has moved to :class:`kombu.message.Message`.
|
||||||
|
@ -92,7 +138,7 @@
|
||||||
|
|
||||||
Contributed by Kevin McDonald
|
Contributed by Kevin McDonald
|
||||||
|
|
||||||
.. _`SoftLayer MQ`_: http://www.softlayer.com/services/additional/message-queue
|
.. _`SoftLayer MQ`: http://www.softlayer.com/services/additional/message-queue
|
||||||
|
|
||||||
- Eventio: Kqueue breaks in subtle ways so select is now used instead.
|
- Eventio: Kqueue breaks in subtle ways so select is now used instead.
|
||||||
|
|
||||||
|
|
|
@ -14,12 +14,20 @@ consume from. Several consumers can be mixed to consume from different
|
||||||
channels, as they all bind to the same connection, and ``drain_events`` will
|
channels, as they all bind to the same connection, and ``drain_events`` will
|
||||||
drain events from all channels on that connection.
|
drain events from all channels on that connection.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Kombu since 3.0 will only accept json/binary or text messages by default,
|
||||||
|
to allow deserialization of other formats you have to specify them
|
||||||
|
in the ``accept`` argument::
|
||||||
|
|
||||||
|
Consumer(conn, accept=['json', 'pickle', 'msgpack', 'yaml'])
|
||||||
|
|
||||||
|
|
||||||
Draining events from a single consumer:
|
Draining events from a single consumer:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
with Consumer(connection, queues):
|
with Consumer(connection, queues, accept=['json']):
|
||||||
connection.drain_events(timeout=1)
|
connection.drain_events(timeout=1)
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,8 +38,8 @@ Draining events from several consumers:
|
||||||
from kombu.utils import nested
|
from kombu.utils import nested
|
||||||
|
|
||||||
with connection.channel(), connection.channel() as (channel1, channel2):
|
with connection.channel(), connection.channel() as (channel1, channel2):
|
||||||
consumers = [Consumer(channel1, queues1),
|
consumers = [Consumer(channel1, queues1, accept=['json']),
|
||||||
Consumer(channel2, queues2)]
|
Consumer(channel2, queues2, accept=['json'])]
|
||||||
with nested(\*consumers):
|
with nested(\*consumers):
|
||||||
connection.drain_events(timeout=1)
|
connection.drain_events(timeout=1)
|
||||||
|
|
||||||
|
@ -48,7 +56,9 @@ Or using :class:`~kombu.mixins.ConsumerMixin`:
|
||||||
self.connection = connection
|
self.connection = connection
|
||||||
|
|
||||||
def get_consumers(self, Consumer, channel):
|
def get_consumers(self, Consumer, channel):
|
||||||
return [Consumer(queues, callbacks=[self.on_message])]
|
return [
|
||||||
|
Consumer(queues, callbacks=[self.on_message], accept=['json']),
|
||||||
|
]
|
||||||
|
|
||||||
def on_message(self, body, message):
|
def on_message(self, body, message):
|
||||||
print("RECEIVED MESSAGE: %r" % (body, ))
|
print("RECEIVED MESSAGE: %r" % (body, ))
|
||||||
|
@ -73,9 +83,11 @@ and with multiple channels again:
|
||||||
def get_consumers(self, _, default_channel):
|
def get_consumers(self, _, default_channel):
|
||||||
self.channel2 = default_channel.connection.channel()
|
self.channel2 = default_channel.connection.channel()
|
||||||
return [Consumer(default_channel, queues1,
|
return [Consumer(default_channel, queues1,
|
||||||
callbacks=[self.on_message]),
|
callbacks=[self.on_message],
|
||||||
|
accept=['json']),
|
||||||
Consumer(self.channel2, queues2,
|
Consumer(self.channel2, queues2,
|
||||||
callbacks=[self.on_special_message])]
|
callbacks=[self.on_special_message],
|
||||||
|
accept=['json'])]
|
||||||
|
|
||||||
def on_consumer_end(self, connection, default_channel):
|
def on_consumer_end(self, connection, default_channel):
|
||||||
if self.channel2:
|
if self.channel2:
|
||||||
|
|
|
@ -15,6 +15,17 @@ Python data structures like dictionaries and lists works.
|
||||||
and if needed you can register any custom serialization scheme you
|
and if needed you can register any custom serialization scheme you
|
||||||
want to use.
|
want to use.
|
||||||
|
|
||||||
|
|
||||||
|
By default Kombu will only load JSON messages, so if you want
|
||||||
|
to use other serialization format you must explicitly enable
|
||||||
|
them in your consumer by using the ``accept`` argument:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
Consumer(conn, [queue], accept=['json', 'pickle', 'msgpack'])
|
||||||
|
|
||||||
|
The accept argument can also include MIME-types.
|
||||||
|
|
||||||
.. _`JSON`: http://www.json.org/
|
.. _`JSON`: http://www.json.org/
|
||||||
.. _`YAML`: http://yaml.org/
|
.. _`YAML`: http://yaml.org/
|
||||||
.. _`msgpack`: http://msgpack.sourceforge.net/
|
.. _`msgpack`: http://msgpack.sourceforge.net/
|
||||||
|
@ -44,6 +55,18 @@ Each option has its advantages and disadvantages.
|
||||||
smaller messages when sending binary files, and a slight speedup
|
smaller messages when sending binary files, and a slight speedup
|
||||||
over `JSON` processing.
|
over `JSON` processing.
|
||||||
|
|
||||||
|
.. admonition:: Pickle and Security
|
||||||
|
|
||||||
|
The pickle format is very convenient as it can serialize
|
||||||
|
and deserialize almost any object, but this is also a concern
|
||||||
|
for security.
|
||||||
|
|
||||||
|
Carefully crafted pickle payloads can do almost anything
|
||||||
|
a regular Python program can do, so if you let your consumer
|
||||||
|
automatically decode pickled objects you must make sure
|
||||||
|
to limit access to the broker so that untrusted
|
||||||
|
parties do not have the ability to send messages!
|
||||||
|
|
||||||
By default Kombu uses pickle protocol 2, but this can be changed
|
By default Kombu uses pickle protocol 2, but this can be changed
|
||||||
using the :envvar:`PICKLE_PROTOCOL` environment variable or by changing
|
using the :envvar:`PICKLE_PROTOCOL` environment variable or by changing
|
||||||
the global :data:`kombu.serialization.pickle_protocol` flag.
|
the global :data:`kombu.serialization.pickle_protocol` flag.
|
||||||
|
@ -77,33 +100,6 @@ Note that a `Consumer` do not need the serialization method specified.
|
||||||
They can auto-detect the serialization method as the
|
They can auto-detect the serialization method as the
|
||||||
content-type is sent as a message header.
|
content-type is sent as a message header.
|
||||||
|
|
||||||
.. _disable-untrusted-serializers:
|
|
||||||
|
|
||||||
Disabling Insecure Serializers
|
|
||||||
------------------------------
|
|
||||||
|
|
||||||
.. versionadded:: 2.5.10
|
|
||||||
|
|
||||||
Deserializing pickle and yaml from untrusted sources is not safe,
|
|
||||||
as both pickle and yaml have the ability to execute arbitrary code.
|
|
||||||
|
|
||||||
If you are not using these formats you should disable them
|
|
||||||
by calling :func:`kombu.disable_insecure_serializers`::
|
|
||||||
|
|
||||||
>>> import kombu
|
|
||||||
>>> kombu.disable_insecure_serializers()
|
|
||||||
|
|
||||||
Or you can specify the content types your consumers should
|
|
||||||
accept by using the ``accept`` argument::
|
|
||||||
|
|
||||||
>>> Consumer(accept=['json', 'pickle'])
|
|
||||||
>>> Consumer(accept=['application/json'])
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
Insecure serializers will be disabled by default
|
|
||||||
in the next major version (Kombu 3.0)
|
|
||||||
|
|
||||||
.. _sending-raw-data:
|
.. _sending-raw-data:
|
||||||
|
|
||||||
Sending raw data without Serialization
|
Sending raw data without Serialization
|
||||||
|
|
Loading…
Reference in New Issue