You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Semgrep提示importlib.import_module存不可信输入风险,求白名单实现方案

问题说明

你在使用importlib.import_module拼接动态配置值导入模块时,触发了Semgrep的安全告警,告警信息如下:

importlib.import_module()函数中传入不可信用户输入会允许攻击者加载任意代码,请避免在importlib.import_module()中使用动态值,或使用白名单防范不可信代码运行。

触发告警的原始代码:

channel_module = import_module("src.main.core_prj.prj_" + config['subscription'].lower())
解决方案

方案1:白名单校验(最推荐,可直接消除告警)

提前定义允许导入的订阅标识列表,导入前先校验传入值是否在合法范围内,不符合则直接抛出异常,从根源上避免加载任意模块:

from importlib import import_module

# 手动维护所有允许的订阅标识,可根据业务实际情况调整
ALLOWED_SUBSCRIPTION_TYPES = {'wechat', 'alipay', 'douyin', 'xiaohongshu'}

sub_type = config['subscription'].lower()
# 先做白名单校验
if sub_type not in ALLOWED_SUBSCRIPTION_TYPES:
    raise ValueError(f"非法的订阅类型: {sub_type}")

# 校验通过后再执行导入
channel_module = import_module(f"src.main.core_prj.prj_{sub_type}")

如果允许的订阅模块数量较多,可自动扫描对应目录生成白名单,无需手动维护:

import os
from importlib import import_module

PRJ_MODULE_DIR = "src/main/core_prj"
# 自动扫描目录下所有prj_开头的模块,提取合法订阅标识
ALLOWED_SUBSCRIPTION_TYPES = set()
for filename in os.listdir(PRJ_MODULE_DIR):
    if filename.startswith("prj_") and (filename.endswith(".py") or os.path.isdir(os.path.join(PRJ_MODULE_DIR, filename))):
        sub_type = filename.split("_", 1)[1].rsplit(".py", 1)[0]
        ALLOWED_SUBSCRIPTION_TYPES.add(sub_type)

sub_type = config['subscription'].lower()
if sub_type not in ALLOWED_SUBSCRIPTION_TYPES:
    raise ValueError(f"非法的订阅类型: {sub_type}")
channel_module = import_module(f"src.main.core_prj.prj_{sub_type}")

方案2:静态映射表

直接建立订阅标识和模块路径的静态映射,完全避免动态字符串拼接的风险:

from importlib import import_module

CHANNEL_MODULE_MAP = {
    "wechat": "src.main.core_prj.prj_wechat",
    "alipay": "src.main.core_prj.prj_alipay",
    "douyin": "src.main.core_prj.prj_douyin",
    "xiaohongshu": "src.main.core_prj.prj_xiaohongshu"
}

sub_type = config['subscription'].lower()
module_path = CHANNEL_MODULE_MAP.get(sub_type)
if not module_path:
    raise ValueError(f"非法的订阅类型: {sub_type}")
channel_module = import_module(module_path)

方案3:输入字符过滤(仅作为补充缓解方案,优先选白名单)

如果业务场景不便维护白名单,可以限制输入仅包含小写字母、数字等安全字符,避免路径遍历或跨目录导入的风险:

import re
from importlib import import_module

sub_type = config['subscription'].lower()
# 限制输入仅包含小写字母和数字,长度不超过20位,可根据业务调整规则
if not re.fullmatch(r'[a-z0-9]{1,20}', sub_type):
    raise ValueError(f"非法的订阅类型格式: {sub_type}")

channel_module = import_module(f"src.main.core_prj.prj_{sub_type}")

内容的提问来源于stack exchange,提问作者Sarvendra Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 04:39:01