05/24 Fix Security bugs
This commit is contained in:
@@ -111,9 +111,41 @@ def analyze():
|
||||
"file_count": len(file_names), **result})
|
||||
|
||||
|
||||
# Magic-byte signatures for each supported binary format.
|
||||
# Office Open XML (docx/xlsx) and legacy OLE (doc/xls) share these headers.
|
||||
_FILE_MAGIC: dict = {
|
||||
".pdf": b"%PDF",
|
||||
".docx": b"PK\x03\x04",
|
||||
".xlsx": b"PK\x03\x04",
|
||||
".doc": b"\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1",
|
||||
".xls": b"\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1",
|
||||
}
|
||||
|
||||
|
||||
def _validate_magic(data: bytes, ext: str) -> None:
|
||||
"""Raise ValueError if the file's actual bytes don't match its extension."""
|
||||
magic = _FILE_MAGIC.get(ext)
|
||||
if magic:
|
||||
if data[: len(magic)] != magic:
|
||||
raise ValueError(
|
||||
f"File content does not match the declared {ext} format "
|
||||
"(possible disguised upload)."
|
||||
)
|
||||
elif ext in (".txt", ".csv", ".md"):
|
||||
# Text files must be decodable; binary data masquerading as text is rejected.
|
||||
try:
|
||||
data[:512].decode("utf-8")
|
||||
except UnicodeDecodeError:
|
||||
raise ValueError(
|
||||
"Text file does not appear to be valid UTF-8. "
|
||||
"Ensure the file is a plain text document."
|
||||
)
|
||||
|
||||
|
||||
def _extract_text(file_obj, ext: str) -> str:
|
||||
"""Extract plain text from an uploaded file object."""
|
||||
data = file_obj.read()
|
||||
_validate_magic(data, ext)
|
||||
|
||||
if ext in (".txt", ".md", ".csv"):
|
||||
return data.decode("utf-8", errors="replace")
|
||||
|
||||
Reference in New Issue
Block a user