use werkzeug safe_join to sanitize the requested path
no tests changed, so my implementation might have been good, but let's use the provided check
This commit is contained in:
parent
b3dfab2611
commit
55cfad90a9
@ -7,6 +7,7 @@ import re
|
|||||||
from flask import Blueprint, Markup, abort
|
from flask import Blueprint, Markup, abort
|
||||||
from flask import current_app as app
|
from flask import current_app as app
|
||||||
from flask import redirect, request, send_from_directory
|
from flask import redirect, request, send_from_directory
|
||||||
|
from werkzeug.security import safe_join
|
||||||
|
|
||||||
from incorporealcms.lib import get_meta_str, init_md, render
|
from incorporealcms.lib import get_meta_str, init_md, render
|
||||||
|
|
||||||
@ -101,15 +102,16 @@ def request_path_to_instance_resource_path(path):
|
|||||||
"""
|
"""
|
||||||
# check if the path is allowed
|
# check if the path is allowed
|
||||||
base_dir = os.path.realpath(f'{app.instance_path}/pages/')
|
base_dir = os.path.realpath(f'{app.instance_path}/pages/')
|
||||||
verbatim_path = os.path.abspath(os.path.join(base_dir, path))
|
safe_path = safe_join(base_dir, path)
|
||||||
resolved_path = os.path.realpath(verbatim_path)
|
|
||||||
logger.debug("base_dir '%s', constructed resolved_path '%s' for path '%s'", base_dir, resolved_path, path)
|
|
||||||
|
|
||||||
# bail if the requested real path isn't inside the base directory
|
# bail if the requested real path isn't inside the base directory
|
||||||
if base_dir != os.path.commonpath((base_dir, resolved_path)):
|
if not safe_path:
|
||||||
logger.warning("client tried to request a path '%s' outside of the base_dir!", path)
|
logger.warning("client tried to request a path '%s' outside of the base_dir!", path)
|
||||||
raise PermissionError
|
raise PermissionError
|
||||||
|
|
||||||
|
verbatim_path = os.path.abspath(safe_path)
|
||||||
|
resolved_path = os.path.realpath(verbatim_path)
|
||||||
|
logger.debug("base_dir '%s', constructed resolved_path '%s' for path '%s'", base_dir, resolved_path, path)
|
||||||
|
|
||||||
# see if we have a real file or if we should infer markdown rendering
|
# see if we have a real file or if we should infer markdown rendering
|
||||||
if os.path.exists(resolved_path):
|
if os.path.exists(resolved_path):
|
||||||
# if this is a file-like request but actually a directory, redirect the user
|
# if this is a file-like request but actually a directory, redirect the user
|
||||||
@ -131,7 +133,7 @@ def request_path_to_instance_resource_path(path):
|
|||||||
return resolved_path.replace(f'{app.instance_path}{os.path.sep}', ''), 'file'
|
return resolved_path.replace(f'{app.instance_path}{os.path.sep}', ''), 'file'
|
||||||
|
|
||||||
# if we're here, this isn't direct file access, so try markdown inference
|
# if we're here, this isn't direct file access, so try markdown inference
|
||||||
verbatim_path = os.path.abspath(os.path.join(base_dir, f'{path}.md'))
|
verbatim_path = f'{safe_path}.md'
|
||||||
resolved_path = os.path.realpath(verbatim_path)
|
resolved_path = os.path.realpath(verbatim_path)
|
||||||
|
|
||||||
# does the final file actually exist?
|
# does the final file actually exist?
|
||||||
|
Loading…
Reference in New Issue
Block a user