Retrieve full absolute path to the pack file. Note: This function also takes care of sanitizing ``file_name`` argument preventing directory traversal and similar attacks. :param pack_ref: Pack reference (needs to be the same as directory on disk). :type pack_ref: ``str``
(
pack_ref, file_path, resource_type=None, use_pack_cache=False
)
| 245 | |
| 246 | |
| 247 | def get_pack_file_abs_path( |
| 248 | pack_ref, file_path, resource_type=None, use_pack_cache=False |
| 249 | ): |
| 250 | """ |
| 251 | Retrieve full absolute path to the pack file. |
| 252 | |
| 253 | Note: This function also takes care of sanitizing ``file_name`` argument |
| 254 | preventing directory traversal and similar attacks. |
| 255 | |
| 256 | :param pack_ref: Pack reference (needs to be the same as directory on disk). |
| 257 | :type pack_ref: ``str`` |
| 258 | |
| 259 | :pack file_path: Resource file path relative to the pack directory (e.g. my_file.py or |
| 260 | actions/directory/my_file.py) |
| 261 | :type file_path: ``str`` |
| 262 | |
| 263 | param: resource_type: Optional resource type. If provided, more user-friendly exception |
| 264 | is thrown on error. |
| 265 | :type resource_type: ``str`` |
| 266 | |
| 267 | :rtype: ``str`` |
| 268 | """ |
| 269 | pack_base_path = get_pack_base_path( |
| 270 | pack_name=pack_ref, use_pack_cache=use_pack_cache |
| 271 | ) |
| 272 | |
| 273 | if resource_type: |
| 274 | resource_type_plural = " %ss " % (resource_type) |
| 275 | resource_base_path = os.path.join(pack_base_path, "%ss/" % (resource_type)) |
| 276 | else: |
| 277 | resource_type_plural = " " |
| 278 | resource_base_path = pack_base_path |
| 279 | |
| 280 | path_components = [] |
| 281 | path_components.append(pack_base_path) |
| 282 | |
| 283 | # Normalize the path to prevent directory traversal |
| 284 | normalized_file_path = os.path.normpath("/" + file_path).lstrip("/") |
| 285 | |
| 286 | if normalized_file_path != file_path: |
| 287 | msg = INVALID_FILE_PATH_ERROR % ( |
| 288 | file_path, |
| 289 | resource_type_plural, |
| 290 | resource_base_path, |
| 291 | resource_type or "action", |
| 292 | ) |
| 293 | raise ValueError(msg) |
| 294 | |
| 295 | path_components.append(normalized_file_path) |
| 296 | result = os.path.join(*path_components) # pylint: disable=E1120 |
| 297 | |
| 298 | if normalized_file_path not in result: |
| 299 | raise ValueError( |
| 300 | f"This is not a normalized path {normalized_file_path}" |
| 301 | f" to prevent directory traversal {result}." |
| 302 | ) |
| 303 | |
| 304 | # Final safety check for common prefix to avoid traversal attack |
no test coverage detected