]> git.lizzy.rs Git - cheatdb.git/commitdiff
Improve markdown escaping
authorrubenwardy <rw@rubenwardy.com>
Wed, 22 Jan 2020 22:10:02 +0000 (22:10 +0000)
committerrubenwardy <rw@rubenwardy.com>
Wed, 22 Jan 2020 22:10:02 +0000 (22:10 +0000)
Fixes #118

app/__init__.py
app/blueprints/users/profile.py
app/markdown.py [new file with mode: 0644]
app/templates/packages/view.html
app/templates/todo/topics.html
requirements.txt

index 478f0d869bd7d3b2c6e39ff1a5b328eff8f554ca..d0640877015d97371d1ae311d98b55aec6d53cf1 100644 (file)
@@ -20,7 +20,6 @@ from flask_user import *
 from flask_gravatar import Gravatar
 import flask_menu as menu
 from flask_mail import Mail
-from flaskext.markdown import Markdown
 from flask_github import GitHub
 from flask_wtf.csrf import CsrfProtect
 from flask_flatpages import FlatPages
@@ -35,7 +34,6 @@ app.config.from_pyfile(os.environ["FLASK_CONFIG"])
 r = redis.Redis.from_url(app.config["REDIS_URL"])
 
 menu.Menu(app=app)
-markdown = Markdown(app, extensions=["fenced_code"], safe_mode=True, output_format="html5")
 github = GitHub(app)
 csrf = CsrfProtect(app)
 mail = Mail(app)
@@ -59,6 +57,10 @@ if not app.debug and app.config["MAIL_UTILS_ERROR_SEND_TO"]:
        register_mail_error_handler(app, mail)
 
 
+from .markdown import init_app
+init_app(app)
+
+
 @babel.localeselector
 def get_locale():
        return request.accept_languages.best_match(app.config['LANGUAGES'].keys())
index 37ea992178b08d46118d7b55acc76a75135204f9..0036fa9179a20d759e6c35ec13219bc3503d6dc8 100644 (file)
@@ -18,7 +18,7 @@
 from flask import *
 from flask_user import *
 from flask_login import login_user, logout_user
-from app import markdown
+from app.markdown import render_markdown
 from . import bp
 from app.models import *
 from flask_wtf import FlaskForm
@@ -153,7 +153,7 @@ def send_email(username):
        form = SendEmailForm(request.form)
        if form.validate_on_submit():
                text = form.text.data
-               html = markdown(text)
+               html = render_markdown(text)
                task = sendEmailRaw.delay([user.email], form.subject.data, text, html)
                return redirect(url_for("tasks.check", id=task.id, r=next_url))
 
diff --git a/app/markdown.py b/app/markdown.py
new file mode 100644 (file)
index 0000000..370d3bb
--- /dev/null
@@ -0,0 +1,63 @@
+import bleach
+from markdown import Markdown
+from flask import Markup
+
+# Whitelist source: MIT
+#
+# https://github.com/Wenzil/mdx_bleach/blob/master/mdx_bleach/whitelist.py
+
+"""
+Default whitelist of allowed HTML tags. Any other HTML tags will be escaped or
+stripped from the text. This applies to the html output that Markdown produces.
+"""
+ALLOWED_TAGS = [
+       'ul',
+       'ol',
+       'li',
+       'p',
+       'pre',
+       'code',
+       'blockquote',
+       'h1',
+       'h2',
+       'h3',
+       'h4',
+       'h5',
+       'h6',
+       'hr',
+       'br',
+       'strong',
+       'em',
+       'a',
+       'img'
+]
+
+"""
+Default whitelist of attributes. It allows the href and title attributes for <a>
+tags and the src, title and alt attributes for <img> tags. Any other attribute
+will be stripped from its tag.
+"""
+ALLOWED_ATTRIBUTES = {
+       'a': ['href', 'title'],
+       'img': ['src', 'title', 'alt']
+}
+
+"""
+If you allow tags that have attributes containing a URI value
+(like the href attribute of an anchor tag,) you may want to adapt
+the accepted protocols. The default list only allows http, https and mailto.
+"""
+ALLOWED_PROTOCOLS = ['http', 'https', 'mailto']
+
+
+md = Markdown(extensions=["fenced_code"], output_format="html5")
+
+def render_markdown(source):
+       return bleach.clean(md.convert(source), \
+               tags=ALLOWED_TAGS, attributes=ALLOWED_ATTRIBUTES, \
+               styles=[], protocols=ALLOWED_PROTOCOLS)
+
+def init_app(app):
+       @app.template_filter()
+       def markdown(source):
+               return Markup(render_markdown(source))
index 0a4b2bfc8e0caa147fda88c94bf8e3b655ab78c4..77b84da21aef690e076a624062b1106ab0d01867 100644 (file)
                                </ul>
                        </div>
 
-                       <div class="card my-4"">
+                       <div class="card my-4">
                                <div class="card-header">
                                        {% if package.approved and package.checkPerm(current_user, "CREATE_THREAD") %}
                                                <div class="btn-group float-right">
index e51f4ec4e0b317584b49759723cb8bef793de283..87e142f41048e50daaf3e42b30de4fe708447b4a 100644 (file)
@@ -60,7 +60,7 @@ Topics to be Added
                        {% set perc = 100 * (total - topic_count) /  total %}
                        <div class="progress-bar bg-success" role="progressbar"
                                style="width: {{ perc }}%" aria-valuenow="{{ perc }}" aria-valuemin="0" aria-valuemax="100"></div>
-               </div>  
+               </div>
        {% else %}
                <p>
                        The forum topic crawler needs to run at least once for this section to work.
index 9473f9f809254b89b13d70bb2b3384d3716e99a3..104755b8c256064836a85bce52035bf24ef777ad 100644 (file)
@@ -2,7 +2,6 @@ Flask~=1.1
 Flask-FlatPages~=0.7
 Flask-Gravatar~=0.5
 Flask-Login~=0.4.1
-Flask-Markdown~=0.3
 Flask-Menu~=0.7
 Flask-Migrate~=2.3
 Flask-SQLAlchemy~=2.3
@@ -11,6 +10,9 @@ Flask-Babel
 GitHub-Flask~=3.2
 SQLAlchemy-Searchable~=1.1
 
+markdown ~= 3.1
+bleach ~= 3.1
+
 beautifulsoup4~=4.6
 celery~=4.4
 kombu~=4.6