Hi everyone,
Qt has a feature called AutoText where when you have a label (both in Qt
Widgets and Qt Quick) and its contents “look like HTML”
(Qt::mightBeRichText) it will switch to rich text (styled text) and
start interpreting it as HTML.
Just name a file or a Wifi SSID "<h1>hello.txt" and marvel at how many
places in your application this will explode because it makes the font
3x as big whenever it displays the name.
In Qt Quick it is even worse because by default the QML Engine creates a
QNetworkAccessManager, i.e. if you manage to sneak an "<img
src='https://example.com/evilimageexploit.jpg'>" into the application,
it will actually start downloading the image (therefore leaking the
user’s IP and making them vulnerable to bugs in the image format plug-ins).
While this is documented behavior and there are mitigations, e.g.
forcing PlainText on the label, restricting network access for the
relevant processes, and so on, the fundamental problem remains: you have
to remember to set PlainText whenever you’re working with untrusted
input and/or whether you want rich text or not. Unlike HTML DOM API
there’s no well understood “innerHTML” vs “innerText”. Using PlainText
also skips mightBeRichText so is slightly faster.
There’s also places where you actually cannot set a text format: for
example Qt Quick Controls ToolTip. The content item can be anything, so
you cannot assume it be a label. The same goes for ItemDelegate which is
typically used to display a list of items (like Wifi SSIDs).
On the other hand, there are potentially many users out there, including
Qt itself (e.g. the about Qt dialog does) that use "<b>" and other
markup to format their text. However, imho the security implications
significantly outweigh the convenience of just using "<b>" (often times
you probably want to set a bold QFont anyway and not abuse rich text for
this).
In KDE we have time and again received security reports where HTML was
unexpectedly interpreted and it is unfeasible to keep telling everyone
to use PlainText, especially given the above when some API does not
allow to do that.
I therefore propose that for Qt 7 we switch to PlainText format by
default. We then need to figure out a way to make the transition easier
(e.g. have an environment variable that lets you force it right now to
test your app, or static code analysis that checks for HTML tags in
strings, or…?). Additionally, we may need to add additional textFormat
properties where useful.
Cheers
Kai Uwe
--
Development mailing list
[email protected]
https://lists.qt-project.org/listinfo/development