用户目录URL的安全隐患:同源策略下的XSS风险

本文深入分析了类似https://example.org/~username/的用户目录URL存在的安全风险,重点探讨了同源策略导致的XSS漏洞问题,并提出了使用子域名替代方案的建议,适用于Web开发者和系统管理员参考。

用户目录URL如https://example.org/~username/是危险的

我想指出一个经典网页空间托管变体的安全问题。虽然这个问题对于了解基本Web安全的人来说应该很明显,但我从未见过公开讨论它。

一些服务器运营商允许系统中的每个用户拥有个人网页空间,他们可以将文件放在一个目录(通常是~/public_html)中,这些文件将出现在主机上一个带有波浪号和用户名的URL下(例如https://example.org/~username/)。Apache网页服务器在mod_userdir模块中提供了这样的功能。虽然这个概念相当古老,但一些人仍然在使用它,大学和Linux发行版也经常使用。

从Web安全的角度来看,这种设置存在一个非常明显的问题,源于同源策略,这是Javascript安全的核心原则。虽然有很多细微差别,但关键原则是在一个网页主机上运行的一段Javascript与其他网页主机是隔离的。

举一个实际的例子:如果你在example.com的网页界面上阅读电子邮件,那么运行在example.org上的脚本不应该能够读取你的邮件、更改你的密码或以任何其他方式干扰运行在不同主机上的应用程序。然而,如果攻击者能够在example.com上放置一个脚本,这被称为跨站脚本或XSS漏洞,攻击者可能能够做到所有这些。

用户目录URL的问题现在应该变得明显了:一个服务器上的所有用户目录URL都在同一个主机上运行,因此处于同一个源中。它从设计上就具有XSS。

这在实践中意味着什么?假设我们有Bob,他在exampe.org上的用户名是“bob”,在https://example.org/~bob/上运行一个博客。用户Mallory,在同一主机上的用户名是“mallory”,想要攻击Bob。如果Bob当前登录到他的博客,而Mallory设法说服Bob同时打开她的网页——托管在https://example.org/~mallory/——她可以在那里放置一个攻击脚本来攻击Bob。攻击可能是多种多样的,从添加另一个用户到博客、更改Bob的密码或读取未发布的内容。

这只有在example.org上的用户互不信任时才是问题,因此主机运营商可能决定如果只有少数受信任用户,这不是问题。然而,还有另一个问题:同一主机上任何用户目录网页上的XSS漏洞可能被用来攻击同一主机上的任何其他网页。

例如,如果Alice在https://example.org/~alice/上运行一个过时的网页应用程序,其中有一个已知的XSS漏洞,而Bob在https://example.org/~bob/上运行他的博客,那么Mallory可以利用Alice网页应用程序中的漏洞来攻击Bob。

所有这些问题主要是在人们运行具有账户和登录的非平凡网页应用程序时出现。如果网页仅用于托管静态内容,问题就会变得不那么严重,尽管仍然存在一些限制,一个用户可能以 manipulated 的方式显示另一个用户的网页。

那么这意味着什么?你可能不应该使用用户目录URL来托管任何除了简单、静态内容之外的东西——如果可以避免,甚至可能连那里也不要用。即使在所有用户都被认为是受信任的情况下,风险也会增加,因为漏洞可以跨越应用程序边界。至于Apache的mod_userdir,我已经联系了Apache开发人员,他们同意在文档中添加警告。

如果你想为你的用户提供类似的东西,你可能想给每个用户一个子域名,例如https://alice.example.org/、https://bob.example.org/等。然而,这仍然有一个注意事项:不幸的是,同源策略并不适用于所有Web技术,特别是它不适用于Cookies。然而,跨主机名Cookie攻击要直接得多,而且通常没有实际的攻击场景,因此使用子域名仍然是更安全的选择。

为了避免这些Cookie问题,对于定期托管用户内容的域名——一个众所周知的例子是github.io——有一个公共后缀列表用于此类域名。如果你运行一个带有用户子域名的服务,你可能考虑在那里添加你的域名,这可以通过一个pull请求来完成。

评论

#1

southerntofu (主页) 于 2020-04-06 21:21 (回复)

感谢你的文章和非常实用的建议!

你不觉得这是Web(如今天这样)普遍存在的问题吗?这与客户端脚本(由服务器决定)作为一个反功能有关。

一些协议如Gemini(https://gemini.circumlunar.space/docs/faq.txt)试图重新发明一个更简单的Web(或更高级的gopherspace)。但我仍然想知道Web是否注定要失败。我们不应该 aim 构建完全无脚本的网站和浏览器吗?

干杯

#2

munchkin (主页) 于 2020-04-09 08:09 (回复)

教育机构中的多租户网页服务器模型是好的。如果在某人的目录中发现恶意脚本,你可以 pinpoint 那个具体的人。一旦你有了大量无法与个人关联的匿名用户账户,那就成了问题。通常,一旦应用程序成为一个可行的经济实体,它不太可能位于使用这种使用模型的机器上。或者更确切地说,你必须信任https、dns和公钥基础设施的神奇三位一体正在工作,这样一切都没问题。

如果你在做更严肃的事情,应用程序不会尝试做自己的证书钉扎吗?

#2.1

Hanno Böck 于 2020-04-09 08:13 (回复)

如果在某人的目录中发现恶意脚本,你可以 pinpoint 那个具体的人。

那不是真的。等到你发现时,那个人可能已经删除了代码。(除非你记录所有文件系统更改。)或者那个人可能通过安装带有XSS的代码来声称 plausible deniability,该代码被攻击使用。

如果你在做更严肃的事情,应用程序不会尝试做自己的证书钉扎吗?

我不知道这与描述的 attack 有什么关系。

#2.1.1

munchkin 于 2020-04-09 09:24 (回复)

那不是真的。等到你发现时,那个人可能已经删除了代码。(除非你记录所有文件系统更改。)或者那个人可能通过安装带有XSS的代码来声称 plausible deniability,该代码被攻击使用。

是的,那是真的。另一方面,成本可能可以忽略不计。或者更确切地说,如果一个学生被 breached,即使它被利用到更广泛的范围,例如学生的家庭环境,机构上的成本可能可以忽略不计,因为那不在机构的权限范围内。

我不知道这与描述的 attack 有什么关系。

我也得再想想那个。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计