Don't allow HTML in tags.

master
Pacman Ghost 4 years ago
parent a892ac62d0
commit 71d99f8837
  1. 16
      asl_articles/articles.py
  2. 16
      asl_articles/publications.py
  3. 4
      asl_articles/tests/test_search.py
  4. 27
      asl_articles/tests/test_tags.py
  5. 7
      asl_articles/utils.py

@ -12,8 +12,8 @@ from asl_articles.authors import do_get_authors
from asl_articles.scenarios import do_get_scenarios
from asl_articles.tags import do_get_tags
from asl_articles import search
from asl_articles.utils import get_request_args, clean_request_args, encode_tags, decode_tags, apply_attrs, \
make_ok_response
from asl_articles.utils import get_request_args, clean_request_args, clean_tags, encode_tags, decode_tags, \
apply_attrs, make_ok_response
_logger = logging.getLogger( "db" )
@ -67,8 +67,12 @@ def create_article():
)
warnings = []
updated = clean_request_args( vals, _FIELD_NAMES, warnings, _logger )
# NOTE: Tags are stored in the database using \n as a separator, so we need to encode *after* cleaning them.
vals[ "article_tags" ] = encode_tags( vals.get( "article_tags" ) )
cleaned_tags = clean_tags( vals.get("article_tags"), warnings )
vals[ "article_tags" ] = encode_tags( cleaned_tags )
if cleaned_tags != vals.get( "article_tags" ):
updated[ "article_tags" ] = decode_tags( vals["article_tags"] )
# create the new article
vals[ "time_created" ] = datetime.datetime.now()
@ -200,8 +204,12 @@ def update_article():
)
warnings = []
updated = clean_request_args( vals, _FIELD_NAMES, warnings, _logger )
# NOTE: Tags are stored in the database using \n as a separator, so we need to encode *after* cleaning them.
vals[ "article_tags" ] = encode_tags( vals.get( "article_tags" ) )
cleaned_tags = clean_tags( vals.get("article_tags"), warnings )
vals[ "article_tags" ] = encode_tags( cleaned_tags )
if cleaned_tags != vals.get( "article_tags" ):
updated[ "article_tags" ] = decode_tags( vals["article_tags"] )
# update the article
article = Article.query.get( article_id )

@ -10,8 +10,8 @@ from asl_articles import app, db
from asl_articles.models import Publication, PublicationImage, Article
from asl_articles.tags import do_get_tags
from asl_articles import search
from asl_articles.utils import get_request_args, clean_request_args, encode_tags, decode_tags, apply_attrs, \
make_ok_response
from asl_articles.utils import get_request_args, clean_request_args, clean_tags, encode_tags, decode_tags, \
apply_attrs, make_ok_response
_logger = logging.getLogger( "db" )
@ -75,8 +75,12 @@ def create_publication():
)
warnings = []
updated = clean_request_args( vals, _FIELD_NAMES, warnings, _logger )
# NOTE: Tags are stored in the database using \n as a separator, so we need to encode *after* cleaning them.
vals[ "pub_tags" ] = encode_tags( vals.get( "pub_tags" ) )
cleaned_tags = clean_tags( vals.get("pub_tags"), warnings )
vals[ "pub_tags" ] = encode_tags( cleaned_tags )
if cleaned_tags != vals.get( "pub_tags" ):
updated[ "pub_tags" ] = decode_tags( vals["pub_tags"] )
# create the new publication
vals[ "time_created" ] = datetime.datetime.now()
@ -131,8 +135,12 @@ def update_publication():
)
warnings = []
updated = clean_request_args( vals, _FIELD_NAMES, warnings, _logger )
# NOTE: Tags are stored in the database using \n as a separator, so we need to encode *after* cleaning them.
vals[ "pub_tags" ] = encode_tags( vals.get( "pub_tags" ) )
cleaned_tags = clean_tags( vals.get("pub_tags"), warnings )
vals[ "pub_tags" ] = encode_tags( cleaned_tags )
if cleaned_tags != vals.get( "pub_tags" ):
updated[ "pub_tags" ] = decode_tags( vals["pub_tags"] )
# update the publication
pub = Publication.query.get( pub_id )

@ -286,7 +286,7 @@ def test_html_stripping( webdriver, flask_app, dbconn ):
"edition": "75<u>L</u>",
"description": "This is some <b>bold text</b>, this is <i>italic</i>.",
"tags": [ "+<b>bold</b>", "+<i>italic</i>" ]
} )
}, toast_type="warning" )
create_article( {
"title": "An <i>italic</i> article",
"subtitle": "A <b>bold</b> subtitle",
@ -294,7 +294,7 @@ def test_html_stripping( webdriver, flask_app, dbconn ):
"tags": [ "+<b>bold</b>", "+<i>italic</i>" ],
"scenarios": [ "+<b>bold</b> [B1]", "+<i>italic</i> [I1]" ],
"snippet": "This is some <b>bold text</b>, this is <i>italic</i>."
} )
}, toast_type="warning" )
# check if the search index contains any HTML
def is_html_clean( val ):

@ -73,6 +73,33 @@ def test_tags( webdriver, flask_app, dbconn ):
# ---------------------------------------------------------------------
def test_clean_html( webdriver, flask_app, dbconn ):
"""Test cleaning HTML from tags."""
# initialize
init_tests( webdriver, flask_app, dbconn )
# try to create a publication with HTML tags
create_publication( {
"name": "test publication",
"tags": [ "+<b>bold</b>" ]
}, toast_type="warning" )
_check_tags( flask_app, {
"test publication": [ "bold" ]
} )
# try to create an article with HTML tags
create_article( {
"title": "test article",
"tags": [ "+<i>italic</i>" ]
}, toast_type="warning" )
_check_tags( flask_app, {
"test publication": [ "bold" ],
"test article": [ "italic" ]
} )
# ---------------------------------------------------------------------
def _check_tags( flask_app, expected ):
"""Check the tags in the UI and database."""

@ -122,6 +122,13 @@ def load_html_whitelists( app ):
# ---------------------------------------------------------------------
def clean_tags( tags, warnings ):
"""Remove HTML from tags."""
cleaned_tags = [ clean_html( t, allow_tags=[], safe_attrs=[] ) for t in tags ]
if cleaned_tags != tags:
warnings.append( "Some values had HTML removed." )
return cleaned_tags
def encode_tags( tags ):
"""Encode tags prior to storing them in the database."""
if not tags:

Loading…
Cancel
Save