XSS prevention added (with tests)
This commit is contained in:
@@ -15,7 +15,7 @@ Dieses Dokument bietet einen umfassenden Überblick über alle Tests im vgui-cic
|
||||
|
||||
## abschnitte App Tests
|
||||
|
||||
Die abschnitte App enthält 32 Tests, die Modelle, Utility-Funktionen, Diagram-Caching und Management-Befehle abdecken.
|
||||
Die abschnitte App enthält 33 Tests, die Modelle, Utility-Funktionen, Diagram-Caching, Management-Befehle und Sicherheit abdecken.
|
||||
|
||||
### Modell-Tests
|
||||
|
||||
@@ -58,6 +58,7 @@ Die abschnitte App enthält 32 Tests, die Modelle, Utility-Funktionen, Diagram-C
|
||||
- **test_render_text_with_footnotes**: Verarbeitet Text, der Fußnoten enthält
|
||||
- **test_render_abschnitt_without_type**: Behandelt Textabschnitte ohne AbschnittTyp
|
||||
- **test_render_abschnitt_with_empty_content**: Behandelt Textabschnitte mit leerem Inhalt
|
||||
- **test_render_textabschnitte_xss_prevention**: Überprüft, dass bösartiger HTML-Code und Skript-Tags aus gerenderten Inhalten bereinigt werden, um XSS-Angriffe zu verhindern
|
||||
|
||||
### Diagram-Caching-Tests
|
||||
|
||||
@@ -332,8 +333,8 @@ Die stichworte App enthält 18 Tests, die Schlüsselwortmodelle und ihre Sortier
|
||||
|
||||
## Test-Statistiken
|
||||
|
||||
- **Gesamt-Tests**: 206
|
||||
- **abschnitte**: 32 Tests
|
||||
- **Gesamt-Tests**: 207
|
||||
- **abschnitte**: 33 Tests (einschließlich XSS-Prävention)
|
||||
- **dokumente**: 116 Tests (98 in tests.py + 9 in test_json.py + 9 JSON-Tests in Haupt-tests.py)
|
||||
- **pages**: 4 Tests
|
||||
- **referenzen**: 18 Tests
|
||||
@@ -348,6 +349,7 @@ Die stichworte App enthält 18 Tests, die Schlüsselwortmodelle und ihre Sortier
|
||||
4. **Utility-Funktionen**: Textverarbeitung, Caching, Formatierung
|
||||
5. **Management-Befehle**: CLI-Schnittstelle und Ausgabeverarbeitung
|
||||
6. **Integration**: App-übergreifende Funktionalität und Datenfluss
|
||||
7. **Sicherheit**: XSS-Prävention durch HTML-Bereinigung beim Rendern von Inhalten
|
||||
|
||||
## Ausführen der Tests
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ This document provides a comprehensive overview of all tests in the vgui-cicd Dj
|
||||
|
||||
## abschnitte App Tests
|
||||
|
||||
The abschnitte app contains 32 tests covering models, utility functions, diagram caching, and management commands.
|
||||
The abschnitte app contains 33 tests covering models, utility functions, diagram caching, management commands, and security.
|
||||
|
||||
### Model Tests
|
||||
|
||||
@@ -58,6 +58,7 @@ The abschnitte app contains 32 tests covering models, utility functions, diagram
|
||||
- **test_render_text_with_footnotes**: Processes text containing footnotes
|
||||
- **test_render_abschnitt_without_type**: Handles Textabschnitte without AbschnittTyp
|
||||
- **test_render_abschnitt_with_empty_content**: Handles Textabschnitte with empty content
|
||||
- **test_render_textabschnitte_xss_prevention**: Verifies that malicious HTML and script tags are sanitized from rendered content to prevent XSS attacks
|
||||
|
||||
### Diagram Caching Tests
|
||||
|
||||
@@ -332,8 +333,8 @@ The stichworte app contains 18 tests covering keyword models and their ordering.
|
||||
|
||||
## Test Statistics
|
||||
|
||||
- **Total Tests**: 206
|
||||
- **abschnitte**: 32 tests
|
||||
- **Total Tests**: 207
|
||||
- **abschnitte**: 33 tests (including XSS prevention)
|
||||
- **dokumente**: 116 tests (98 in tests.py + 9 in test_json.py + 9 JSON tests in main tests.py)
|
||||
- **pages**: 4 tests
|
||||
- **referenzen**: 18 tests
|
||||
@@ -348,6 +349,7 @@ The stichworte app contains 18 tests covering keyword models and their ordering.
|
||||
4. **Utility Functions**: Text processing, caching, formatting
|
||||
5. **Management Commands**: CLI interface and output handling
|
||||
6. **Integration**: Cross-app functionality and data flow
|
||||
7. **Security**: XSS prevention through HTML sanitization in content rendering
|
||||
|
||||
## Running the Tests
|
||||
|
||||
|
||||
@@ -28,12 +28,6 @@ DEBUG = True
|
||||
|
||||
ALLOWED_HOSTS = ["10.128.128.144","localhost","127.0.0.1","*"]
|
||||
|
||||
TEMPLATES = [
|
||||
{"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||
"APP_DIRS": True,
|
||||
}
|
||||
]
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
|
||||
@@ -467,6 +467,32 @@ A -> B
|
||||
typ, html = result[0]
|
||||
self.assertEqual(typ, "text")
|
||||
|
||||
def test_render_textabschnitte_xss_prevention(self):
|
||||
"""Test that malicious HTML is sanitized in rendered content"""
|
||||
from dokumente.models import VorgabeLangtext
|
||||
|
||||
# Create content with malicious HTML
|
||||
malicious_abschnitt = VorgabeLangtext.objects.create(
|
||||
abschnitt=self.vorgabe,
|
||||
abschnitttyp=self.typ_text,
|
||||
inhalt='<script>alert("xss")</script><img src=x onerror=alert(1)>Normal text',
|
||||
order=1
|
||||
)
|
||||
|
||||
result = render_textabschnitte(VorgabeLangtext.objects.filter(pk=malicious_abschnitt.pk))
|
||||
|
||||
self.assertEqual(len(result), 1)
|
||||
typ, html = result[0]
|
||||
self.assertEqual(typ, "text")
|
||||
|
||||
# Dangerous tags and attributes should be removed or sanitized
|
||||
self.assertNotIn('<script>', html) # Script tags should not be present unescaped
|
||||
self.assertNotIn('onerror', html) # Dangerous attributes removed
|
||||
# Note: 'alert' may still be present in escaped script tags, which is safe
|
||||
|
||||
# Safe content should remain
|
||||
self.assertIn('Normal text', html)
|
||||
|
||||
|
||||
class MdTableToHtmlTest(TestCase):
|
||||
"""Test cases for md_table_to_html function"""
|
||||
|
||||
@@ -4,12 +4,34 @@ import zlib
|
||||
import re
|
||||
from textwrap import dedent
|
||||
from django.conf import settings
|
||||
import bleach
|
||||
|
||||
# Import the caching function
|
||||
from diagramm_proxy.diagram_cache import get_cached_diagram
|
||||
|
||||
DIAGRAMMSERVER="/diagramm"
|
||||
|
||||
# Allowed HTML tags for bleach sanitization
|
||||
ALLOWED_TAGS = [
|
||||
'p', 'br', 'strong', 'em', 'u', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
|
||||
'ul', 'ol', 'li', 'blockquote', 'code', 'pre', 'hr',
|
||||
'table', 'thead', 'tbody', 'tr', 'th', 'td',
|
||||
'img', 'a', 'sup', 'sub', 'span', 'div'
|
||||
]
|
||||
|
||||
ALLOWED_ATTRIBUTES = {
|
||||
'img': ['src', 'alt', 'width', 'height'],
|
||||
'a': ['href', 'title'],
|
||||
'span': ['class'],
|
||||
'div': ['class'],
|
||||
'p': ['class'],
|
||||
'table': ['class'],
|
||||
'th': ['colspan', 'rowspan', 'class'],
|
||||
'td': ['colspan', 'rowspan', 'class'],
|
||||
'pre': ['class'],
|
||||
'code': ['class'],
|
||||
}
|
||||
|
||||
def render_textabschnitte(queryset):
|
||||
"""
|
||||
Converts a queryset of Textabschnitt-like models into a list of (typ, html) tuples.
|
||||
@@ -52,6 +74,8 @@ def render_textabschnitte(queryset):
|
||||
html += "</code></pre>"
|
||||
else:
|
||||
html = markdown(inhalt, extensions=['tables', 'attr_list','footnotes'])
|
||||
# Sanitize HTML to prevent XSS
|
||||
html = bleach.clean(html, tags=ALLOWED_TAGS, attributes=ALLOWED_ATTRIBUTES)
|
||||
output.append((typ, html))
|
||||
return output
|
||||
|
||||
|
||||
@@ -102,6 +102,7 @@
|
||||
<li><a href="/dokumente">Standards</a></li>
|
||||
{% if user.is_staff %}
|
||||
<li><a href="/dokumente/unvollstaendig/">Unvollständig</a></li>
|
||||
<li><a href="/autorenumgebung/">Autorenumgebung</a></li>
|
||||
{% endif %}
|
||||
<li><a href="/referenzen">Referenzen</a></li>
|
||||
<li><a href="/stichworte">Stichworte</a></li>
|
||||
@@ -131,6 +132,9 @@
|
||||
<li class="dropdown {% if 'unvollstaendig' in request.path %}current{% endif %}">
|
||||
<a href="/dokumente/unvollstaendig/">Unvollständig</a>
|
||||
</li>
|
||||
<li class="dropdown {% if 'autorenumgebung' in request.path %}current{% endif %}">
|
||||
<a href="/autorenumgebung/">Autorenumgebung</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class="dropdown {% if 'referenzen' in request.path %}current{% endif %}">
|
||||
<a href="/referenzen">Referenzen</a>
|
||||
|
||||
@@ -32,3 +32,4 @@ six==1.17.0
|
||||
sqlparse==0.5.3
|
||||
urllib3==2.5.0
|
||||
wcwidth==0.2.13
|
||||
bleach==6.1.0
|
||||
|
||||
Reference in New Issue
Block a user