1
0
mirror of https://github.com/django/django.git synced 2025-10-24 22:26:08 +00:00

Documented risk of XSS vulnerability when using Postgres headlines.

Because the default start and stop parameters are <b> and </b>
respectively, it is tempting to pass the headline value to the `safe`
template filter, to render the highlighted section of the headline in
bold. This is dangerous.

Also, tested the sanitation behavior of Postgres. If the undocumented
behavior of Postgres changes in this regard, we want to ensure that
Django's code and documentation is updated appropriately.
This commit is contained in:
David D Lowe
2024-08-27 14:22:50 +01:00
parent cdcd604ef8
commit bfc83d8ff9
2 changed files with 50 additions and 0 deletions

View File

@@ -7,6 +7,7 @@ transcript.
"""
from django.db.models import F, Value
from django.utils.safestring import SafeString
from . import PostgreSQLSimpleTestCase, PostgreSQLTestCase
from .models import Character, Line, LineSavedSearch, Scene
@@ -732,6 +733,42 @@ class SearchHeadlineTests(GrailTestData, PostgreSQLTestCase):
searched.headline,
)
def test_headline_sanitize_html(self):
dangerous_line = Line.objects.create(
scene=self.robin,
character=self.minstrel,
dialogue='Foobar <script>console.log("danger");</script>',
)
dangerous_line.full_clean()
searched = Line.objects.annotate(
headline=SearchHeadline(
"dialogue",
SearchQuery("Foobar", config="english"),
highlight_all=False,
),
).get(pk=dangerous_line.pk)
self.assertNotIsInstance(searched.headline, SafeString)
self.assertEqual(
searched.headline,
'<b>Foobar</b> console.log("danger"); ',
"When hightlight_all is False, PostgreSQL removes existing HTML tags",
)
searched = Line.objects.annotate(
headline=SearchHeadline(
"dialogue",
SearchQuery("Foobar", config="english"),
highlight_all=True,
),
).get(pk=dangerous_line.pk)
self.assertNotIsInstance(searched.headline, SafeString)
self.assertEqual(
searched.headline,
'<b>Foobar</b> <script>console.log("danger");</script>',
"When highlight_all is True, PostgreSQL riskily keeps existing HTML tags",
)
def test_headline_short_word_option(self):
self.check_default_text_search_config()
searched = Line.objects.annotate(