From e7ffdb5beb33377c7d7b5c95fc2e1bc3b2deff95 Mon Sep 17 00:00:00 2001 From: Solaris-star <820622658@qq.com> Date: Mon, 20 Jul 2026 21:18:11 +0800 Subject: [PATCH] fix(security): do not enable trust_remote_code from basename registry from_finetuned used os.path.basename to look up AUTO_EMBEDDER_MAPPING and copied model_config.trust_remote_code when the caller omitted the flag. A colliding local path or Hub repo name could silently execute remote code. Default to False; require an explicit trust_remote_code=True. Fixes #1579 --- FlagEmbedding/inference/auto_embedder.py | 12 +++++- tests/test_auto_embedder_trust_remote_code.py | 39 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 tests/test_auto_embedder_trust_remote_code.py diff --git a/FlagEmbedding/inference/auto_embedder.py b/FlagEmbedding/inference/auto_embedder.py index 6fad0330f..8065bbaa9 100644 --- a/FlagEmbedding/inference/auto_embedder.py +++ b/FlagEmbedding/inference/auto_embedder.py @@ -95,8 +95,18 @@ def from_finetuned( _model_class = model_config.model_class if pooling_method is None: pooling_method = model_config.pooling_method.value + # Never enable trust_remote_code from a basename-only registry match. + # Basename collisions (local dirs / arbitrary Hub repos) must not + # silently execute remote code (#1579). Callers opt in explicitly. if trust_remote_code is None: - trust_remote_code = model_config.trust_remote_code + trust_remote_code = False + if model_config.trust_remote_code: + logger.warning( + "`trust_remote_code` defaults to False for security; " + "pass trust_remote_code=True explicitly if this model " + "requires custom code (registry basename match alone " + "is not sufficient)." + ) if query_instruction_format is None: query_instruction_format = model_config.query_instruction_format diff --git a/tests/test_auto_embedder_trust_remote_code.py b/tests/test_auto_embedder_trust_remote_code.py new file mode 100644 index 000000000..372694753 --- /dev/null +++ b/tests/test_auto_embedder_trust_remote_code.py @@ -0,0 +1,39 @@ + +"""Registry basename must not silently enable trust_remote_code (#1579).""" + +from FlagEmbedding.inference.embedder.model_mapping import AUTO_EMBEDDER_MAPPING +from FlagEmbedding.inference.auto_embedder import FlagAutoModel + + +def test_registry_has_trust_true_entries(): + # Precondition: at least one mapping still declares trust_remote_code=True + assert any(getattr(c, "trust_remote_code", False) for c in AUTO_EMBEDDER_MAPPING.values()) + + +def test_from_finetuned_does_not_inherit_registry_trust(monkeypatch): + """Basename match must not force trust_remote_code=True when omitted.""" + # Pick any mapping entry that wants trust_remote_code=True if present + name = None + for k, cfg in AUTO_EMBEDDER_MAPPING.items(): + if getattr(cfg, "trust_remote_code", False): + name = k + break + if name is None: + # Fallback: any entry + name = next(iter(AUTO_EMBEDDER_MAPPING)) + + captured = {} + + class Dummy: + DEFAULT_POOLING_METHOD = "cls" + + def __init__(self, model_name_or_path, **kwargs): + captured.update(kwargs) + captured["model_name_or_path"] = model_name_or_path + + # Patch the selected model class constructor + cfg = AUTO_EMBEDDER_MAPPING[name] + monkeypatch.setattr(cfg, "model_class", Dummy) + + FlagAutoModel.from_finetuned(f"/tmp/evil/{name}") + assert captured.get("trust_remote_code") is False