为啥以及何时使用 Django mark_safe() 函数

Posted

技术标签:

【中文标题】为啥以及何时使用 Django mark_safe() 函数【英文标题】:Why and When to use Django mark_safe() function为什么以及何时使用 Django mark_safe() 函数 【发布时间】:2015-12-24 07:34:04 【问题描述】:

看完文档,mark_safe()的作用还不清楚。我想这与 CSRF 的东西有关。但是为什么以及何时应该使用 mark_safe()?

这是文档

mark_safe(s)

明确将字符串标记为对 (html) 安全 输出目的。返回的对象可以在任何地方使用字符串 或 unicode 对象是合适的。

可以在一个字符串上多次调用。

为了构建 HTML 片段,您通常应该使用 django.utils.html.format_html() 代替。

如果被修改,标记为安全的字符串将再次变得不安全。例如:

【问题讨论】:

何时可以信任内容。即不是用户提交的 HTML。 文档没有提到 CSRF,所以我不知道你为什么会认为它与它有关。 【参考方案1】:

Django 是一个框架,它默认尝试做“正确”的事情。这意味着,当您做最简单的事情时,您很可能在做正确的事情。

现在让我们看一下php和python中的一些模板:

PHP:

<? echo $foo ?>

可能会给:

<script src="evil">

姜戈:

 foo 

给出相同的输入:

&gt;script src="evil"&lt;

现在假设,您想放置一个链接&lt;a href="link"&gt;text&lt;/a&gt;。然后 django 将再次使用&amp;lt;&amp;gt; 将其呈现为文本。如果您知道自己在做什么,您现在可以使用 mark_safe 来表明该文本是可信的(即不是来自用户输入)。

通常你会在你的模板中使用 foo|safe % autoescape off % foo % endautoescape %作为django程序员,当字符串被声明为安全时会更清楚。

那么,mark_safe 在哪里使用?当您编写自己的模板标签或过滤器时,您需要将字符串标记为对 python 安全,因为开发人员会假设 foo|mylinkifyfunction 做了正确的事情(即它转义了 url foo,但没有转义网址周围的&lt;a href=""&gt;&lt;/a&gt;)。

【讨论】:

那么,mark_safe是为了正确渲染<&gt等? mark_safe 告诉 django 模板应该从您的 python 代码中按原样使用字符串。通常这不是你想要的。这是一个example,其中python代码应该为模板输出&lt;br /&gt;,它不会被转义。 @day 它转义了 url foo,但没有转义 url 周围的 ,这行是什么意思?【参考方案2】:

还值得注意的是,在构建 HTML 代码片段时,建议使用 format_html(...) 函数而不是 mark_safe 并转义其所有参数。

所以,不要写:

mark_safe("%s <b>%s</b> %s" % (
    some_html,
    escape(some_text),
    escape(some_other_text),
))

你应该改用:

format_html(" <b></b> ",
    mark_safe(some_html),
    some_text,
    some_other_text,
)

这样做的好处是您无需将escape() 应用于每个参数,并且如果您忘记了一个错误和 XSS 漏洞的风险。

【讨论】:

以上是关于为啥以及何时使用 Django mark_safe() 函数的主要内容,如果未能解决你的问题,请参考以下文章

为啥以及何时使用重组分支?

何时以及为啥要使用 Java 同步? [复制]

为啥使用片段,以及何时使用片段而不是活动?

为啥以及何时使用 angular.copy? (深拷贝)

为啥以及何时应该在块的末尾使用逗号?

Grunt、Gulp.js 和 Bower 有啥区别?为啥以及何时使用它们?