Skip to main content
Les vulnérabilités d’injection se produisent lorsque les entrées utilisateur non fiables sont interprétées comme du code ou de la logique de requête plutôt que comme des données. Elles vont du cross-site scripting (XSS) qui exécute du JavaScript dans les navigateurs des victimes à l’injection de base de données qui expose tout votre magasin de données.

user-input-not-filtered

Élevé

Description

Les champs de saisie ne nettoient pas ni n’échappent les données fournies par l’utilisateur avant de les rendre sur la page, rendant l’application vulnérable aux attaques de Cross-Site Scripting (XSS).

Importance

Le XSS permet aux attaquants d’injecter du JavaScript arbitraire dans les pages de votre application. Cela peut être utilisé pour :
  • Voler les cookies de session (même sans contournement HttpOnly via XSS stocké)
  • Rediriger les utilisateurs vers des sites de phishing
  • Exfiltrer silencieusement des données de formulaire (enregistrement de frappe)
  • Défigurer l’application
  • Attaquer d’autres utilisateurs qui consultent la page infectée

Comment QAOS le détecte

L’agent identifie les champs de saisie qui reflètent le contenu utilisateur (champs de recherche, formulaires de commentaires, champs de profil, paramètres URL rendus sur la page) et soumet des charges utiles de test XSS. Il observe si la charge utile est exécutée, rendue sans échappement ou stockée et affichée à d’autres visiteurs. Charges utiles de test utilisées :
<script>alert(1)</script>
"><img src=x onerror=alert(1)>
javascript:alert(1)

Comment corriger

Ne faites jamais confiance aux entrées utilisateur. Appliquez l’encodage de sortie approprié au contexte :
// Encoder les entités HTML (prévenir l'injection HTML)
const encoded = input
  .replace(/&/g, '&amp;')
  .replace(/</g, '&lt;')
  .replace(/>/g, '&gt;')
  .replace(/"/g, '&quot;')

// Utiliser une bibliothèque comme DOMPurify pour le contenu HTML enrichi
import DOMPurify from 'dompurify'
element.innerHTML = DOMPurify.sanitize(userContent)
Utilisez une Content Security Policy (CSP) comme mesure de défense en profondeur :
Content-Security-Policy: default-src 'self'; script-src 'self'

hostile-data-used-in-query

Élevé

Description

Les entrées contrôlées par l’utilisateur sont utilisées directement dans la construction de requêtes sans paramétrage, permettant aux attaquants de modifier la logique de requête et d’extraire des enregistrements non autorisés.

Importance

Un seul champ de recherche injectable peut exposer toute votre base de données. Les charges utiles d’injection SQL comme ' OR 1=1 -- contournent les clauses WHERE. Les charges utiles d’injection NoSQL comme {"$ne": null} retournent tous les enregistrements. C’est systématiquement la cause n°1 des violations de données à grande échelle.

Comment QAOS le détecte

L’agent identifie les champs de recherche, de filtre et de requête, puis soumet des charges utiles d’injection et observe les changements de réponse :
Normal : /users?search=alice     → retourne 1 utilisateur
Attaque : /users?search=' OR 1=1--  → retourne tous les utilisateurs

Comment corriger

Utilisez toujours des requêtes paramétrées. Ne concaténez jamais les entrées utilisateur dans des chaînes de requête :
# INCORRECT — vulnérable à l'injection
query = f"SELECT * FROM users WHERE name = '{user_input}'"

# CORRECT — requête paramétrée
cursor.execute("SELECT * FROM users WHERE name = %s", (user_input,))
// MongoDB — éviter l'injection directe d'opérateurs
const users = await User.find({ name: req.query.name })  // potentiellement dangereux
// Utiliser la validation + liste d'autorisation d'opérateurs

untrusted-data-concatenation-dynamic-query

Élevé

Description

Des requêtes dynamiques sont construites en concaténant plusieurs valeurs d’entrée non fiables, permettant à des fragments injectés comme &showAll=true, &fields=password ou ?filter[$gt]=0 de modifier le comportement de la requête et d’exposer des données non autorisées.

Importance

Même lorsque les entrées individuelles sont partiellement assainies, combiner plusieurs valeurs contrôlées par l’utilisateur dans une seule expression de requête crée des opportunités d’injection. Les vulnérabilités d’assignation massive dans les ORM entrent dans cette catégorie.

Comment QAOS le détecte

L’agent teste les pages basées sur des filtres en injectant des paramètres de requête supplémentaires comme showAll=true, fields=password,ssn,salary ou filter[$ne]=null pour vérifier si l’application les passe aveuglément à la couche de données.

Comment corriger

Utilisez une liste d’autorisation explicite de paramètres et d’opérateurs acceptés. Ne passez jamais directement des fragments de requête bruts des entrées utilisateur à un ORM ou un constructeur de requête :
// Définir explicitement les champs de filtre autorisés
const ALLOWED_FILTERS = ['name', 'status', 'createdAt']
const safeFilter = {}
for (const key of ALLOWED_FILTERS) {
  if (req.query[key]) safeFilter[key] = req.query[key]
}
const results = await Model.find(safeFilter)

orm-parameter-extraction-in-url

Élevé

Description

Les paramètres URL sont passés directement à une requête ORM sans validation, permettant l’injection d’opérateurs de style MongoDB ([$ne], [$gt], [$regex]), de fragments SQL ou de paramètres d’assignation massive qui exposent des enregistrements supplémentaires ou des champs cachés.

Importance

L’injection ORM via les paramètres URL est particulièrement courante dans les applications Node.js utilisant Mongoose ou Sequelize, où req.query est passé directement à Model.find(). Cela peut contourner tout contrôle d’accès et exposer chaque enregistrement dans la collection.

Comment QAOS le détecte

L’agent ajoute des suffixes d’injection aux paramètres URL sur les pages avec des listes de données :
/users?id[$ne]=invalid        → MongoDB : correspond à tous les utilisateurs où id ≠ "invalid"
/products?name[$regex]=.*     → MongoDB : correspond à tous les produits
/orders?showAll=true          → contournement par assignation massive
/users?fields=name,email,ssn  → injection de champs

Comment corriger

Assainissez les paramètres de requête avant de les passer à votre ORM. Rejetez toute entrée contenant des opérateurs $ ou une syntaxe de tableau :
const mongoSanitize = require('express-mongo-sanitize')
app.use(mongoSanitize())  // supprime $ de toutes les entrées

// Ou valider manuellement
if (typeof req.query.id !== 'string') throw new Error('Paramètre invalide')

orm-parameter-extraction-in-form

Élevé

Description

La même vulnérabilité d’injection ORM que ci-dessus, mais exploitée via des soumissions de formulaires (paramètres du corps POST) plutôt que des chaînes de requête URL.

Importance

Les paramètres du corps POST reçoivent souvent moins de scrutin que les paramètres URL, surtout dans les frameworks qui utilisent des parseurs de corps qui convertissent automatiquement la notation de formulaire name[$ne]=x en objets imbriqués { name: { $ne: 'x' } }.

Comment QAOS le détecte

L’agent soumet des formulaires avec des paramètres de corps modifiés contenant des charges utiles d’injection ORM et observe si la réponse inclut des données auxquelles il ne devrait pas avoir accès.

Comment corriger

Appliquez le même assainissement aux paramètres du corps POST qu’aux chaînes de requête. Utilisez express-mongo-sanitize ou l’équivalent pour votre framework, et validez toutes les entrées par rapport à des schémas explicites en utilisant des outils comme Zod, Joi ou Pydantic.