Skip to content

Commit 1c3f1a2

Browse files
committed
Remove support for HTML in panel titles
This features was used by a single panel only and has the potential for mistakenly introducing XSS vulnerabilities. Support for HTML in titles first appeared in 5015057.
1 parent 067ba88 commit 1c3f1a2

File tree

4 files changed

+85
-3
lines changed

4 files changed

+85
-3
lines changed

debug_toolbar/panels/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class SettingsPanel(Panel):
2424
nav_title = _("Settings")
2525

2626
def title(self):
27-
return _("Settings from <code>%s</code>") % settings.SETTINGS_MODULE
27+
return _("Settings from %s") % settings.SETTINGS_MODULE
2828

2929
def generate_stats(self, request, response):
3030
self.record_stats(

debug_toolbar/templates/debug_toolbar/includes/panel_content.html

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<div id="{{ panel.panel_id }}" class="djdt-panelContent">
55
<div class="djDebugPanelTitle">
66
<a href="" class="djDebugClose">×</a>
7-
<h3>{{ panel.title|safe }}</h3>
7+
<h3>{{ panel.title }}</h3>
88
</div>
99
<div class="djDebugPanelContent">
1010
{% if toolbar.store_id %}
@@ -16,4 +16,3 @@ <h3>{{ panel.title|safe }}</h3>
1616
</div>
1717
</div>
1818
{% endif %}
19-

tests/panels/test_custom.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from django.test import override_settings
2+
3+
from debug_toolbar.panels import Panel
4+
5+
from ..base import IntegrationTestCase
6+
7+
8+
class CustomPanel(Panel):
9+
def title(self):
10+
return "Title with special chars &\"'<>"
11+
12+
13+
@override_settings(
14+
DEBUG=True, DEBUG_TOOLBAR_PANELS=["tests.panels.test_custom.CustomPanel"]
15+
)
16+
class CustomPanelTestCase(IntegrationTestCase):
17+
def test_escapes_panel_title(self):
18+
response = self.client.get("/regular/basic/")
19+
self.assertContains(
20+
response,
21+
"""
22+
<li class="djDebugPanelButton djdt-CustomPanel">
23+
<input type="checkbox" checked title="Disable for next and successive requests" data-cookie="djdtCustomPanel">
24+
<a class="CustomPanel" href="#" title="Title with special chars &amp;&quot;&#39;&lt;&gt;">
25+
Title with special chars &amp;&quot;&#39;&lt;&gt;
26+
</a>
27+
</li>
28+
""",
29+
html=True,
30+
)
31+
self.assertContains(
32+
response,
33+
"""
34+
<div id="CustomPanel" class="djdt-panelContent">
35+
<div class="djDebugPanelTitle">
36+
<a href="" class="djDebugClose">×</a>
37+
<h3>Title with special chars &amp;&quot;&#39;&lt;&gt;</h3>
38+
</div>
39+
<div class="djDebugPanelContent">
40+
<img class="djdt-loader" src="/static/debug_toolbar/img/ajax-loader.gif" alt="loading">
41+
<div class="djdt-scroll"></div>
42+
</div>
43+
</div>
44+
""",
45+
html=True,
46+
)

tests/panels/test_settings.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from django.test import override_settings
2+
3+
from ..base import IntegrationTestCase
4+
5+
6+
@override_settings(DEBUG=True)
7+
class SettingsIntegrationTestCase(IntegrationTestCase):
8+
def test_panel_title(self):
9+
response = self.client.get("/regular/basic/")
10+
# The settings module is None due to using Django's UserSettingsHolder
11+
# in tests.
12+
self.assertContains(
13+
response,
14+
"""
15+
<li class="djDebugPanelButton djdt-SettingsPanel">
16+
<input type="checkbox" checked title="Disable for next and successive requests" data-cookie="djdtSettingsPanel">
17+
<a class="SettingsPanel" href="#" title="Settings from None">Settings</a>
18+
</li>
19+
""",
20+
html=True,
21+
)
22+
self.assertContains(
23+
response,
24+
"""
25+
<div id="SettingsPanel" class="djdt-panelContent">
26+
<div class="djDebugPanelTitle">
27+
<a href="" class="djDebugClose">×</a>
28+
<h3>Settings from None</h3>
29+
</div>
30+
<div class="djDebugPanelContent">
31+
<img class="djdt-loader" src="/static/debug_toolbar/img/ajax-loader.gif" alt="loading">
32+
<div class="djdt-scroll"></div>
33+
</div>
34+
</div>
35+
""",
36+
html=True,
37+
)

0 commit comments

Comments
 (0)