diff --git a/CHANGELOG.md b/CHANGELOG.md index 733e9c0c..b7284caa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,35 @@ Records breaking changes from major version bumps +## 22.0.0 + +PR: [#286](https://github.com/alphagov/digitalmarketplace-utils/pull/286) + +### What changed + +We used to be able to use a `|markdown` filter in our jinja templates which would turn markdown formatted strings into [Markup](http://jinja.pocoo.org/docs/dev/api/#jinja2.Markup) strings as well as permit HTML tags. +This opened us up to vulnerabilities where untrusted input might end up going through one of these filters and expose us to a cross-site scripting (XSS) exploit. + +Going forward, markdown formatted text will be allowed in specific fields (documented in the [README for digitalmarketplace-frameworks](https://github.com/alphagov/digitalmarketplace-frameworks/blob/4c0502379910d8248f062b8aaf35fc58ce912370/README.md#template-fields)) and then rendered by TemplateFields, handled by the Content Loader. + +### Example app change + +Old: +```jinja + +

Question name: {{ question.name|markdown }}

+ +``` + +New: +```jinja + + +

Question name: {{ question.name }}

+ +``` + + ## 21.0.0 PR: [#266](https://github.com/alphagov/digitalmarketplace-utils/pull/266) diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..cb825994 --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +SHELL := /bin/bash +VIRTUALENV_ROOT := $(shell [ -z $$VIRTUAL_ENV ] && echo $$(pwd)/venv || echo $$VIRTUAL_ENV) + +virtualenv: + [ -z $$VIRTUAL_ENV ] && [ ! -d venv ] && virtualenv venv || true + +requirements_for_test: virtualenv requirements_for_test.txt + ${VIRTUALENV_ROOT}/bin/pip install -r requirements_for_test.txt + +test: show_environment test_pep8 test_python + +test_pep8: virtualenv + ${VIRTUALENV_ROOT}/bin/pep8 . + +test_python: virtualenv + ${VIRTUALENV_ROOT}/bin/py.test ${PYTEST_ARGS} + +show_environment: + @echo "Environment variables in use:" + @env | grep DM_ || true + +.PHONY: virtualenv requirements_for_test test_pep8 test_python show_environment diff --git a/dmutils/__init__.py b/dmutils/__init__.py index d961b51d..299ea468 100644 --- a/dmutils/__init__.py +++ b/dmutils/__init__.py @@ -3,4 +3,4 @@ import flask_featureflags -__version__ = '21.11.0' +__version__ = '22.0.0' diff --git a/dmutils/filters.py b/dmutils/filters.py index 71759c2c..88cdb4d1 100644 --- a/dmutils/filters.py +++ b/dmutils/filters.py @@ -1,13 +1,8 @@ from __future__ import unicode_literals import re -from markdown import markdown from flask import Markup -def markdown_filter(text, *args, **kwargs): - return markdown(text, ['markdown.extensions.abbr'], *args, **kwargs) - - def smartjoin(input): list_to_join = list(input) if len(list_to_join) > 1: diff --git a/dmutils/flask_init.py b/dmutils/flask_init.py index 4c1e266e..83c1f823 100644 --- a/dmutils/flask_init.py +++ b/dmutils/flask_init.py @@ -1,7 +1,6 @@ import os from flask_featureflags.contrib.inline import InlineFeatureFlag from . import config, logging, proxy_fix, request_id, formats, filters -from flask import Markup from flask.ext.script import Manager, Server @@ -47,9 +46,6 @@ def add_header(response): response.headers['X-Frame-Options'] = 'DENY' return response - @application.template_filter('markdown') - def markdown_filter_flask(data): - return Markup(filters.markdown_filter(data)) application.add_template_filter(filters.format_links) application.add_template_filter(formats.timeformat) application.add_template_filter(formats.shortdateformat) diff --git a/requirements.txt b/requirements.txt index 097daab1..986eaadc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,7 +10,6 @@ mandrill==1.0.57 monotonic==0.3 pytz==2015.4 Flask-WTF==0.12 -markdown==2.6.2 Flask-Script==2.0.5 workdays==1.4 unicodecsv==0.14.1 diff --git a/tests/test_filters.py b/tests/test_filters.py index b6950fc1..3fb3c1ff 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -1,35 +1,6 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from dmutils.filters import markdown_filter, smartjoin, format_links - - -def test_markdown_filter_produces_markup(): - - markdown_string = """## H2 title - -- List item 1 -- List item 2 - -Paragraph -**Bold** -*Emphasis* - -HTML is an abbreviation. - -*[HTML]: Hyper Text Markup Language -""" - - html_string = """

H2 title

- -

Paragraph -Bold -Emphasis

-

HTML is an abbreviation.

""" - - assert markdown_filter(markdown_string) == html_string +from dmutils.filters import smartjoin, format_links def test_smartjoin_for_more_than_one_item():