Si encuentras algún problema en tu código o proyecto, recuerda probar siempre en un ambiente de testing antes añadir el código al trabajo final.
Solución:
Puede obligar al usuario a crear un archivo/directorio dentro de wiki normalizando la ruta con os.path.normpath y luego verificando si la ruta comienza con, por ejemplo, ‘(ruta-a-wiki)’
os.path.normpath('(path-to-wiki)/foo/bar.txt').startswith('(path-to-wiki)')
Para asegurarse de que la ruta/nombre de archivo ingresado por el usuario no contenga nada desagradable, puede obligar al usuario a ingresar una ruta o nombre de archivo en alfabético inferior/superior, dígitos numéricos o guiones o guiones bajos.
Luego, siempre puede verificar el nombre de archivo normalizado usando una expresión regular similar
userpath=os.path.normpath('(path-to-wiki)/foo/bar.txt')
re.findall(r'[^A-Za-z0-9_-\]',userpath)
Para resumir
si userpath=os.path.normpath('(path-to-wiki)/foo/bar.txt')
luego
if not os.path.normpath('(path-to-wiki)/foo/bar.txt').startswith('(path-to-wiki)')
or re.search(r'[^A-Za-z0-9_-\]',userpath):
... Do what ever you want with an invalid path
Armin Ronacher tiene una publicación de blog sobre este tema (y otros).
Estas ideas se implementan como la función safe_join() en Flask:
def safe_join(directory, filename):
"""Safely join `directory` and `filename`.
Example usage::
@app.route('/wiki/')
def wiki_page(filename):
filename = safe_join(app.config['WIKI_FOLDER'], filename)
with open(filename, 'rb') as fd:
content = fd.read() # Read and process the file content...
:param directory: the base directory.
:param filename: the untrusted filename relative to that directory.
:raises: :class:`~werkzeug.exceptions.NotFound` if the resulting path
would fall out of `directory`.
"""
filename = posixpath.normpath(filename)
for sep in _os_alt_seps:
if sep in filename:
raise NotFound()
if os.path.isabs(filename) or filename.startswith('../'):
raise NotFound()
return os.path.join(directory, filename)
ahora hay una biblioteca completa para validar cadenas: Echale un vistazo:
from pathvalidate import sanitize_filepath
fpath = "fi:l*e/p"a?t>h|.t ".format(fpath, sanitize_filepath(fpath)))
fpath = " _a*b:ce%f/(g)h+i_0.txt"
print(" -> ".format(fpath, sanitize_filepath(fpath)))
producción:
fi:l*e/p"a?t>h|.t file/path.txt
_a*b:ce%f/(g)h+i_0.txt -> _abcde%f/(g)h+i_0.txt
Al final de la web puedes encontrar las aclaraciones de otros creadores, tú asimismo puedes mostrar el tuyo si lo crees conveniente.