Skip to main content

V12.5.2 File Download

Requirement:#

Verify that direct requests to uploaded files will never be executed as HTML/JavaScript content.

Explanation:#

Требование направлено на обеспечение того, чтобы прямые запросы к загружаемым файлам не могли быть выполнены как содержимое HTML или JavaScript. Это требование направлено на предотвращение атак, известных как "Content-Type Sniffing" или "MIME Sniffing", когда браузеры могут неверно интерпретировать тип содержимого файла и выполнять его как HTML или JavaScript, что может привести к атакам cross-site scripting (XSS).

1 Content-Type Sniffing:

  • Content-Type sniffing - это поведение веб-браузеров, при котором они пытаются определить реальный тип контента файла на основе его содержимого, а не только на основе объявленного заголовка Content-Type. 1 HTML/JavaScript Execution:

  • Если файл интерпретируется как HTML или JavaScript, то это может привести к возникновению таких уязвимостей безопасности, как cross-site scripting  (XSS). Злоумышленник может загрузить вредоносный файл, например, изображение с искусственным содержимым, которое будет интерпретировано браузером как HTML или JavaScript.

Remediation:#

Чтобы выполнить это требование и предотвратить Content-Type Sniffing или MIME Sniffing:

1 Set Correct Content-Type Headers:

  • При доставке файлов убедитесь, что вы установили корректный заголовок Content-Type, который точно отражает тип содержимого. Этот заголовок должен быть задан в соответствии с реальным типом файла, например text/plain для текстовых файлов, image/jpeg для изображений и т.д. 1 Use Content-Disposition Header:

  • Установите заголовок Content-Disposition для определения требуемых действий браузера. Для загрузки файлов используйте заголовок attachment, чтобы предложить пользователю загрузить файл, а не отображать его в браузере. 1 Set X-Content-Type-Options Header:

  • Добавьте в ответы заголовок X-Content-Type-Options и установите для него значение nosniff. Это позволяет браузерам не выполнять атаку типа content-type sniffing и предотвратить потенциальные проблемы безопасности.

Пример кода, который демонстрирует, как соответствовать требованию устанавливая соответствующие заголовки, чтобы предотвратить Content-Type Sniffing:

from flask import Flask, send_file, request, Response
app = Flask(__name__)
ALLOWED_EXTENSIONS = ["txt", "pdf", "docx"] # Example list of allowed file extensions
def is_allowed_extension(filename):
return "." in filename and filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route("/download")
def download_file():
# Get the filename parameter from the query string
filename = request.args.get("filename")
if not filename:
return "Filename parameter missing", 400
# Validate filename and extension
if not is_allowed_extension(filename):
return "Invalid file extension", 400
# Determine the content type based on the file extension
content_type = "application/octet-stream" # Default content type
if filename.endswith(".txt"):
content_type = "text/plain"
elif filename.endswith(".pdf"):
content_type = "application/pdf"
elif filename.endswith(".docx"):
content_type = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
# Set the appropriate headers for safe file download
response = send_file(filename, mimetype=content_type, as_attachment=True)
response.headers["Content-Disposition"] = f'attachment; filename="{filename}"'
response.headers["X-Content-Type-Options"] = "nosniff"
return response
if __name__ == "__main__":
app.run()
 

В данном примере:

  •     Функция is_allowed_extension проверяет, входит ли расширение запрашиваемого файла в список разрешенных расширений.
  •     download_file проверяет имя и расширение файла и устанавливает соответствующие заголовки Content-Type, Content-Disposition и X-Content-Type-Options для безопасной загрузки файла.
  •     Тип содержимого определяется на основе расширения файла, чтобы браузеры правильно интерпретировали содержимое.

Данный пример предназначен для предотвращения перехвата типа содержимого и обеспечения безопасной загрузки файлов.

Additional:#

https://cwe.mitre.org/data/definitions/434.html