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.
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
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 theQt Graphical Effects
module. Here is the directory listing ofqtbase/qml/QtGraphicalEffects
before the changes:After:
This is one way of making it harder to access the QML files of Qt modules.