QUIP 23: Qt-Security header in source code files
by Dimitrios Apostolou
Details
- Number: 23
- Title: Qt-Security header in source code files
- Author: Dimitrios Apostolou
- Status: Active
- Type: Process
- Post History: 045465.html, 046973.html
- Content Type: text/x-rst
- Created: 3 July 2024
Overview
Some files in Qt may contain, near the top, one single-line comment starting with the string “Qt-Security”. The full syntax is described later in this document. Here is an example of what such a header may look like in practice:
// Qt-Security score:critical reason:data-parser
Purpose
The idea is to identify the files containing code where bugs are more likely to cause security issues. For example, code that is parsing input from untrusted sources, or a protocol implementation.
This information may then be used by the code-review and CI system to enforce special handling for such files, for example extra scrutiny in the review process, stricter test requirements, enabling sanitizers and doing fuzz testing in the CI process etc. Opposite special handling might be enforced for files marked as security-insignificant, for example skipping static analysis.
Criteria for choosing the right score
All source files that are part of a module or plugin implementation as
defined in
QUIP-18
are marked with a security header. This allows us to keep track of which
sources have been reviewed, and makes it possible to block new sources
without any score from being added in the future. In the absence of such
a header, the default score of a file is to be significant to security,
described by score:significant.
Security-critical files are marked with score:critical. Following
methodologies such as Threat Modeling and Risk
Assessment to satisfy the
requirements from legislation such as as the European Union’s Cyber
Resilience Act
(CRA),
this applies primarily to source code that implements an interface
through which data might cross a trust boundary in a software system
built with Qt. This typically applies to files containing code that:
- parses external data or handles input from untrusted sources directly
- implements network protocols (this is actually a subcategory of the above)
- implements cryptography or handles relevant libraries.
- can execute external code from untrusted locations or with arguments from untrusted sources
- implements authentication or access control mechanisms
- performs file system traversal or operates with temporary files
- implements object serialization/deserialization
- implements inter-process communication (including shared memory or D-Bus interfaces)
- implements extensive memory management, such as garbage collectors or custom allocators
Usually, files with a critical score are .cpp, .c or .mm files,
but if other files contain such code, they are marked as well. An
example of this would be C++ header files that contain inline functions
or macros that fulfill the above criteria.
A file with insignificant impact on security is marked with
score:insignificant. This is mostly intended for certain tools and
tests, where a crash is very unlikely to cause a security vulnerability
in Qt.
Syntax
The syntax of the header is intended to be both readable by humans, as well as easily parseable by a tool. As mentioned earlier, the syntax is:
// Qt-Security score:LEVEL reason:some-reason
The Qt-Security comment line must be located towards the beginning of the file, before any source code. By preference it’s usually placed right after the SPDX license header. The content of the header must all appear in one line, without any line breaks in between.
-
scoregives a score. For now the only acceptable values are: insignificant
Code where bugs are not expected to directly cause vulnerabilities.significant
Security significant code. This is the default level, implied for files lacking the Qt-Security header.critical
Security critical code, where bugs are more likely to cause vulnerabilities and security issues in general. -
reasoncontains a keyword explaining the main reason for the score. Valid values are strings of the form[-a-z0-9]+for example:- data-parser
- network-protocol
- cryptography
- execute-external-code
If multiple reasons are relevant for a given file, then reason may
contain a comma-separated list of keywords.
Definitions
The category ‘execute-external-code’ is used when Qt code can
potentially execute code from untrusted locations or when its arguments
come from untrusted sources. This includes system() calls, QProcess,
QLibrary, loading shaders, or QML/javascript from files that might
come from an untrusted location.
Code doing that needs to take steps to ensure that the file is loaded from a trusted source (i.e. we have to assume that the PATH can be trusted), or clearly document that those files need to come from a trusted source (i.e. the application needs to ensure that it doesn’t load QML files from untrusted locations).
For example, if a file contains code that calls system(), it must be
tagged with score:critical because it must at least:
-
Validate that the executable comes from a trusted location
-
Validate the arguments passed to that executable
-
QUIP-18: https://contribute.qt-project.org/quips/18#module-and-plugin-implementation
-
Threat Modeling and Risk Assessment: https://www.threatmodelingmanifesto.org
-
CRA: https://digital-strategy.ec.europa.eu/en/policies/cyber-resilience-act