3

I just made a shocking discovery - when deploying QML applications, all the "stock" QML components used in the project are deployed as bare QML files, directly visible in the file system, they are not even tucked away in the application qrc binary as user QML files are. Meaning that anyone can open those human readable files, and write whatever code he needs executed. Also, it is possible to do a fair amount of introspection on QObject derived types, even from QML, you can crawl down the object tree, analyze the application structure, iterate through object's methods and properties. Plenty of room for malicious hackery. You don't even have to dig for some low level overlooked exploit - it is all just there for the taking.

Are there any security features to prevent that from happening? Something to check deployed QML sourced for modifications perhaps, even as basic as a checksum? If not, are there any strategies towards manually implementing security? It seems the deployment process is pretty much set, that's the way it is and there isn't room for customization?

Also note that from my investigation in relation to this question, it does seem to be possible to override how QML files are resolved, but even if one goes this arduous way, how does that stack with the existing deployment scheme? Is there a "pretty" way to customize the deployment procedure, especially considering it varies drastically between different target platforms.

The question is not about protecting my code from plagiarism, the question is about protecting Qt's code from tampering.


Since many people seem to have a problem with understanding the issue at hand, let me put it in a form of a metaphor, which will hopefully be easier to understand. All locks can be picked, but that doesn't mean it is not a problem if your door comes with no lock whatsoever. Security concerns in the case of a door that cannot be locked are not unfounded just because locks aren't infallible.

Yes, all applications can be hacked, but it makes all the difference in the world whether this requires reverse engineering of binaries, finding an overlooked low level vulnerability and a way to exploit it to your malicious intent, or it is as trivial as opening a text file and just writing what you want to happen.

This is not the case of the typical, intrinsic and unavoidable vulnerability, which is up to the developer to try to minimize as much as possible, this is the case of a huge, gaping hole, existing by design in Qt's deployment strategy for QML applications. Not only is addressing this not a responsibility of the developer, on top of that Qt's licensing schemes might very well impede the developer from doing it at all. It is a little hard to implement security when insecurity exists at the framework level and you are not allowed to work around it.

For some reason people seem to miss the reverse engineering aspect of this intrinsic lack of security. Before a hacker begins targeting users, he has to develop the hack. This is where the insecurity is most pronounced. The hacker will undoubtedly have admin/root access to his own machine, so no scheme to protect QML sources from writing will work. Having the QML engine willy–nilly interpret text files makes it all that much easier to hack the application, tremendously easier than exploiting the executable binary. From then on, there are other routes to compromise the user's system (and all widely used systems are vulnerable), but point is, at least from the perspective of the individual app developer, that a compromised system alone doesn't compromise the user's data in my application, as it is stored protected on the file system, but it is exposed in the application. Having the QML engine so insecure and childishly easy to inject any code into the application - that's the big issue here. How easy it is to compromise the QML files on the user's system is secondary and a minor concern. The big problem is how easy QML makes the initial development of the hack.

Lastly, the bias of certain people, whose jobs revolve around Qt is understandable, as is their "professional duty" to downplay flaws, which might hamper its adoption and therefore their business, and even if professional, it is highly unethical when the security and privacy of users is at stake. Investing efforts into undermining the risks is hardly the best way to improve on your product's reputation, those risks will not go away just because you are denying them, they will however go away if you improve on your product. Admitting to the risks and committing to fixing them will surely be a while lot less embarrassing than a potential high profile data leak that makes the headlines.

Community
  • 1
  • 1
dtech
  • 47,916
  • 17
  • 112
  • 190
  • Possible duplicate of [Protecting QML source code from plagiarism](http://stackoverflow.com/questions/34814738/protecting-qml-source-code-from-plagiarism) – spring Jan 30 '16 at 02:07
  • Note that unless you buy the commercial license (and then you could use the commercial license support channels to ask for help about this), you are distributing the Qt QML files under LGPL, and therefore you *must* provide a way for the user to modify them. It's basically the same problem as with static linking of Qt libs (possible, but tedious, as you still must make it possible for user to modify the LGPL part). – hyde Jan 30 '16 at 11:26
  • @hyde - IIRC LGPL only requires you to link dynamically, and if you link to modified libraries, you must provide the modified code - all this so that the user can (theoretically) re-link the application to another set of compatible libraries. What you claim is like saying that LGPL requires your application be insecure - that's not neither in your, nor in your users interest. Commercial Qt license? Please, I only have 2 kidneys, and I'd rather keep them both :) – dtech Jan 30 '16 at 11:31
  • 3
    I don't understand your concerns. You can just the same replace any Qt dll in the application installation folder to a malicious one. Yes it is the way you can subvert the application, yes someone can tamper with stock QML files to make some harm if he finds a way to modify them in the way so it actually could make a harm. But it is not different from old-school dll replacement. – ixSci Jan 30 '16 at 12:15
  • 2
    @ixSci - except it is so much easier. My concern is this is as unprotected as it gets, having QML files out on the file system combined with the dynamism, introspection and predictability of QML object structure results in an unprecedented level of application vulnerability. Now if you are asking me, as a developer, what do I care about the security and vulnerability of my application - I don't think such a question even merits an answer. – dtech Jan 30 '16 at 12:56
  • Well, I can't agree that adding whatever code you need to, say, QObject ctor and rebuilding QtBase dll is harder than trying to subvert the application with clever javascript code put in the QML files. You can do almost everything with C++ code(given you have proper credentials with the app) and you are pretty constrained with javascript. So, again, I think you are looking for a non-existing problem — no sane person would try to subvert the app in a hard way when he has a much simpler ones. – ixSci Jan 30 '16 at 13:16
  • But if it so much bothers you, you can do the following: calculate hash sum of your package(all the files) and sign it with the private key. Then, on each run you would check if the hash sum is valid(decrypting the signature with the public key) – ixSci Jan 30 '16 at 13:18
  • @ixSci - that won't work, there is too much variation in how applications are deployed on different platforms and the lack of control over it. On your previous post - this is not exactly true - a library may well be entirely incapable of compromising your application code in any deliberate way, it may break your application but not necessarily compromise things like the user's data or privacy, this is not the case with QML. – dtech Jan 30 '16 at 13:25
  • "no sane person would try to subvert the app in a hard way when he has a much simpler ones" - no sane person would consider what you describe as a "much simpler way" than modifying a text file :D – dtech Jan 30 '16 at 13:38
  • 2
    "Are there any security features to prevent that from happening?” - yes, dont make those QML files writable to everyone (and in any sane installation, they’re aren’t) Whether you loading QML, other scripts or compiled code from insecure locations really makes no difference to me. – Frank Osterfeld Jan 30 '16 at 14:41
  • @FrankOsterfeld - seriously? I can write to pretty much every file, installed on my system, so maybe your typical workstation applications come with "insane" installers? Unfortunately, file permissions are not something you get strict control over from within your application. Every user with "administrator" privileges can do as he wills on that system. The problem is not that the files are writable, the problem is that the files are plain human readable text files, interpreted by the QML engine with "no questions asked" and no security considerations. – dtech Jan 30 '16 at 15:15
  • 1
    As I mentioned several times already, the problem is not that you can hack QML code, but how easy it is. You can hack any application, but there is an ocean of a difference between having to find low level exploits in the binary and just opening a text file and writing what you want to happen. If that difference is "no difference" to you, then LOL, just LOL :) – dtech Jan 30 '16 at 15:19
  • 2
    @ddriver The very purpose of GPL is to allow user to control the software on their computer... Also, no, that is not a real security concern. If malicious 3rd party can modify programs you use, you are hosed. Editing plain QML files in harmful ways will be much harder than just deploying a root kit. – hyde Jan 30 '16 at 21:15
  • @hyde - GPL != LGPL, and yes, it is a security concern, whether or not a user's system is compromised is one side of it, another side is QML's lack of security makes it easy for the hacker to develop the hack on his machine, then apply the hack on systems he manages to compromise. Saying that it is not a security risk is like saying SQL injections are not a security risk, and while you can protect against the latter, there doesn't seem to be a way to protect against the former. Qt will naively execute the QML file whatever the content might be. Worst part is this is so obviously intentional... – dtech Jan 30 '16 at 21:37
  • What I mean is compromising a user's system is not a security risk as far as the user's private data in my application is concerned. I don't store sensitive data on the file system unprotected. However being so easy to modify and introspect QML applications, anything accessible to the QML engine is automatically prone to being compromised. As if the lack of security features in Qt is not enough to begin with - no resource file protection, no meta information protection, just open it in a hex editor and read it. 20+ years in development, you'd think they'd consider some security... – dtech Jan 30 '16 at 22:31
  • 2
    @ddriver: As if compiling a modified DLL needs low-level exploit skills. You modify Qt source code, compile it, and replace the QtCore.dll or whatever on the target system. Or replace binary X with binary Y alltogether. If the system allows that, then the system is inherently insecure. And on any sane system, the installed application and the files it ships (including QML) are *not* user-writable but require root/administrator privileges. That's the standard on Linux and also on Windows which you seem referring to. – Frank Osterfeld Jan 31 '16 at 08:11
  • @FrankOsterfeld - I still don't understand what makes you think a hacker, working to compromise your application won't have administrator privileges on his machine. You just keep singing the same old song, wishfully ignoring every factual argument I made. Way to go... – dtech Jan 31 '16 at 10:05
  • root privileges on *the attacked* machine. That's what's needed to modify the QML on the *attacked* machine when the application is installed properly, as any installer or package management system does. Your argument is that it's so much easier to modify QML than modifying/replacing binary, which I say is nonsense because if someone can modify either, the door is wide open anyway. – Frank Osterfeld Jan 31 '16 at 10:56
  • @FrankOsterfeld - you somehow, and amazingly in the bad context, are still failing to see the big picture. Yes, you can just as easily modify stuff, whether it is a compiled binary or a plain text file, BUT a compiled binary makes it THAT MUCH HARDER to apply a modification you can maliciously exploit than just writing your malicious code in a text file. Please, abstain from further nonsense until you get a firm grasp on the concept. – dtech Jan 31 '16 at 13:26
  • @ddriver: I'd appreciate if you could stop insulting me and stop ignoring what hyde, ixSci and me told you from the beginning: If the attacker has root access, i.e. can modify the QML files, he can just install a rootkit, replace any binary with another, etc. The system is already compromised. And yes, finding functions exported to QML that can be used exploit the system in the desired way is so much more powerful and easier than running a rootkit installer (*sarcasm*). End of discussion. – Frank Osterfeld Feb 01 '16 at 21:26
  • @FrankOsterfeld - I'd appreciate if you stop repeating like a parrot and pay attention to the actual issue. You are still missing the point. – dtech Feb 01 '16 at 21:52

2 Answers2

3

With Qt 5.7, static builds of Qt (configuring Qt with -static) will cause QML files belonging to Qt modules to be built into a plugin via the resource system. For example, consider the relevant change in the Qt Graphical Effects module. Here is the directory listing of qtbase/qml/QtGraphicalEffects before the changes:

Blend.qml
BrightnessContrast.qml
Colorize.qml
ColorOverlay.qml
ConicalGradient.qml
Desaturate.qml
DirectionalBlur.qml
Displace.qml
DropShadow.qml
FastBlur.qml
GammaAdjust.qml
GaussianBlur.qml
Glow.qml
HueSaturation.qml
InnerShadow.qml
LevelAdjust.qml
LinearGradient.qml
MaskedBlur.qml
OpacityMask.qml
private
qmldir
RadialBlur.qml
RadialGradient.qml
RectangularGlow.qml
RecursiveBlur.qml
ThresholdMask.qml
ZoomBlur.qml

After:

private
qmldir
qtgraphicaleffectsplugin.lib
qtgraphicaleffectsplugin.prl
qtgraphicaleffectsplugind.prl

This is one way of making it harder to access the QML files of Qt modules.

Mitch
  • 23,716
  • 9
  • 83
  • 122
  • This sounds very good, even if 5.7 is probably at least a good 9 months away, however requiring a static build, it doesn't seem like LGPL users will benefit from it. – dtech Jan 30 '16 at 15:52
  • 1
    Yeah, I'm not sure about the legalities/practicalities there... though I was under the impression that it was possible to ship statically linked apps with the open source license. – Mitch Jan 30 '16 at 15:56
  • If by the "open source" license you mean LGPL - not really, although due to the lack of another option, this seems to be the case of iOS deployment. Now it might be OK if **your** application is open source, but all in all, LGPL + proprietary code seem to mandate dynamic linking. – dtech Jan 30 '16 at 15:59
  • 1
    @ddriver If you provide object files of the proprietary parts, and linking Makefiles/scripts, so user can re-link with different/modified LGPL part, then having static linking should be ok. I don't know any software which does it that way though. Those iOS apps maybe. – hyde Jan 30 '16 at 21:22
0

Managing Resource Files with the Qt Resource System

The Qt resource system allows resource files to be stored as binary files in an application executable. This can be useful when building a mixed QML/C++ application as it enables QML files (as well as other resources such as images and sound files) to be referred to through the resource system URI scheme rather than relative or absolute paths to filesystem resources. Note, however, that if you use the resource system, the application executable must be re-compiled whenever a QML source file is changed in order to update the resources in the package.

To use the resource system in a mixed QML/C++ application:

Create a .qrc resource collection file that lists resource files in XML formatFrom C++, load the main QML file as a resource using the :/ prefix or as a URL with the qrc scheme

Once this is done, all files specified by relative paths in QML will be loaded from the resource system instead. Use of the resource system is completely transparent to the QML layer; this means all QML code should refer to resource files using relative paths and should not use the qrc scheme. This scheme should only be used from C++ code for referring to resource files.

Source: http://doc.qt.io/qt-5/qtquick-deployment.html

Luigi
  • 70
  • 1
  • 3
  • 5
    This doesn't answer the question, Qt doesn't package its own stock QML files in a resource, they are just sitting there in the open. Unless you provide a way to make Qt deploy those files as resources this is not a valid answer. – dtech Jan 30 '16 at 11:16
  • @ddriver Is there something which prevents one from just using this on Qt's .qml files? I haven't tried. – hyde Feb 01 '16 at 04:53
  • @hyde - well, there is the thing you mentioned about deployment and LGPL, although it is a little unclear whether qml files fall in the "library" category. Technically it could be done, and it is also a nice opportunity to strip the qml files of comments, which probably take more space than the actual code. However, when it is not clear whether you are allowed to do that, it is not really a safe path to take. Also, with android deployment in particular, it means you will deploy the qml files twice, once in the qrc and once auto-deployed in the apk and on the filesystem. – dtech Feb 01 '16 at 11:17
  • @hyde - it would have been so much better if stock qml files are automatically deployed as a resource by Creator, even if resource files themselves are unprotected, but for some reason this is not being done. It isn't exactly clear whether this is due to negligence or deliberate, but in the case of the latter, it might be because of problems with this approach, not so much technical as legal. – dtech Feb 01 '16 at 11:19