Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Dynamic imports are especially dangerous if you cannot validate upfront what is being imported.

Dynamic imports can be achieved using:

Security concerns

Dynamic imports present a potential security issue, particularly when the module name originates from an untrusted source. Common risky scenarios include:

Why importlib.import_module() is preferred over __import__

Aspect__import__importlib.import_module()
PurposeLow-level, legacy functionModern, explicit API
ReadabilityObscure, looks like a magic methodClear, self-documenting name
MaintainabilityDiscouraged for general useActively maintained by core Python developers
SecurityNo built-in safeguardsSame risks but cleaner interface

Mitigations

There is always a security risk when importlib.import_module() is used. No mitigation eliminates this risk entirely — it can only be reduced.

Possible mitigations:

  1. Use static analysis tools: Always use a Python code audit tool with module scanning options for all modules within a file.

  1. Pre-audit all possible imports : Check and understand what will be imported and what security risks are involved. You MUST never trust that dynamic imports are safe. Most are not!

  1. Review API design – Check whether your Python program has or truly needs an API to download or import modules dynamically. Often, a static approach can replace the dynamic one.

  1. Seek expert review – If you do not trust the implementation, call a security expert to help you. See the sponsor page for companies that can assist.

Example

Insecure Dynamic Import

# INSECURE: Directly importing user-supplied module name
import importlib

user_input = input("Enter module name to load: ")
module = importlib.import_module(user_input)

# If user enters "os", they can now access system functions
# If user enters "subprocess", they can execute shell commands
module.system("rm -rf /")  # Potentially catastrophic

What is wrong with this code?

The most secure approach is to avoid dynamic imports entirely and use static imports with dispatch tables:

# MOST SECURE: No dynamic imports - use static imports with dispatch
import math
import json
import datetime
import re
from typing import Dict, Callable, Any

# Dispatch table mapping names to actual modules
MODULE_DISPATCH: Dict[str, Any] = {
    "math": math,
    "json": json,
    "datetime": datetime,
    "re": re
}

# Dispatch table for specific functions
FUNCTION_DISPATCH: Dict[str, Callable] = {
    "math.sqrt": math.sqrt,
    "math.pi": lambda: math.pi,
    "json.loads": json.loads,
    "json.dumps": json.dumps,
    "datetime.datetime": datetime.datetime,
    "re.search": re.search
}

def get_module(module_name: str) -> Any:
    """Get a module from the dispatch table - no dynamic import needed."""
    if module_name not in MODULE_DISPATCH:
        raise ValueError(f"Module '{module_name}' not available")
    return MODULE_DISPATCH[module_name]

def get_function(function_name: str) -> Callable:
    """Get a function from the dispatch table - no dynamic import needed."""
    if function_name not in FUNCTION_DISPATCH:
        raise ValueError(f"Function '{function_name}' not available")
    return FUNCTION_DISPATCH[function_name]

# Usage
user_input = "math.sqrt"  # From user input
try:
    func = get_function(user_input)
    result = func(25)  # sqrt(25) = 5
    print(f"Result: {result}")
except ValueError as e:
    print(f"Invalid request: {e}")

Summary of Best Practices

PracticeRecommendation
Avoid dynamic importsPrefer static imports with dispatch tables whenever possible
Never use __import__()This legacy function should never appear in modern Python code
Use allowlistsIf dynamic imports are unavoidable, maintain a strict allowlist of permitted modules
Validate function accessDo not expose entire modules — restrict access to specific safe functions
Audit all importsUse static analysis tools to detect and review all dynamic import usage

References