简介
当涉及应用程序的用户界面(UI)时,人们关心的往往是美观、设计的一致性、简单性和清晰性。然而,像浏览器这样的应用程序,不仅需要加载、解析不受信任的内容,而且还需要提供相应的API来调用各种UI,这时,该类应用程序就会面临一个新的关注点:设计安全的UI。
多年来,浏览器的用户界面已经在网络钓鱼活动和技术支持诈骗等攻击活动中被滥用。通常来说,这些攻击的目标并不是在受害者的机器上执行代码,而是获得受害者的信任并引诱(或恐吓)他们拨打一个号码。这类技术通常被称为社会工程攻击,它们很难被完全缓解,因为任何不受信任的页面都可以随意显示任何图像。即使如此,确保浏览器的用户界面不为此类攻击提供便利也是很重要的。正如我们将看到的,不安全的用户界面设计甚至会导致用户私人信息泄露,例如信用卡、密码和地址。除了这些逻辑上的安全问题之外,我们还将看到,像任何大型的C++项目一样,即使在用户界面代码中也可能存在内存安全漏洞。
在这篇文章中,我们首先为读者介绍如何发现UI中的安全漏洞,然后讨论一些已发现的UI安全漏洞。
UI安全检查表
在评估一个给定的用户界面是否安全时,要问自己以下一组问题。通常需要通过以下多项检查,才能确定一个可滥用的用户界面安全漏洞。
- 是否覆盖可见视区(又称死亡线)?
a. 浏览器提示(想想警报框、权限提示等)应该总是允许跨过死亡线,以表明它们是合法的,并且来自于浏览器。这是为了确保用户界面无法被网页元素所冒充,因为网页无法(或不应该)使用JS/HTML/CSS越过死亡线。
b. 另一方面,网页的用户界面(例如自动填充项、下拉选择器、颜色选择器等)不应该跨越死亡线。相反,我们应该确保它们只出现在可见视区内。这是为了确保网页不能覆盖重要的浏览器UI(omnibox、shyUI和权限提示)或使网页能够冒充浏览器UI。
向下滚动一下,再次激活自动填充,我们将看到:
这种设计就不安全;正确的行为应该是这样的:
注:另外,页面可以向上滚动,然后显示自动填写的用户界面。
- 是否包含不受信任的内容?
如果用户界面中显示的文本或图像受到不受信任的外部来源(通常是被访问的网页)的影响,那么用户界面应该清楚地表明这一区别,使得最终用户能够分辨出哪些内容是浏览器所展示的,哪些内容是网页所展示的。
例如,让我们来看看Javascript的提示框。它是一个浏览器的提示组件,呈现的是网页提供的文本;在这里,还确保在最上面指出“example.tld says:”,从而让用户清楚地知道,该字符串之后的文本来自网站,而不是浏览器。此外,这些提示框应该禁止在跨源frame内调用,否则就有可能被用于欺骗用户。
上图中,所有红色的内容都是不可信任的。下面