
Injection SQL dans l'optimiseur d'agrégation MongoLite via toJsonExtractRaw()
cockpithq/cockpit:core-2.13.47fe563023b7fae854c857d2e2dc0878ef28fbb5f (tag 2.13.4)CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:NUne vulnérabilité d'injection SQL a été identifiée dans Cockpit CMS (édition Core version 2.13.4). La vulnérabilité se situe dans l'optimiseur d'agrégation , plus précisément dans la méthode . Les noms de champs contrôlés par l'utilisateur sont concaténés directement dans les requêtes SQL sans assainissement approprié.
MongoLitetoJsonExtractRaw()Un attaquant authentifié disposant d'un accès en lecture (via une clé API) à un modèle de contenu peut injecter des commandes SQL arbitraires dans le pipeline d'agrégation via le point de terminaison REST /api/content/aggregate/{model}.
Cette faille permet aux attaquants de :
_state=1) pour lire les brouillons non publiés.sqlite_master.Les étapes suivantes démontrent comment un attaquant peut contourner le filtre d'autorisation _state=1.
testcol.title et body.Capture d'écran : Configuration du modèle de contenu testcol

MasterRole) afin qu'il dispose de la permission LECTURE pour le modèle testcol.Capture d'écran : Configuration des permissions du rôle pour la collection

MasterRole que vous venez de configurer. Copiez la valeur de la clé (par exemple, API-b8e8...).Capture d'écran : Configuration de la clé API avec le rôle d'accès en lecture

Public et définissez son état sur PUBLIÉ (icône verte).SECRET_DRAFT et définissez son état sur NON PUBLIÉ (icône rouge).Capture d'écran : La liste des éléments montrant un élément publié et un élément non publié

Par défaut, les requêtes API standard ne renvoient que le contenu dont l'état est Publié. Cependant, en injectant du SQL dans le pipeline d'agrégation, le filtre de contenu publié peut être contourné.
json_extract() et ajoute un commentaire SQL -- pour neutraliser le SQL de fin, ciblant spécifiquement la clause WHERE qui limite les résultats aux éléments publiés.Champ injecté :
$title') as _id FROM collections_testcol--
Pipeline JSON complet :
[{"$group": {"_id": "$title') as _id FROM collections_testcol--", "c": {"$sum": 1}}}]
/api/content/aggregate/testcol. Assurez-vous de remplacer YOUR_API_KEY par la clé générée à l'étape 2.2 :curl "http://localhost:8080/api/content/aggregate/testcol?api_key=YOUR_API_KEY&pipeline=%5B%7B%22%24group%22%3A%20%7B%22_id%22%3A%20%22%24title%27%29%20as%20_id%20FROM%20collections_testcol--%22%2C%20%22c%22%3A%20%7B%22%24sum%22%3A%201%7D%7D%7D%5D"
Comme le montre la capture d'écran finale ci-dessous, la réponse API renvoie avec succès l'élément SECRET_DRAFT malgré son état explicitement NON PUBLIÉ. Cela confirme que l'injection SQL contourne le mécanisme d'autorisation central de l'application et permet l'extraction non autorisée de données via l'API.
Capture d'écran : Extraction réussie des données non publiées 'SECRET_DRAFT'

Dans un déploiement CMS headless classique, une clé API publique en lecture seule est souvent intégrée/codée en dur dans le JavaScript frontal. En exploitant cette vulnérabilité via le point de terminaison API public, un attaquant peut :
content.sqlite, y compris les collections pour lesquelles la clé API n'est pas autorisée.sqlite_master pour découvrir tous les noms et structures de tables.| Date | Action |
|---|---|
| 2026-02-28 | Vulnérabilité découverte lors d'une recherche de sécurité autorisée |
| 2026-03-02 | Rapport soumis au fournisseur |
| 2026-03-02 | Correctif du fournisseur -- https://github.com/Cockpit-HQ/Cockpit/commit/b6a0b45c5e8fe16f3027b889583cc3a9127ab4b0 |
| 2026-03-09 | Correctif publié v 2.13.5 -- https://getcockpit.com/releases |