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