SQL注入。 如果使用 Django 的对象关系映射器 (ORM) 层,则基本上可以防止 SQL 注入。
唯一需要注意的是,您需要避免使用字符串连接手动形成 SQL 查询。例如,不要使用原始 SQL 查询(例如raw()
)。同样,不要使用extra()
方法/修饰符来注入原始 SQL。不要直接执行自定义 SQL;如果你绕过 Django 的 ORM 层,你就绕过了它对 SQL 注入的保护。
CSRF。Django 内置的 CSRF 保护很好。确保启用它并在任何地方使用它。Django 提供了在本地或全局禁用它的方法;显然,不要那样做。
确保 GET 请求没有任何副作用很重要。对于可能产生副作用的请求,请确保使用 POST 请求(并且不要接受 GET 请求)。这是标准的网页设计,但有些开发者搞砸了;Django 内置的 CSRF 预防假设你做对了。
如果您有子域,有一些注意事项(例如,您的 Web 应用程序托管在www.example.com
其中,并且有一个子域alice.example.com
托管用户控制的内容);在这种情况下,内置的 CSRF 保护可能不够用。由于多种原因,这是一个棘手的案例。大多数 Web 应用程序不必担心这些警告。
跨站脚本。如果您使用 Django 的模板系统并确保启用了自动转义,那么您已经完成了 95% 的工作。Django 为停止 XSS 提供了一种自动转义机制:它会自动转义动态插入到模板中的数据,如果它还没有被转义(例如,请参见mark_safe
、safe
等)。这种机制是个好东西,但它本身还不够。阻止 XSS 需要您采取很多方法,但您仍然必须注意一些问题。
特别是,对于大多数 HTML 上下文,Django 的自动转义将充分转义数据,但在某些特殊情况下,您必须手动进行额外的转义:
确保引用插入动态数据的所有属性。好:<img alt="{{foo}}" ...>
。坏:<img alt={{foo}} ...>
。对于未引用的属性值,Django 的自动转义是不够的。
对于插入 CSS(style
标签和属性)或 Javascript(script
块、事件处理程序和onclick
/etc. 属性)的数据,您必须使用适用于 CSS 或 Javascript 的转义规则手动转义数据。
对于插入到需要 URL 的属性中的数据(例如 , a href
)img src
,您必须手动验证 URL 以确保它是安全的。您需要根据允许协议的白名单检查协议(例如,、、、、等http:
——https:
但绝对不是)。mailto:
ftp:
javascript:
对于插入评论中的数据,您必须做一些额外的事情来逃避-
s。实际上,更好的是,不要在 HTML 注释中插入动态数据;那是 HTML 的一个不起眼的角落,它只是要求一些微妙的问题。(类似地,不要将动态数据插入到用户输入出现疯狂的属性中(例如,foo class=...
)。)
您仍然必须单独避免客户端 XSS(也称为基于 DOM 的 XSS);Django 无法帮助您解决这个问题。您可以阅读Adam Barth 关于避免 XSS 的建议,了解一些有助于避免客户端 XSS 的指南。
如果你mark_safe
过去手动告诉 Django 一些数据已经被转义并且是安全的,那么你最好知道你在做什么,而且最好是安全的。如果你不知道自己在做什么,这里很容易出错。例如,如果您以编程方式生成 HTML,将其存储到数据库中,然后将其发送回客户端(显然未转义),则很容易出错;你自己一个人,自动转义对你没有帮助。
你必须为这些情况做一些额外的事情的原因是 Django 的自动转义功能使用了一个应该是一刀切的转义函数,但实际上,一种尺寸并不总是适合所有情况; 在某些情况下,您需要自己做一些额外的事情。
有关在这些特殊上下文中使用哪些转义规则的更多信息,请参阅 OWASP XSS 备忘单。
其他的东西。还有一些你没有提到的事情:
想要查询更多的信息。请参阅Django 关于安全性的文档,包括Django 书中关于安全性的章节。