{"title":"Import Hijacking via sys.path Manipulation","language":"Python","severity":"Critical","cwe":"CWE-427","source_lines":[2],"flow_lines":[2,3,6,7],"sink_lines":[6],"vulnerable_code":"import sys\nimport os\n\ndef load_cloud_credentials(provider_path):\n    config_dir = os.path.join('/tmp/cloud_configs', provider_path)\n    if not os.path.exists(config_dir):\n        os.makedirs(config_dir)\n    sys.path.insert(0, config_dir)\n    import aws_auth\n    creds = aws_auth.get_credentials()\n    return creds","explanation":"The function accepts a user-controlled `provider_path` parameter that is used to construct a directory path, which is then inserted into `sys.path`. This allows an attacker to inject a malicious directory containing a fake `aws_auth` module that will be imported instead of the legitimate one, enabling credential theft or arbitrary code execution.","remediation":"The fix eliminates sys.path manipulation entirely by using importlib.util to load modules directly from a trusted, fixed base directory. It validates the provider name against an allowlist of known providers and uses os.path.realpath to prevent path traversal attacks that could escape the trusted directory.","secure_code":"import os\nimport importlib.util\n\nALLOWED_PROVIDERS = {'aws', 'azure', 'gcp'}\nTRUSTED_MODULE_DIR = '/opt/cloud_provider_modules'\n\ndef load_cloud_credentials(provider_name):\n    # Validate provider name against allowlist\n    if provider_name not in ALLOWED_PROVIDERS:\n        raise ValueError(f\"Unsupported cloud provider: {provider_name}. Allowed: {ALLOWED_PROVIDERS}\")\n    \n    # Construct module path from trusted base directory only\n    module_file = os.path.join(TRUSTED_MODULE_DIR, provider_name, f\"{provider_name}_auth.py\")\n    \n    # Resolve to absolute path and verify it stays within trusted directory\n    resolved_path = os.path.realpath(module_file)\n    trusted_base = os.path.realpath(TRUSTED_MODULE_DIR)\n    if not resolved_path.startswith(trusted_base + os.sep):\n        raise ValueError(\"Module path escapes trusted directory\")\n    \n    if not os.path.isfile(resolved_path):\n        raise FileNotFoundError(f\"Authentication module not found: {resolved_path}\")\n    \n    # Load module from specific file path without modifying sys.path\n    spec = importlib.util.spec_from_file_location(f\"{provider_name}_auth\", resolved_path)\n    if spec is None or spec.loader is None:\n        raise ImportError(f\"Cannot load module spec from {resolved_path}\")\n    \n    auth_module = importlib.util.module_from_spec(spec)\n    spec.loader.exec_module(auth_module)\n    \n    creds = auth_module.get_credentials()\n    return creds"}