[SECURITY] Rewrite all links in rich texts

This commit is contained in:
Raphael Michel
2017-08-21 13:35:34 +02:00
parent c38a850294
commit 4bae0d1b81
2 changed files with 28 additions and 1 deletions

View File

@@ -1,6 +1,12 @@
import urllib.parse
import bleach
import markdown
from bleach import DEFAULT_CALLBACKS
from django import template
from django.core import signing
from django.urls import reverse
from django.utils.http import is_safe_url
from django.utils.safestring import mark_safe
register = template.Library()
@@ -42,6 +48,15 @@ ALLOWED_ATTRIBUTES = {
}
def safelink_callback(attrs, new=False):
url = attrs.get((None, 'href'), '/')
if not is_safe_url(url):
signer = signing.Signer(salt='safe-redirect')
attrs[None, 'href'] = reverse('redirect') + '?url=' + urllib.parse.quote(signer.sign(url))
attrs[None, 'target'] = '_blank'
return attrs
@register.filter
def rich_text(text: str, **kwargs):
"""
@@ -52,5 +67,5 @@ def rich_text(text: str, **kwargs):
markdown.markdown(text),
tags=ALLOWED_TAGS,
attributes=ALLOWED_ATTRIBUTES,
))
), callbacks=DEFAULT_CALLBACKS + [safelink_callback])
return mark_safe(body_md)

View File

@@ -66,6 +66,18 @@ class EventMiddlewareTest(EventTestMixin, SoupTest):
class ItemDisplayTest(EventTestMixin, SoupTest):
def test_link_rewrite(self):
q = Quota.objects.create(event=self.event, name='Quota', size=2)
item = Item.objects.create(event=self.event, name='Early-bird ticket', default_price=0, active=True,
description="http://example.org [Sample](http://example.net)")
q.items.add(item)
html = self.client.get('/%s/%s/' % (self.orga.slug, self.event.slug)).rendered_content
self.assertNotIn('href="http://example.org', html)
self.assertNotIn('href="http://example.net', html)
self.assertIn('href="/redirect/?url=http%3A//example.org%3A', html)
self.assertIn('href="/redirect/?url=http%3A//example.net%3A', html)
def test_not_active(self):
q = Quota.objects.create(event=self.event, name='Quota', size=2)
item = Item.objects.create(event=self.event, name='Early-bird ticket', default_price=0, active=False)