Swift en première ligne : pourquoi la sécurité n'est pas une option, mais une nécessité
\nVous codez en Swift, fier de la performance et de l'élégance de votre code. Mais vous êtes-vous déjà demandé à quel point votre application est vulnérable aux attaques ? Les injections SQL et XSS (Cross-Site Scripting) ne sont pas de simples histoires effrayantes dans les manuels. Ce sont des menaces réelles qui peuvent vous coûter les données de vos utilisateurs, votre réputation et de l'argent.
\nDans cet article, nous allons voir comment protéger une application Swift (qu'il s'agisse d'un client iOS ou d'une partie serveur avec Vapor) contre deux des types d'attaques les plus dangereux. Pas de blabla — uniquement des exemples pratiques, des solutions prêtes à l'emploi et du code concret. C'est parti !
\n\nInjections SQL en Swift : comment les pirates « trompent » la base de données
\nImaginez : un utilisateur saisit dans un champ de texte '; DROP TABLE Users; --. Si vous insérez directement cette chaîne dans une requête SQL, la base de données exécutera la commande de suppression. Un classique du genre.
En Swift, cette vulnérabilité se rencontre le plus souvent dans les frameworks serveur (Vapor, Kitura) ou lors de l'utilisation de Core Data et SQLite via des wrappers non sécurisés.
\n\nExemple dangereux : comment NE PAS faire
\nimport SQLite\n\nlet username = userInput.text // "admin' OR '1'='1"\nlet query = "SELECT * FROM users WHERE name = '\\(username)'"\ntry db.execute(query) // MENACE ! Requête compromise\n\nCe code est un chiffon rouge pour un taureau. Un attaquant peut accéder à n'importe quelles données ou détruire la table.
\n\nBonne approche : les requêtes paramétrées
\nRègle d'or : n'insérez jamais les données utilisateur directement dans une chaîne de requête. Utilisez la paramétrisation.
\nimport SQLite\n\nlet db = try Connection("path/to/db.sqlite3")\nlet users = Table("users")\nlet name = Expression<String>("name")\n\nlet username = userInput.text // "admin' OR '1'='1"\nlet query = users.filter(name == username) // SÉCURISÉ\nlet result = try db.prepare(query)\n\nLa bibliothèque SQLite.swift échappe elle-même les caractères spéciaux. Pour Vapor avec Fluent, utilisez le modèle et les filtres :
\nimport Fluent\nimport Vapor\n\nstruct UserController: RouteCollection {\n func login(req: Request) async throws -> String {\n let input = try req.content.decode(LoginRequest.self)\n // Fluent paramétrise automatiquement la requête\n let user = try await User.query(on: req.db)\n .filter(\\.$name == input.username)\n .first()\n return user?.name ?? "Not found"\n }\n}\n\nImportant : même si vous utilisez du SQL raw dans Vapor, appliquez SQLBind pour lier les paramètres.
ORM et Core Data : l'illusion de la sécurité
\nDe nombreux développeurs pensent que Core Data ou Fluent protègent automatiquement contre les injections. C'est vrai — si vous n'utilisez pas NSExpression avec du formatage de chaîne ou du SQL brut. Mais rappelez-vous : tout NSPredicate construit via une interpolation de chaîne est un risque.
// DANGEREUX\nlet predicate = NSPredicate(format: "name == %@", userInput) // Sécurisé ?\n// NON ! Si userInput contient '%', une injection par substitution peut se produire.\n\nUtilisez toujours %@ avec des variables, et non %K avec des clés, et n'insérez jamais de chaînes via \\().
Attaques XSS en Swift : quand un attaquant injecte du JavaScript
\nXSS est une attaque où un script malveillant est exécuté dans le navigateur de l'utilisateur. Pour les applications iOS, XSS est pertinent lors de l'utilisation de WKWebView pour afficher du contenu HTML (par exemple, dans un fil d'actualités ou des chats).
Scénario réel : un chat avec formatage HTML
\nUn utilisateur écrit : Bonjour ! <script>alert('XSS')</script>. Si vous affichez ce message dans une WebView sans traitement — le script s'exécutera.
// DANGEREUX\nlet html = "<div>\\(message.text)</div>"\nwebView.loadHTMLString(html, baseURL: nil)\n
Blogs
Book Recommendations
Lire aussi
Web scraping avec BeautifulSoup : guide complet Python
Bibliothèques Python essentielles : de NumPy à PyQt