防止用户 URL 输入中的 XSS
Preventing XSS in user URL input
我有一个带有输入字段的应用程序,允许用户提交 URL,它将在页面上显示为 link(在用 React 编写的 SPA 中)。
我希望用户能够提交相对 URL 和绝对 URL。例如(以下所有内容都应该是一个很好的输入):
https://whosebug.com
whosebug.com
http://example.com
localhost:1234
localhost
...
我正在尝试防止 XSS 攻击。因此,当用户在 URL 输入中提交 javascript:alert('hacked')
时,它应该不起作用。
我考虑的方法是简单地在输入前加上 http://
前缀(如果它不在输入中)。这样最后的结果就是 http://javascript:alert('hacked')
在服务器端,我正在使用 ASP.NET 核心,我有一个看起来像这样的模型:
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')
它是 "valid"。这让我相信它没问题,而且它不是 XSS 攻击媒介。我也在 Chrome 和 Firefox 中测试过它似乎是 "safe".
是这样吗?我错过了什么吗?在将输入传递给服务器之前将 http://
添加到足以防止 XSS 攻击的输入。如果我可以澄清,请告诉我。
如果您要接受用户的 URL,则需要注意一些事项。您提到了 javascript:
向量。还有data:
urls(例如,data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=
会弹出一个警告说"hello"。)在我看来,你需要解析url,并确保 scheme/protocol 在白名单中(例如,https
和 http
)。此白名单将取决于您的需要。也许您希望人们能够使用 mailto:
或 slack:
link,但您需要了解每种协议可能存在的攻击或滥用类型。仅附加 http 有点奇怪,最终可能会出现漏洞。例如 http://test@http://example.com
可以使用 basic HTTP authentication 将用户名 http
和密码 //test
传递给主机 example.com
。我怀疑这是否适用于现代浏览器,但这是可能的。
就其价值而言,http://javascript:alert(1)
永远不应被解释为 javascript。我猜浏览器会将 javascript
解释为主机(比如 whosebug.com 是主机)。但是如果主机在其网络上有一台名为 javascript
的计算机,它将解析为一个错误页面。如果你正确地实现了白名单,你就不需要担心这样的事情了。
接下来,您需要确保您在显示时escaping/encoding和URL是正确的。像这样: <a href="escape(url)">name</a>
您需要确保用户不能将 "
放入 url 并突破 html 属性。考虑类似 system.web.security.antixss.antixssencoder.urlencode.
您还需要注意,用户仍然可以 link 恶意的有效 https 站点。一个例子是看起来像您的网络钓鱼站点,或者可能只是一些带有恶意软件下载的站点。许多网站会创建一个警告弹出窗口,告诉用户他们将离开该网站。这可能是你想做的事情,但这真的取决于。我不确定这些有多大帮助,但如果您担心用户被诱骗离开,则需要考虑一下。
最后,用户可能 link 到您网站上的现有页面并且仍然是恶意的 - 例如,CSRF。您需要小心防止这些类型的页面存在。想象一下有人 link 访问 https://example.com/account/delete
,然后一个毫无戒心的用户删除了他们自己的帐户。
编辑:我个人不会在没有该方案的情况下让用户输入 URLs,因为这意味着您必须假设 http
。我会在客户端验证它是 URL(包括协议),然后检查它是否在白名单中。
我有一个带有输入字段的应用程序,允许用户提交 URL,它将在页面上显示为 link(在用 React 编写的 SPA 中)。
我希望用户能够提交相对 URL 和绝对 URL。例如(以下所有内容都应该是一个很好的输入):
https://whosebug.com
whosebug.com
http://example.com
localhost:1234
localhost
...
我正在尝试防止 XSS 攻击。因此,当用户在 URL 输入中提交 javascript:alert('hacked')
时,它应该不起作用。
我考虑的方法是简单地在输入前加上 http://
前缀(如果它不在输入中)。这样最后的结果就是 http://javascript:alert('hacked')
在服务器端,我正在使用 ASP.NET 核心,我有一个看起来像这样的模型:
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')
它是 "valid"。这让我相信它没问题,而且它不是 XSS 攻击媒介。我也在 Chrome 和 Firefox 中测试过它似乎是 "safe".
是这样吗?我错过了什么吗?在将输入传递给服务器之前将 http://
添加到足以防止 XSS 攻击的输入。如果我可以澄清,请告诉我。
如果您要接受用户的 URL,则需要注意一些事项。您提到了 javascript:
向量。还有data:
urls(例如,data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=
会弹出一个警告说"hello"。)在我看来,你需要解析url,并确保 scheme/protocol 在白名单中(例如,https
和 http
)。此白名单将取决于您的需要。也许您希望人们能够使用 mailto:
或 slack:
link,但您需要了解每种协议可能存在的攻击或滥用类型。仅附加 http 有点奇怪,最终可能会出现漏洞。例如 http://test@http://example.com
可以使用 basic HTTP authentication 将用户名 http
和密码 //test
传递给主机 example.com
。我怀疑这是否适用于现代浏览器,但这是可能的。
就其价值而言,http://javascript:alert(1)
永远不应被解释为 javascript。我猜浏览器会将 javascript
解释为主机(比如 whosebug.com 是主机)。但是如果主机在其网络上有一台名为 javascript
的计算机,它将解析为一个错误页面。如果你正确地实现了白名单,你就不需要担心这样的事情了。
接下来,您需要确保您在显示时escaping/encoding和URL是正确的。像这样: <a href="escape(url)">name</a>
您需要确保用户不能将 "
放入 url 并突破 html 属性。考虑类似 system.web.security.antixss.antixssencoder.urlencode.
您还需要注意,用户仍然可以 link 恶意的有效 https 站点。一个例子是看起来像您的网络钓鱼站点,或者可能只是一些带有恶意软件下载的站点。许多网站会创建一个警告弹出窗口,告诉用户他们将离开该网站。这可能是你想做的事情,但这真的取决于。我不确定这些有多大帮助,但如果您担心用户被诱骗离开,则需要考虑一下。
最后,用户可能 link 到您网站上的现有页面并且仍然是恶意的 - 例如,CSRF。您需要小心防止这些类型的页面存在。想象一下有人 link 访问 https://example.com/account/delete
,然后一个毫无戒心的用户删除了他们自己的帐户。
编辑:我个人不会在没有该方案的情况下让用户输入 URLs,因为这意味着您必须假设 http
。我会在客户端验证它是 URL(包括协议),然后检查它是否在白名单中。