QUIP 23: Qt-Security header in source code files

by Dimitrios Apostolou

← QUIP index

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.

  • score gives 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.

  • reason contains 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: