Commit 33142858 authored by Ondřej Borýsek's avatar Ondřej Borýsek
Browse files

Don't allow HTML import by default

parent 8b499ffe
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -2,11 +2,19 @@ import pathlib

from werkzeug.utils import secure_filename
from flask import request

from helpers.md_and_html_convertor import MdAndHTMLConvertorLowLevel
from helpers.file_utils import is_whitelisted_extension
from typing import Optional, Union, Set, Tuple
import os


def does_text_contain_custom_escaped_characters(data: bytes):
    text = data.decode(encoding="utf8")
    unescaped_text = MdAndHTMLConvertorLowLevel.reverse_custom_escaping_of_html(text)
    return text != unescaped_text


def save_multiple_uploaded_files(output_folder: str, reserved_filenames: Set[str], allowed_extensions: Set[str]) -> Tuple[str, Set[str]]:
    files = request.files.getlist("file[]")
    output_filenames = set()
@@ -29,6 +37,17 @@ def save_multiple_uploaded_files(output_folder: str, reserved_filenames: Set[str
        if filename in output_filenames:
            return f"Name {filename} is duplicate.", output_filenames

        is_dangerous_content_allowed = request.form.get("import_dangerous_files", False)
        content = file.stream.read()
        file.stream.seek(0)
        if does_text_contain_custom_escaped_characters(content) and not is_dangerous_content_allowed:
            min_char = min(MdAndHTMLConvertorLowLevel.HTML_TO_RESERVED_CHARS.values()).encode("unicode_escape")
            max_char = max(MdAndHTMLConvertorLowLevel.HTML_TO_RESERVED_CHARS.values()).encode("unicode_escape")

            return f"""File {filename} contains characters that could cause cause XSS (characters range from {min_char} to {max_char}.
            Importer uses them to encode HTML characters so that we can distinguish them in output of Scan2Report.
            If you need to import them (for example you are recovering a backup), check the option "Import custom escaped HTML (possible XSS)".""", output_filenames

        output_filenames.add(filename)
        output_path = os.path.join(output_folder, filename)
        file.save(output_path)
+3 −3
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@ class MdAndHTMLConvertor:

class MdAndHTMLConvertorLowLevel:

    _HTML_TO_RESERVED_CHARS = {
    HTML_TO_RESERVED_CHARS = {
        '<': '\ue020',
        '>': '\ue021',
        '&': '\ue022',
@@ -165,7 +165,7 @@ class MdAndHTMLConvertorLowLevel:

    @classmethod
    def reverse_custom_escaping_of_html(cls, text: str) -> str:
        for html_char, custom_escaped_char in cls._HTML_TO_RESERVED_CHARS.items():
        for html_char, custom_escaped_char in cls.HTML_TO_RESERVED_CHARS.items():
            text = text.replace(custom_escaped_char, html_char)

            unicode_repr = ascii(custom_escaped_char).strip("'")
@@ -200,7 +200,7 @@ class MdAndHTMLConvertorLowLevel:
    @classmethod
    def custom_escape_html(cls, text: str) -> str:
        """ Escapes HTML special chars so that it's possible to distinguish them from any HTML chars added later in the process by scan2report. """
        for html_char, custom_escaped_char in cls._HTML_TO_RESERVED_CHARS.items():
        for html_char, custom_escaped_char in cls.HTML_TO_RESERVED_CHARS.items():
            text = text.replace(html_char, custom_escaped_char)
        return text

+5 −0
Original line number Diff line number Diff line
@@ -62,6 +62,11 @@
        <textarea name="scan2report_args" id="scan2report_args" rows="4" cols="100" placeholder='Example: --ignore "nessus_example1,nessus_example2"'></textarea>
        <br><br>

        <label for="import_dangerous_files">Import custom escaped HTML (can lead to XSS)</label>
        <input type="checkbox" name="import_dangerous_files" id="import_dangerous_files"/>

        <br><br>

        <input type=submit value=Upload>
    </form>
{% endblock %}
 No newline at end of file
+4 −0
Original line number Diff line number Diff line
@@ -16,6 +16,10 @@
            {% endfor %}

        </select>
        <br><br>
        <label for="import_dangerous_files">Import custom escaped HTML (can lead to XSS)</label>
        <input type="checkbox" name="import_dangerous_files" id="import_dangerous_files"/>

        <br><br>

        <input type=submit value=Upload>