django-fluent / django-fluent-comments

A modern, ajax-based appearance for django comments
https://django-fluent.org/
Apache License 2.0
182 stars 90 forks source link

Email on new comments has issues if comment contains bad content #112

Open the-mace opened 6 years ago

the-mace commented 6 years ago

On the latest version 2.0.2 I get this thanks to some hackers:

File "/usr/local/lib/python2.7/dist-packages/django_comments/views/comments.py" in post_comment 
130. request=request 

File "/usr/local/lib/python2.7/dist-packages/django/dispatch/dispatcher.py" in send 
191. response = receiver(signal=self, sender=sender, **named) 

File "/usr/local/lib/python2.7/dist-packages/fluent_comments/models.py" in on_comment_posted 
82. send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, recipient_list, fail_silently=True) 

File "/usr/local/lib/python2.7/dist-packages/django/core/mail/__init__.py" in send_mail 
62. return mail.send() 

File "/usr/local/lib/python2.7/dist-packages/django/core/mail/message.py" in send 
342. return self.get_connection(fail_silently).send_messages([self]) 

File "/usr/local/lib/python2.7/dist-packages/django_yubin/smtp_queue.py" in send_messages 
36. queue_email_message(email_message) 

File "/usr/local/lib/python2.7/dist-packages/django_yubin/__init__.py" in queue_email_message 
123. encoded_message=email_message.message().as_string()) 

File "/usr/local/lib/python2.7/dist-packages/django/core/mail/message.py" in message 
307. msg['Subject'] = self.subject 

File "/usr/local/lib/python2.7/dist-packages/django/core/mail/message.py" in __setitem__ 
232. name, val = forbid_multi_line_headers(name, val, self.encoding) 

File "/usr/local/lib/python2.7/dist-packages/django/core/mail/message.py" in forbid_multi_line_headers 
92. raise BadHeaderError("Header values can't contain newlines (got %r for header %r)" % (val, name)) 

Exception Type: BadHeaderError at /comments/post/ 
Exception Value: Header values can't contain newlines (got u'[SITE] New comment posted on "<script>alert(1)</script> <script>alert(1)</script>: <img src=x onerror=alert(1)>\r\n\r\ntest..."' for header u'Subject') 
Request information: 

Other than disabling the emails I don't see any way to block the bad content. I don't actually need to see the actual comment, just knowing there's one there is good enough.

vdboor commented 6 years ago

That's odd - how can these hackers point to that content_object?

The code uses:

content_object = comment.content_object
subject = u'[{0}] New comment posted on "{1}"'.format(site.name, content_object)

which means they've already managed to add a model somewhere, and then point to it by adding a comment. Adding a <script> to the subject would target vulnerable webmail clients (as Django already escapes HTML in templates)

One thing is clear, the Django comments post data needs better checks to avoid linking to random models.

vdboor commented 6 years ago

I've made some improvements in the 'master' branch to enable the comment moderator by default.

This also allows to reject comments to unregistered models (FLUENT_COMMENTS_DEFAULT_MODERATOR = 'deny', and call moderate_model() on any model you'd allow comments to be posted at)