【问题标题】:How to prevent XSS attacks in Django REST API CharFields?如何防止 Django REST API CharFields 中的 XSS 攻击?
【发布时间】:2020-05-19 03:47:34
【问题描述】:

我目前正在开发一个使用 Django 2.2 和 djangorestframework 3.9.2 的应用程序。我知道 Django 本身提供了针对 SQL 注入的保护,或者在 django 模板 (XSS) 中显示内容的上下文中,但我注意到当我使用 Django REST API 时,我的模型中的所有 CharFields 都不会自动清理。

注意:这个问题不适用于 django 模板。

例如拥有直接消息模型 (message/models.py):

class Message(models.Model):
    sender = models.ForeignKey(...)
    receiver = models.ForeignKey(...)
    message = models.CharField(max_length=1200)
    timestamp = models.DateTimeField(...)
    is_read = models.BooleanField(default=False)

实际上并不阻止任何人发送内容为<script>alert("Hello there");</script> 的消息。它将保存在数据库中并由 REST API 按原样返回,允许远程运行任何 JS 脚本(基本上是跨站点脚本)。

这是预期的行为吗? 如何预防?

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    Django(或 DRF)不会转义任何进入数据库的 html/文本内容。文本仅在使用模板系统显示时被转义(除非它在某些时候被标记为安全)。

    这样做的原因是 Django 并不真正知道您将使用此文本做什么。对于某些用例,存储 HTML 可能非常好,包括脚本标签。

    如果您正在寻找一种在输入进入数据库之前对其进行清理的方法,我可以推荐 Mozilla 的 bleach 库:https://github.com/mozilla/bleach

    我没有使用过django-bleach (https://django-bleach.readthedocs.io/),但它似乎是一种将bleach 集成到Django 中的便捷方式。

    【讨论】:

    • 我早些时候发现了 django-bleach,但现在它似乎并不相关,虽然它工作正常,但测试都失败了,没有任何明确的原因(控制台说 TypeError: argument cannot be of 'NoneType' type, must be of text type 即使对于未由漂白剂处理的字段)。不过,您的回复确实回答了我的问题,谢谢。
    【解决方案2】:

    您可以在序列化程序的验证中使用escape() 方法:

    from django.utils.html import escape
    
    class MySerializer:
        def validate_myfield(self, value):
            return escape(value)
    

    【讨论】:

    • 这似乎是今天最相关的答案
    猜你喜欢
    • 2020-08-28
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多