fix: reject empty model name in trusted owner cache paths

check_model_from_owner_group treated paths like iic--/snapshots/v1 as
trusted because split('--') still yields two parts. Require both owner
and name segments to be non-empty.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
suluyan
2026-07-20 15:47:42 +08:00
parent 7091a00168
commit 5781f8505b
2 changed files with 35 additions and 4 deletions

View File

@@ -147,12 +147,13 @@ def check_model_from_owner_group(model_dir: str,
if group in owner_group:
return True
# Also check cache path pattern: {cache_root}/{owner}--{model_name}/snapshots/{revision}
# Require exactly "{owner}--{name}" format (2 segments split by --)
# to prevent spoofing via accounts like "iic--hacked" which would
# produce paths like "iic--hacked--evil" and bypass the check.
# Require exactly "{owner}--{name}" with both segments non-empty
# to prevent spoofing via accounts like "iic--hacked" (paths like
# "iic--hacked--evil") or empty names like "iic--".
grandparent = os.path.basename(os.path.dirname(parent_dir))
if '--' in grandparent:
parts = grandparent.split('--')
if len(parts) == 2 and parts[0] in owner_group:
# Both owner and name must be non-empty; reject "iic--" / "--name".
if len(parts) == 2 and all(parts) and parts[0] in owner_group:
return True
return False

View File

@@ -0,0 +1,30 @@
# Copyright (c) Alibaba, Inc. and its affiliates.
import unittest
from modelscope.utils.automodel_utils import check_model_from_owner_group
class OwnerGroupPathSafetyTest(unittest.TestCase):
"""Safety checks for trusted-owner cache path recognition."""
def test_empty_name_cache_path_rejected(self):
# modelscope_hub layout: {cache}/{owner}--{name}/snapshots/{rev}
# Empty name ("iic--") must not be treated as a trusted owner path.
self.assertFalse(
check_model_from_owner_group('/cache/iic--/snapshots/v1'))
self.assertFalse(
check_model_from_owner_group('/cache/damo--/snapshots/v1'))
def test_valid_and_spoof_cache_paths(self):
self.assertTrue(
check_model_from_owner_group('/cache/iic--x/snapshots/v1'))
self.assertFalse(
check_model_from_owner_group('/cache/--iic/snapshots/v1'))
self.assertFalse(
check_model_from_owner_group(
'/cache/iic--hacked--evil/snapshots/v1'))
self.assertTrue(check_model_from_owner_group('/cache/iic/some_model'))
if __name__ == '__main__':
unittest.main()