Add mime_type checks on file uploads

This commit is contained in:
yunimoo 2024-05-31 17:43:49 -04:00
parent 014a247847
commit 7eece7603b
3 changed files with 27 additions and 2 deletions

View File

@ -23,6 +23,7 @@
import os import os
from datetime import datetime from datetime import datetime
import json import json
import magic
from shutil import copyfile from shutil import copyfile
from uuid import uuid4 from uuid import uuid4
from markupsafe import escape, Markup # dependency of flask from markupsafe import escape, Markup # dependency of flask
@ -757,6 +758,10 @@ def file_handling_on_upload(requested_file):
flash(_("File %(filename)s could not saved to temp dir", flash(_("File %(filename)s could not saved to temp dir",
filename=requested_file.filename), category="error") filename=requested_file.filename), category="error")
return None, Response(json.dumps({"location": url_for("web.index")}), mimetype='application/json') return None, Response(json.dumps({"location": url_for("web.index")}), mimetype='application/json')
except (Exception):
flash(_("File is not allowed to be uploaded to this server",
filename=requested_file.filename), category="error")
return None, Response(json.dumps({"location": url_for("web.index")}), mimetype='application/json')
return meta, None return meta, None

View File

@ -19,6 +19,9 @@
from tempfile import gettempdir from tempfile import gettempdir
import os import os
import shutil import shutil
import magic
import zipfile
from . import constants
def get_temp_dir(): def get_temp_dir():
tmp_dir = os.path.join(gettempdir(), 'calibre_web') tmp_dir = os.path.join(gettempdir(), 'calibre_web')
@ -30,3 +33,19 @@ def get_temp_dir():
def del_temp_dir(): def del_temp_dir():
tmp_dir = os.path.join(gettempdir(), 'calibre_web') tmp_dir = os.path.join(gettempdir(), 'calibre_web')
shutil.rmtree(tmp_dir) shutil.rmtree(tmp_dir)
def validate_mime_type(tmp_file_path):
mime = magic.Magic(mime=True)
tmp_mime_type = mime.from_file(tmp_file_path)
if any(mime_type in tmp_mime_type for mime_type in constants.EXTENSIONS_UPLOAD):
return True
# Some epubs show up as zip mimetypes
elif "zip" in tmp_mime_type:
try:
with zipfile.ZipFile(tmp_file_path, 'r') as epub:
if "mimetype" in epub.namelist():
return True
except:
pass
raise Exception("Forbidden MIME type to upload")

View File

@ -23,7 +23,7 @@ from flask_babel import gettext as _
from . import logger, comic, isoLanguages from . import logger, comic, isoLanguages
from .constants import BookMeta from .constants import BookMeta
from .helper import split_authors from .helper import split_authors
from .file_helper import get_temp_dir from .file_helper import get_temp_dir, validate_mime_type
log = logger.create() log = logger.create()
@ -91,6 +91,7 @@ def process(tmp_file_path, original_file_name, original_file_extension, rar_exec
meta = meta._replace(title=original_file_name) meta = meta._replace(title=original_file_name)
if not meta.author.strip() or meta.author.lower() == 'unknown': if not meta.author.strip() or meta.author.lower() == 'unknown':
meta = meta._replace(author=_('Unknown')) meta = meta._replace(author=_('Unknown'))
if validate_mime_type(tmp_file_path):
return meta return meta