Votre code dans le viseur : pourquoi la sécurité en Kotlin n'est pas une option, mais une nécessité
\n\nImaginez : vous avez écrit l'application parfaite. Une belle interface, une rapidité fulgurante, une architecture propre. Mais dans une ligne de code se cache une « porte dérobée ». Un attaquant saisit dans le champ de recherche ' OR '1'='1 — et votre base de données est ouverte comme une boîte de conserve. Cela vous dit quelque chose ? Si non — tant mieux. Mais il vaut mieux être prêt à l'avance que d'éteindre un incendie en production.
Kotlin est un langage puissant et moderne. Mais, comme tout autre outil, il ne rend pas votre code sécurisé par défaut. Les injections SQL et XSS (Cross-Site Scripting) restent dans le top du OWASP Top 10 depuis de nombreuses années. Et les développeurs Kotlin qui pensent « j'utilise un ORM, je ne risque rien » se retrouvent souvent en zone de danger.
\n\nDans cet article, nous allons voir comment transformer votre code Kotlin en une forteresse imprenable. Pas de blabla — seulement des conseils pratiques, des exemples concrets et des astuces que vous pourrez appliquer dès aujourd'hui.
\n\nInjections SQL en Kotlin : anatomie d'une attaque et stratégies de protection
\n\nÀ quoi ressemble une vulnérabilité (et pourquoi c'est effrayant)
\n\nUne injection SQL se produit lorsque l'entrée utilisateur est directement intégrée dans une requête SQL. Supposons que vous ayez ce code (ne faites jamais cela !) :
\n\nfun getUserById(id: String): User? {\n val query = "SELECT * FROM users WHERE id = '$id'"\n val statement = connection.createStatement()\n val result = statement.executeQuery(query)\n // ...\n}\n\nSi un attaquant transmet id = "1'; DROP TABLE users; --", la base de données exécutera : SELECT * FROM users WHERE id = '1'; DROP TABLE users; --'. Et vos utilisateurs disparaîtront. Définitivement.
Règle n°1 : Utilisez toujours des requêtes paramétrées
\n\nC'est l'étalon-or. Kotlin (et Java) fournit PreparedStatement, qui sépare le code SQL des données :
fun getUserByIdSafe(id: String): User? {\n val query = "SELECT * FROM users WHERE id = ?"\n val preparedStatement = connection.prepareStatement(query)\n preparedStatement.setString(1, id)\n val result = preparedStatement.executeQuery()\n // ...\n}\n\nLa base de données reçoit le modèle de requête séparément des données. Même si du code malveillant arrive dans id, il sera interprété comme une chaîne de caractères, et non comme une commande.
Règle n°2 : Utilisez Exposed ou d'autres ORM correctement
\n\nLa bibliothèque Exposed est un choix populaire pour Kotlin. Elle est sécurisée si vous utilisez son API correctement. Mauvais exemple (concaténation brute) :
\n\n// MAUVAIS : vulnérabilité\nval users = transaction {\n exec("SELECT * FROM users WHERE name = '$userInput'")\n}\n\nBon exemple (utilisation du DSL d'Exposed) :
\n\n// BON : échappement intégré\nval users = transaction {\n Users.select { Users.name eq userInput }\n}\n\nDans Exposed, l'opérateur eq échappe automatiquement les valeurs. Mais si vous écrivez des requêtes SQL brutes via exec — soyez vigilants.
Règle n°3 : La validation à l'entrée — votre deuxième bouclier
\n\nMême avec des requêtes paramétrées, il ne faut pas laisser n'importe quoi entrer dans la base. Utilisez les outils intégrés de Kotlin pour la vérification :
\n\nfun validateUserId(id: String): Boolean {\n // Vérifions que id est un UUID ou un entier\n return id.matches(Regex("^[a-fA-F0-9-]{36}$")) || \n id.all { it.isDigit() }\n}\n\nSouvenez-vous : ne faites confiance à aucune entrée. Même si elle vient de votre propre frontend. Surtout si elle vient de votre propre frontend.
\n\nAttaques XSS : comment empêcher le code JavaScript de prendre le contrôle de votre site
\n\nQu'est-ce que XSS et pourquoi Kotlin ne vous protège pas automatiquement
\n\nXSS (Cross-Site Scripting) — c'est lorsqu'un attaquant injecte un script sur votre page. Par exemple, dans le champ de commentaire, il écrit : <script>alert('Vos données ont été volées')</script>