关于 c#:Preventing XSS in user URL input

Preventing XSS in user URL input

我有一个带有输入字段的应用程序,它允许用户提交一个 URL,该 URL 将作为链接显示在页面上(在用 React 编写的 SPA 中)。

我希望用户能够提交相对网址以及绝对网址。例如(以下所有内容都应该是一个很好的输入):

1
2
3
4
5
6
https://stackoverflow.com
stackoverflow.com
http://example.com
localhost:1234
localhost
...

我正在努力防止 XSS 攻击。这样当用户在 URL 输入中提交 javascript:alert('hacked') 时,它应该不起作用。

我想这样做的方法是简单地用 http:// 前缀输入(如果它已经不在输入中)。所以最终结果是 http://javascript:alert('hacked')

在服务器端,我使用的是 ASP.NET Core,我有一个看起来像这样的模型:

1
2
3
4
5
6
7
8
9
10
11
using System.ComponentModel.DataAnnotations;

namespace MyApp.Models {
    public class LinkModel {
        [Required]
        public string Title { get; set; }

        [Url]
        public string Url { get; set; }
    }
}

注意 Url 属性,当我测试时 - http://javascript:alert('hacked') 它是"有效的"。这让我相信它没问题,而且它不是 XSS 攻击媒介。我还在 Chrome 和 Firefox 中对其进行了测试,它似乎是"安全的"。

是这样吗?我错过了什么吗?在将 http:// 传递到服务器之前将其添加到输入足以防止 XSS 攻击。如果我能澄清,请告诉我。


如果您接受来自用户的 URL,则需要注意一些事项。您提到了 javascript: 向量。还有 data: url(例如,data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4= 会弹出一个提示"你好"。)在我看来,你需要解析 url,并确保方案/协议是白色的列表(例如,httpshttp)。此白名单将取决于您的需要。也许您希望人们能够使用 mailto:slack: 链接,但您需要了解每种协议可能存在的攻击或滥用类型。只是附加 http 有点奇怪,最终可能会有一个漏洞。例如,http://test@http://example.com 可以使用基本的 HTTP 身份验证将用户名 http 和密码 //test 传递给主机 example.com。我怀疑这在现代浏览器中是否有效,但这是可能的。

就其价值而言,http://javascript:alert(1) 永远不应被解释为 javascript。我猜浏览器将 javascript 解释为主机(如 stackoverflow.com 是主机)。但是,如果主机在其网络上有一台名为 javascript 的计算机,它将解析为错误页面。如果你正确地实现了白名单,你就不需要担心这样的事情。

接下来,您需要确保在显示 URL 时正确转义/编码 URL。像这样: name 您需要确保用户不能将 " 放入 url 并突破 html 属性。考虑像 system.web.security.antixss.antixssencoder.urlencode.

这样的东西

您还需要注意,用户仍然可以链接恶意的有效 https 站点。一个例子是一个看起来像你的网络钓鱼网站,或者可能只是一些下载恶意软件的网站。许多站点会创建一个警告弹出窗口,告诉用户他们将离开站点。这可能是您想做的事情,但这确实取决于。我不确定这些有多大帮助,但是如果您担心用户被诱骗离开,则需要考虑一下。

最后,用户可以链接到您网站上的现有页面,但仍然是恶意的 - 例如,CSRF。您需要小心防止这些类型的页面存在。想象一下有人链接到 https://example.com/account/delete,然后一个毫无戒心的用户删除了他们自己的帐户。

edit:我个人不会让用户在没有方案的情况下输入 URL,因为这意味着您必须假设 http。我会在客户端验证它是一个 URL(包括协议),然后检查它是否在白名单中。