@@ -125,6 +125,7 @@ def run_skill_script(
125125 except Exception as e :
126126 return f"Error executing script: { str (e )} "
127127
128+ @require_approval (risk_level = "low" )
128129 def read_skill_file (
129130 self ,
130131 skill_path : str ,
@@ -149,6 +150,10 @@ def read_skill_file(
149150 skill_path = os .path .join (self ._working_directory , skill_path )
150151 skill_path = os .path .abspath (skill_path )
151152
153+ working_dir = os .path .abspath (self ._working_directory )
154+ if os .path .commonpath ([skill_path , working_dir ]) != working_dir :
155+ return f"Error: Workspace boundary violation - skill directory escapes workspace"
156+
152157 if not os .path .exists (skill_path ):
153158 return f"Error: Skill directory not found at { skill_path } "
154159
@@ -160,7 +165,7 @@ def read_skill_file(
160165 full_path = os .path .abspath (full_path )
161166
162167 # Security check: ensure file is within skill directory
163- if not full_path . startswith ( skill_path ) :
168+ if os . path . commonpath ([ full_path , skill_path ]) != skill_path :
164169 return f"Error: Path traversal detected - { file_path } is outside skill directory"
165170
166171 if not os .path .exists (full_path ):
@@ -239,6 +244,7 @@ def run_skill_script(script_path: str, args: str = "", timeout: int = 60) -> str
239244 return _skill_tools .run_skill_script (script_path , args , timeout )
240245
241246
247+ @require_approval (risk_level = "low" )
242248def read_skill_file (skill_path : str , file_path : str , encoding : str = 'utf-8' ) -> str :
243249 """
244250 Read a file from a skill directory.
0 commit comments