Create Fory with custom security policy

January 13, 2026 ยท View on GitHub

This page covers security best practices and DeserializationPolicy.

Production Configuration

Never disable strict=True in production unless your environment is completely trusted:

import pyfory

# Recommended production settings
f = pyfory.Fory(
    xlang=False,   # or True for cross-language
    ref=True,      # Handle circular references
    strict=True,   # IMPORTANT: Prevent malicious data
    max_depth=100  # Prevent deep recursion attacks
)

# Explicitly register allowed types
f.register(UserModel, type_id=100)
f.register(OrderModel, type_id=101)
# Never set strict=False in production with untrusted data!

Development vs Production

Use environment variables to switch between configurations:

import pyfory
import os

# Development configuration
if os.getenv('ENV') == 'development':
    fory = pyfory.Fory(
        xlang=False,
        ref=True,
        strict=False,    # Allow any type for development
        max_depth=1000   # Higher limit for development
    )
else:
    # Production configuration (security hardened)
    fory = pyfory.Fory(
        xlang=False,
        ref=True,
        strict=True,     # CRITICAL: Require registration
        max_depth=100    # Reasonable limit
    )
    # Register only known safe types
    for idx, model_class in enumerate([UserModel, ProductModel, OrderModel]):
        fory.register(model_class, type_id=100 + idx)

DeserializationPolicy

When strict=False is necessary (e.g., deserializing functions/lambdas), use DeserializationPolicy to implement fine-grained security controls during deserialization.

Why use DeserializationPolicy?

  • Block dangerous classes/modules (e.g., subprocess.Popen)
  • Intercept and validate __reduce__ callables before invocation
  • Sanitize sensitive data during __setstate__
  • Replace or reject deserialized objects based on custom rules

Blocking Dangerous Classes

import pyfory
from pyfory import DeserializationPolicy

dangerous_modules = {'subprocess', 'os', '__builtin__'}

class SafeDeserializationPolicy(DeserializationPolicy):
    """Block potentially dangerous classes during deserialization."""

    def validate_class(self, cls, is_local, **kwargs):
        # Block dangerous modules
        if cls.__module__ in dangerous_modules:
            raise ValueError(f"Blocked dangerous class: {cls.__module__}.{cls.__name__}")
        return None

    def intercept_reduce_call(self, callable_obj, args, **kwargs):
        # Block specific callable invocations during __reduce__
        if getattr(callable_obj, '__name__', "") == 'Popen':
            raise ValueError("Blocked attempt to invoke subprocess.Popen")
        return None

    def intercept_setstate(self, obj, state, **kwargs):
        # Sanitize sensitive data
        if isinstance(state, dict) and 'password' in state:
            state['password'] = '***REDACTED***'
        return None

# Create Fory with custom security policy
policy = SafeDeserializationPolicy()
fory = pyfory.Fory(xlang=False, ref=True, strict=False, policy=policy)

# Now deserialization is protected by your custom policy
data = fory.serialize(my_object)
result = fory.deserialize(data)  # Policy hooks will be invoked

Available Policy Hooks

HookDescription
validate_class(cls, is_local)Validate/block class types during deserialization
validate_module(module, is_local)Validate/block module imports
validate_function(func, is_local)Validate/block function references
intercept_reduce_call(callable_obj, args)Intercept __reduce__ invocations
inspect_reduced_object(obj)Inspect/replace objects created via __reduce__
intercept_setstate(obj, state)Sanitize state before __setstate__
authorize_instantiation(cls, args, kwargs)Control class instantiation

See also: pyfory/policy.py contains detailed documentation and examples for each hook.

Best Practices

  1. Always use strict=True in production
  2. Use DeserializationPolicy when strict=False is necessary
  3. Block dangerous modules (subprocess, os, etc.)
  4. Set appropriate max_depth to prevent stack overflow
  5. Validate data sources before deserialization
  6. Log security events for auditing