morlandi / django-ajax-datatable

A Django app which provides the integration of a Django project with the jQuery Javascript library DataTables.net
MIT License
208 stars 64 forks source link

Discuss HTML injection in the documentation #19

Closed PetrDlouhy closed 2 years ago

PetrDlouhy commented 3 years ago

The table doesn't prevent HTML injection in any way. So everything is left on the implementator. It should be at least mentioned in the documentation with solution (I found it by using customize_row and from django.utils.html import escape).

morlandi commented 3 years ago

That's a good point! Mentioning it in the documentation is the bare minimum ... but I'ld like to be safer ;) I'm not applying mark_safe() explicitly anywhere in the library; still, customized HTML content is sent unescaped to datatable.net. What do you suggest?

PetrDlouhy commented 3 years ago

Well, django-ajax-datatable could escape all string sent to datatable.net unless it is explicitly allowed in column_defs by something like allow_html. It would break current implementations, but maybe it is worth it.

You should also consider using HTML in the title - it should be generally safer, but I can imagine such implementations, where would be user data even in titles.

r1bnc commented 3 years ago

Referencing this issue for the html problem: https://github.com/morlandi/django-ajax-datatable/issues/18#issuecomment-817066311

r1bnc commented 2 years ago

Quick fix to escape column and row data:

from django.utils.html import escape

class MyModelAjaxDatatableView(AjaxDatatableView):
    ...
    def render_column(self, row, column):
        value = escape(self.column_obj(column).render_column(row))
        return value

    # Escape HTML on Row Data
    def render_row_details(self, pk, request=None):
        obj = self.model.objects.get(pk=pk)

        fields = [f.name for f in self.model._meta.get_fields() if f.concrete]
        html = '<table class="row-details">'
        for field in fields:
            try:
                # Escape HTML on Value
                value = escape(getattr(obj, field))
                html += '<tr><td>%s</td><td>%s</td></tr>' % (field, value)
            except:
                pass
        html += '</table>'
        return html
morlandi commented 2 years ago

See also #61

Thank you @r1bnc .. however, I would rather act "python side" and will check and merge #62 instead.

I will close this issue, but please feel free to reopen it if you think thang #62 is not enought