Skip to main content

QLabel及其朋友的安全性思考

Comments

原文链接: Peter Hartmann Security considerations regarding QLabel and friends

本篇博客旨在提醒,要始终保持QLabel以及其它相似类中输入内容的清洁。

摘要:

当创建一个QLabel来显示文字信息时,要意识到该类将会尝试猜测其格式是纯文本还是富文本。特别是,如果你希望数据是纯文本,但你无法控制它的来源,比如当下载Web中数据时,通过setTextFormat()显式地设置文本的格式或使用Qt::escape()来进行转义或许是个很好的主意。

更多细节:

通过对QLabel(以及其他,比如QMessageBox)的输入的精心构建可以使得其不能显示输入文本中的全部信息。

本文写作动机源于对一些Qt/KDE应用程序的漏洞报告;它们会被欺骗并在标签中显示虚假的信息。

  • CVE-2011-3365影响到KSSL
  • CVE-2011-3366影响到Rekonq
  • CVE-2011-3367影响到Arora

例子:

考虑一个使用SSL连接到服务器的浏览器。当用户想要查看SSL连接(无论是由于SSL错误还是仅出于兴趣)的细节时,浏览器将显示一个包含了SSL证书中多数描述性字段(field)的对话框。其中最重要的是主题(subject)字段的通用名称属性(Common Name attribute),它表示该证书被授予到的主机名。例如,https://qt.nokia.com使用的SSL证书包含以下的主题行,其中通用名称(简称CN)字段以黑体高亮:


Subject: C=NO, ST=Oslo, L=Oslo, O=Nokia, OU=ASF, CN=qt.nokia.com

现在想象一个使用了下列不常用的通用名称属性的服务器:


Subject: C=NO, ST=myState, O=myCompany, CN=qt.nokia.com<table>.evilhost.com

当通过setText()在一个QLabel中显示这个通用名称时,该QLabel将会认为传递进的文本是富文本,并且不显示"<table>.evilhost.com"部分。这样一来,输出看起来像下面这样:

这显然不是QLabel应该显示的。这种情况下的解决方案是在该QLabel上显式地设置文本格式:

label->setTextFormat(Qt::PlainText);

这样一来,标签将会正确显示完整的信息。

所以读者现在可能会说:“对,有道理,但是没有证书颁发机构会签发在通用名称中包含HTML标记的证书”。尽管如此,考虑到证书颁发机构(CAs)签发包含NUL字节的证书,这种情况也不是遥不可及的。(然而,NUL字节的情况更糟,因为SSL的实现可能会被欺骗并接受其他主机名而不是证书被颁发到的主机;本文只是涉及流氓主机名的显示。)

当在不被信任的输入中使用富文本时,你可能愿意像下面这样来转义它:

label->setText(QString::fromAscii("<b>Common Name:</b> %1").arg(Qt::escape(commonName)));

小结:

对要送入QLabel、QMessageBox以及其他控件的输入,要务必谨慎;一个很好的做法可能是,显式地设置文本的格式或者在送入上述类之前先转义它。

致谢:

感谢来自Nth Dimension的Tim Brown和来自KDE的Jeff Mitchell提交了这个问题,感谢来自KDE的Rich Moore审阅(cross-reading)了本文。

Comments

Subscribe to our blog

Try Qt 6.11 Now!

Download the latest release here: www.qt.io/download

Qt 6.11 is now available, with new features and improvements for application developers and device creators.

We're Hiring

Check out all our open positions here and follow us on Instagram to see what it's like to be #QtPeople.