Path traversal check

This commit is contained in:
Piero Toffanin 2021-10-26 15:41:14 -04:00
parent d12c81b773
commit a1244b9e3e
3 changed files with 24 additions and 5 deletions

View file

@ -12,7 +12,7 @@ from flask_swagger_ui import get_swaggerui_blueprint
from translatehtml import translate_html from translatehtml import translate_html
from werkzeug.utils import secure_filename from werkzeug.utils import secure_filename
from app import flood, remove_translated_files from app import flood, remove_translated_files, security
from app.language import detect_languages, transliterate from app.language import detect_languages, transliterate
from .api_keys import Database from .api_keys import Database
from .suggestions import Database as SuggestionsDatabase from .suggestions import Database as SuggestionsDatabase
@ -621,10 +621,15 @@ def create_app(args):
Download a translated file Download a translated file
""" """
if args.disable_files_translation: if args.disable_files_translation:
abort(403, description="Files translation are disabled on this server.") abort(400, description="Files translation are disabled on this server.")
filepath = os.path.join(get_upload_dir(), filename) filepath = os.path.join(get_upload_dir(), filename)
try:
checked_filepath = security.path_traversal_check(filepath, get_upload_dir())
if os.path.isfile(checked_filepath):
filepath = checked_filepath
except security.SuspiciousFileOperation:
abort(400, description="Invalid filename")
return_data = io.BytesIO() return_data = io.BytesIO()
with open(filepath, 'rb') as fo: with open(filepath, 'rb') as fo:

14
app/security.py Normal file
View file

@ -0,0 +1,14 @@
import os
class SuspiciousFileOperation(Exception):
pass
def path_traversal_check(unsafe_path, known_safe_path):
known_safe_path = os.path.abspath(known_safe_path)
unsafe_path = os.path.abspath(unsafe_path)
if (os.path.commonprefix([known_safe_path, unsafe_path]) != known_safe_path):
raise SuspiciousFileOperation("{} is not safe".format(unsafe_path))
# Passes the check
return unsafe_path

View file

@ -175,7 +175,7 @@
<div class="row" v-if="translationType === 'files'"> <div class="row" v-if="translationType === 'files'">
<div class="file-dropzone"> <div class="file-dropzone">
<div v-if="inputFile === false" class="dropzone-content"> <div v-if="inputFile === false" class="dropzone-content">
<span>Supported file format: [[ supportedFilesFormatFormatted ]]</span> <span>Supported file formats: [[ supportedFilesFormatFormatted ]]</span>
<form action="#"> <form action="#">
<div class="file-field input-field"> <div class="file-field input-field">
<div class="btn"> <div class="btn">