Intercept and validate __reduce__ protocol callable invocation. This hook is called when deserializing an object that was serialized using the __reduce__ or __reduce_ex__ protocol, right before the callable is invoked to reconstruct the object. When Called -
(self, callable_obj, args, **kwargs)
| 358 | # ============================================================================ |
| 359 | |
| 360 | def intercept_reduce_call(self, callable_obj, args, **kwargs): |
| 361 | """Intercept and validate __reduce__ protocol callable invocation. |
| 362 | |
| 363 | This hook is called when deserializing an object that was serialized using the |
| 364 | __reduce__ or __reduce_ex__ protocol, right before the callable is invoked |
| 365 | to reconstruct the object. |
| 366 | |
| 367 | When Called |
| 368 | ----------- |
| 369 | - During deserialization of objects using __reduce__/__reduce_ex__ |
| 370 | - Before callable_obj(*args) is executed |
| 371 | - After the callable and args have been deserialized |
| 372 | |
| 373 | Security Use Cases |
| 374 | ------------------ |
| 375 | - Block dangerous callables (eval, exec, os.system, subprocess.Popen) |
| 376 | - Validate that callables match expected signatures |
| 377 | - Inspect arguments for malicious payloads |
| 378 | - Return pre-constructed safe objects to skip callable invocation |
| 379 | - Log reduce operations for auditing |
| 380 | |
| 381 | Args: |
| 382 | callable_obj (callable): The callable that will be invoked to reconstruct |
| 383 | the object (typically a class or factory function). |
| 384 | args (tuple): The arguments that will be passed to the callable. |
| 385 | **kwargs: Reserved for future extensions. |
| 386 | |
| 387 | Returns: |
| 388 | None: Return None to proceed with normal callable invocation (callable_obj(*args)). |
| 389 | object: Return an object to use directly, skipping the callable invocation. |
| 390 | This allows you to construct safe replacement objects. |
| 391 | |
| 392 | Raises: |
| 393 | Exception: Raise any exception to reject the callable and abort deserialization. |
| 394 | |
| 395 | Example: |
| 396 | >>> class ReduceChecker(DeserializationPolicy): |
| 397 | ... def intercept_reduce_call(self, callable_obj, args, **kwargs): |
| 398 | ... # Block subprocess.Popen |
| 399 | ... if callable_obj.__name__ == 'Popen': |
| 400 | ... raise ValueError("Popen not allowed") |
| 401 | ... |
| 402 | ... # Audit all reduce operations |
| 403 | ... import logging |
| 404 | ... logging.info(f"Reducing with {callable_obj}({args})") |
| 405 | ... |
| 406 | ... return None # Proceed normally |
| 407 | |
| 408 | Note: |
| 409 | This is one of the most critical security hooks, as __reduce__ is the primary |
| 410 | vector for arbitrary code execution in pickle-based attacks. |
| 411 | |
| 412 | `check_reduce_callable` is an alias for this hook. |
| 413 | """ |
| 414 | pass |
| 415 | |
| 416 | # Hook aliases |
| 417 | def check_reduce_callable(self, callable_obj, args, **kwargs): |
no outgoing calls
no test coverage detected