@@ -24,7 +24,6 @@ public static class ManagePrefabs
2424 private const string ACTION_CREATE_FROM_GAMEOBJECT = "create_from_gameobject" ;
2525 private const string ACTION_GET_INFO = "get_info" ;
2626 private const string ACTION_GET_HIERARCHY = "get_hierarchy" ;
27-
2827 private const string SupportedActions = ACTION_OPEN_STAGE + ", " + ACTION_CLOSE_STAGE + ", " + ACTION_SAVE_OPEN_STAGE + ", " + ACTION_CREATE_FROM_GAMEOBJECT + ", " + ACTION_GET_INFO + ", " + ACTION_GET_HIERARCHY ;
2928
3029 // Pagination constants
@@ -83,6 +82,10 @@ private static object OpenStage(JObject @params)
8382 }
8483
8584 string sanitizedPath = AssetPathUtility . SanitizeAssetPath ( prefabPath ) ;
85+ if ( sanitizedPath == null )
86+ {
87+ return new ErrorResponse ( $ "Invalid prefab path: '{ prefabPath } '.") ;
88+ }
8689 GameObject prefabAsset = AssetDatabase . LoadAssetAtPath < GameObject > ( sanitizedPath ) ;
8790 if ( prefabAsset == null )
8891 {
@@ -117,7 +120,7 @@ private static object CloseStage(JObject @params)
117120
118121 string assetPath = stage . assetPath ;
119122 bool saveBeforeClose = @params [ "saveBeforeClose" ] ? . ToObject < bool > ( ) ?? false ;
120-
123+
121124 if ( saveBeforeClose && stage . scene . isDirty )
122125 {
123126 try
@@ -335,8 +338,8 @@ private static object CreatePrefabFromGameObject(JObject @params)
335338 /// <summary>
336339 /// Validates parameters for creating a prefab from GameObject.
337340 /// </summary>
338- private static ( bool isValid , string errorMessage , string targetName , string finalPath , bool includeInactive , bool replaceExisting , bool unlinkIfInstance )
339- ValidateCreatePrefabParams ( JObject @params )
341+ private static ( bool isValid , string errorMessage , string targetName , string finalPath , bool includeInactive , bool replaceExisting , bool unlinkIfInstance )
342+ ValidateCreatePrefabParams ( JObject @params )
340343 {
341344 string targetName = @params [ "target" ] ? . ToString ( ) ?? @params [ "name" ] ? . ToString ( ) ;
342345 if ( string . IsNullOrEmpty ( targetName ) )
@@ -351,6 +354,14 @@ private static (bool isValid, string errorMessage, string targetName, string fin
351354 }
352355
353356 string sanitizedPath = AssetPathUtility . SanitizeAssetPath ( requestedPath ) ;
357+ if ( sanitizedPath == null )
358+ {
359+ return ( false , $ "Invalid prefab path (path traversal detected): '{ requestedPath } '", targetName , null , false , false , false ) ;
360+ }
361+ if ( string . IsNullOrEmpty ( sanitizedPath ) )
362+ {
363+ return ( false , $ "Invalid prefab path '{ requestedPath } '. Path cannot be empty.", targetName , null , false , false , false ) ;
364+ }
354365 if ( ! sanitizedPath . EndsWith ( ".prefab" , StringComparison . OrdinalIgnoreCase ) )
355366 {
356367 sanitizedPath += ".prefab" ;
@@ -510,6 +521,10 @@ private static object GetInfo(JObject @params)
510521 }
511522
512523 string sanitizedPath = AssetPathUtility . SanitizeAssetPath ( prefabPath ) ;
524+ if ( sanitizedPath == null )
525+ {
526+ return new ErrorResponse ( $ "Invalid prefab path: '{ prefabPath } '.") ;
527+ }
513528 GameObject prefabAsset = AssetDatabase . LoadAssetAtPath < GameObject > ( sanitizedPath ) ;
514529 if ( prefabAsset == null )
515530 {
@@ -551,6 +566,10 @@ private static object GetHierarchy(JObject @params)
551566 }
552567
553568 string sanitizedPath = AssetPathUtility . SanitizeAssetPath ( prefabPath ) ;
569+ if ( string . IsNullOrEmpty ( sanitizedPath ) )
570+ {
571+ return new ErrorResponse ( $ "Invalid prefab path '{ prefabPath } '. Path traversal sequences are not allowed.") ;
572+ }
554573
555574 // Parse pagination parameters
556575 var pagination = PaginationRequest . FromParams ( @params , defaultPageSize : DefaultPageSize ) ;
0 commit comments