在 Python 中允许 Markdown,同时防止 XSS 攻击的最佳实践?

发布于 2024-10-21 22:16:33 字数 370 浏览 6 评论 0原文

我需要让用户将 Markdown 内容输入到我的 Web 应用程序中,该应用程序具有 Python 后端。我不想不必要地限制他们的条目(例如不允许任何 HTML,这违背了 Markdown 的精神和规范),但显然我需要防止跨站脚本(XSS)攻击。

我不可能是第一个遇到这个问题的人,但没有看到任何带有所有关键字“python”、“Markdown”和“XSS”的问题,所以这里是。

使用 Python 库处理 Markdown 和防止 XSS 攻击的最佳实践方法是什么? (支持 PHP Markdown Extra 语法的奖励积分。)

I need to let users enter Markdown content to my web app, which has a Python back end. I don’t want to needlessly restrict their entries (e.g. by not allowing any HTML, which goes against the spirit and spec of Markdown), but obviously I need to prevent cross-site scripting (XSS) attacks.

I can’t be the first one with this problem, but didn’t see any SO questions with all the keywords “python,” “Markdown,” and “XSS”, so here goes.

What’s a best-practice way to process Markdown and prevent XSS attacks using Python libraries? (Bonus points for supporting PHP Markdown Extra syntax.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

﹏雨一样淡蓝的深情 2024-10-28 22:16:33

我无法确定“最佳实践”,但通常在接受 Markdown 输入时您有三种选择:

  1. 在 Markdown 内容中允许 HTML(这是 Markdown 最初/官方的工作方式,但如果天真地对待,这可能会引发 XSS 攻击) .

  2. 只需将任何 HTML 视为纯文本,本质上是让您的 Markdown 处理器转义用户的输入。因此,输入中的 ... 不会创建小文本,而是创建文字文本“...”。

  3. 丢弃 Markdown 中的所有 HTML 标签。这对用户来说非常不利,并且可能会因 <3 等文本而阻塞,具体取决于实现。这是 Stack Overflow 上采用的方法。

我的问题具体涉及案例#1。

鉴于此,对我来说效果很好的是通过

  1. Markdown for Python 发送用户输入a>,可选支持额外语法,然后通过
  2. < a href="https://github.com/html5lib" rel="noreferrer">html5lib 的清理程序

我对这个组合进行了一系列 XSS 攻击尝试,但都失败了(万岁!);但使用像 这样的良性标签可以完美地工作。

这样,您实际上可以使用选项 #1(根据需要),但潜在危险或格式错误的 HTML 片段除外,这些片段将按选项 #2 进行处理。

(感谢 YH Wong 为我指明了 Markdown 库的方向!)

I was unable to determine “best practice,” but generally you have three choices when accepting Markdown input:

  1. Allow HTML within Markdown content (this is how Markdown originally/officially works, but if treated naïvely, this can invite XSS attacks).

  2. Just treat any HTML as plain text, essentially letting your Markdown processor escape the user’s input. Thus <small>…</small> in input will not create small text but rather the literal text “<small>…</small>”.

  3. Throw out all HTML tags within Markdown. This is pretty user-hostile and may choke on text like <3 depending on implementation. This is the approach taken here on Stack Overflow.

My question regards case #1, specifically.

Given that, what worked well for me is sending user input through

  1. Markdown for Python, which optionally supports Extra syntax and then through
  2. html5lib’s sanitizer.

I threw a bunch of XSS attack attempts at this combination, and all failed (hurray!); but using benign tags like <strong> worked flawlessly.

This way, you are in effect going with option #1 (as desired) except for potentially dangerous or malformed HTML snippets, which are treated as in option #2.

(Thanks to Y.H Wong for pointing me in the direction of that Markdown library!)

浅笑轻吟梦一曲 2024-10-28 22:16:33

Python 中的 Markdown 可能就是您正在寻找的。它似乎也涵盖了您请求的许多扩展

为了防止 XSS 攻击,首选的方法与其他语言完全相同 - 在渲染回来时转义用户输出。我刚刚浏览了 文档代码。 Markdown 似乎能够通过一些简单的配置调整来开箱即用。

Markdown in Python is probably what you are looking for. It seems to cover a lot of your requested extensions too.

To prevent XSS attacks, the preferred way to do it is exactly the same as other languages - you escape the user output when rendered back. I just took a peek at the documentation and the source code. Markdown seems to be able to do it right out of the box with some trivial config tweaks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文