security

Security outils

Les corvées de sécurité quotidiennes de l'ingénierie web — empreintes, entropie des mots de passe, revendications JWT, rédaction de CSP et expurgation des captures avant partage — et l'outil qui convient à chaque tâche.

11 outils

§01 GUIDE DU DOMAINE

La couche des corvées de sécurité web

L’essentiel du travail de sécurité d’une semaine d’ingénierie normale n’a rien d’adversarial. C’est mécanique : choisir un algorithme de condensé, générer un identifiant qui satisfait la politique de quelqu’un, lire les revendications d’un jeton pour comprendre pourquoi l’authentification a échoué, écrire une Content-Security-Policy qui ne casse pas le site, nettoyer une capture avant de la coller dans un ticket. Rien de tout cela ne ressemble à un test d’intrusion, et c’est là que démarrent les vrais incidents — le mode de défaillance est une mauvaise habitude, pas une compétence manquante.

Le modèle qui prévient la plupart de ces habitudes est une division en trois que les gens réduisent à une seule chose. L’encodage — Base64, encodage pourcent, Punycode — est réversible et n’implique aucun secret ; il change la forme des données, jamais leur confidentialité. Le hachageSHA-256, SHA-512 — est à sens unique et n’implique pas non plus de secret ; il prouve que deux suites d’octets sont identiques, rien de plus. Les opérations à clé — HMAC, signatures JWT, TLS — sont les seules à prouver qui a produit quelque chose, et seulement tant que la clé reste secrète. Pas de clé, pas d’authentification : un bloc Base64, un condensé nu et une charge utile de JWT décodée sont des affirmations lisibles avec rien derrière.

Le second axe est la direction. Les corvées qui émettent de la politique — directives CSP, en-têtes, secrets générés — ne sont correctes qu’une fois l’artefact vérifié dans la réponse déployée. Les corvées qui inspectent quelque chose qu’on vous a remis portent le risque inverse : ce qui se trouve à l’intérieur de l’artefact. L’expurgation appartient à cette catégorie, car la façon habituelle dont des secrets quittent une entreprise est un HAR joint à un rapport de bug, pas un exploit.

Ce que chaque primitive garantit réellement

PrimitiveProuveN’apporte pasMésusage courant
Base64 / encodage d’URLLe transport sûr d’octets par des canaux textuelsLa confidentialité — n’importe qui peut l’inverser« Cacher » une clé d’API dans une charge utile
SHA-256 / SHA-512L’intégrité : même entrée, même condenséLe secret ; le coût de force brute sur une entrée à faible entropieStocker des empreintes de mots de passe
SHA-1La compatibilité avec des sommes de contrôle héritéesLa résistance aux collisions (pratiquement cassée)Signatures ; déduplication d’entrées hostiles
HMAC (hachage + clé secrète)L’authenticité tant que la clé reste secrèteLa confidentialité — la charge utile reste lisibleLivrer la clé à un navigateur
Argon2id / bcrypt / scryptUn stockage de mots de passe salé et délibérément lentLa vitesse — la lenteur est la fonctionnalitéY substituer un hachage rapide « pour la perf »
Signature JWT (HS256, RS256)L’authenticité de l’émetteur — seulement après vérificationRien du tout, si vous vous contentez de décoderFaire confiance aux revendications d’une charge utile décodée
Content-Security-PolicyUne liste d’autorisation appliquée par le navigateur pour les chargementsUn correctif pour l’injection ; les clients non navigateurs'unsafe-inline' laissé dans script-src
TLS + Strict-Transport-SecurityLa confidentialité du transport ; aucun repli vers httpToute affirmation sur la logique applicativeLire un cadenas comme « l’application est sûre »

Combien d’entropie suffit

L’entropie vaut longueur × log2(taille du vivier) : le vivier compte donc autant que la longueur.

Vivier de caractèresBits par caractère8 car.14 car.20 car.
a–z (26)4,70386694
a–z0–9 (36)5,174172103
a–zA–Z0–9 (62)5,954883119
les quatre jeux (87)6,445290129

En dessous de 40 bits, c’est cassé ; 80 est le plancher pour un compte qui compte ; un UUID v4 aléatoire porte 122 bits.

Choisir le bon outil

Pour les empreintes, le Générateur de Hash calcule SHA-1, SHA-256, SHA-384 et SHA-512 d’un coup via Web Crypto, si bien qu’un condensé correspond à echo -n "text" | shasum -a 256 octet pour octet — le moyen rapide de réconcilier une somme de contrôle dont personne n’a noté l’algorithme. MD5 est absent parce que Web Crypto ne l’implémente pas.

Pour les secrets que vous créez, la question est de savoir qui détient la valeur. Le Générateur de Mot de Passe convient quand c’est un humain ou un gestionnaire de mots de passe et qu’un site impose une politique de longueur ou de jeu de caractères ; il rapporte l’entropie en direct pour le vivier que vous avez activé. Le Générateur UUID convient quand le consommateur est une machine et que vous voulez un identifiant opaque sans négociation de jeu de caractères. Les deux s’appuient sur un CSPRNG — le générateur de mots de passe puise dans crypto.getRandomValues, le générateur d’UUID dans crypto.randomUUID() — donc aucun ne se replie sur Math.random.

Pour les jetons, le Décodeur JWT scinde header.payload.signature, met en forme les deux premières parties, et restitue iat, exp et nbf en ISO 8601 avec un verdict d’expiration — de quoi trancher « est-ce périmé, ou les revendications sont-elles fausses ? » en un seul collage. Utilisez Base64 quand tout ce que vous avez récupéré d’un journal est un unique segment ; le Base64url emploie - et _, remplacez-les donc d’abord par + et /.

Pour la politique, gardez la rédaction et la vérification séparées. Le Générateur CSP assemble l’en-tête depuis 14 champs par directive par-dessus une base durcie — default-src 'self', object-src 'none', base-uri 'self', frame-ancestors 'none' — et le hub CSP va directive par directive. Prouvez ensuite que la réponse déployée le porte avec En-têtes HTTP, qui charge côté serveur et montre les en-têtes bruts tels que l’origine les a envoyés. Les CDN réécrivent les en-têtes, et une balise <meta> ne peut pas porter frame-ancestors.

Avant de partager, la Visionneuse HAR lit votre propre capture — méthode, statut, type MIME, taille, temps par entrée — tandis que le Nettoyeur HAR prépare la copie qui quittera votre machine, en remplaçant les en-têtes cookie, authorization, x-api-key et similaires par [REDACTED], en vidant les corps et en masquant les paramètres de requête ressemblant à des jetons. Quand le suspect est une seule URL, le Parseur d’URL décode la chaîne de requête pour montrer si un jeton signé y est logé, et le Convertisseur IDN révèle si un domaine sosie est en réalité cyrillique sous sa forme xn--.

Tout cela s’exécute localement, sauf le vérificateur d’en-têtes, qui envoie votre URL à api.sitekits.dev. /fr/for/security/ rassemble la plupart de ces outils sur une page — les plus généralistes (UUID, Base64, la visionneuse HAR) figurent dans d’autres jeux par métier ; le hub confidentialité couvre ce que votre navigateur laisse fuir.

Pièges qui causent de vrais incidents

Un jeton décodé n’est pas un jeton vérifié

Décoder ne prouve qu’un Base64url bien formé. La vérification exige la clé de l’émetteur, un algorithme épinglé, et des contrôles exp / nbf / iss / aud côté serveur. Ne prenez jamais l’algorithme dans l’en-tête alg du jeton lui-même — c’est ainsi que fonctionnent alg: none et la confusion RS256 vers HS256.

Un hachage rapide n’est pas du stockage de mots de passe

Un SHA-256 nu d’un mot de passe est un banc d’essai pour GPU, pas une défense ; non salé, une seule table arc-en-ciel casse chaque utilisateur. Hacher pour comparer des fichiers est le cas inverse — là, un condensé rapide est correct.

'unsafe-inline' annule l’essentiel de la CSP

Il réautorise exactement le script en ligne injecté que la CSP existe pour bloquer. Utilisez des nonces ou des empreintes. Un connect-src avec joker est le même piège par l’autre bout : l’exfiltration reste ouverte même quand l’exécution de script est verrouillée.

L’expurgation est de la correspondance de motifs, pas de la compréhension

L’assainisseur compare à une liste fixe d’en-têtes et à des noms de paramètres contenant token, key, secret, password, passwd, pwd, auth, session, sig ou signature. Un identifiant dans un segment de chemin d’URL, ou nommé t, survit — et un compte d’expurgations à zéro sur une session authentifiée est un signal, pas un feu vert.

L’entropie décrit le générateur, pas la chaîne

La formule ne tient que si chaque caractère a été tiré au hasard. P@ssw0rd!2024 a 13 caractères et les quatre classes, et figure pourtant dans toutes les listes de cassage. Seule la façon dont une chaîne a été générée décide si le score d’un indicateur signifie quoi que ce soit.

FAQ
SHA-256 suffit-il pour stocker des mots de passe ?
Non. SHA-256 est rapide par conception, et des GPU grand public calculent des milliards de condensés par seconde : un attaquant détenant une table d'empreintes fuitée casse donc les mots de passe courts ou courants en quelques heures. Utilisez une KDF salée et délibérément lente — Argon2id, bcrypt ou scrypt — avec un facteur de travail ajusté. SHA-256 est le bon choix pour l'intégrité de fichiers, l'adressage par contenu et la détection de changements, pas pour des identifiants.
Puis-je faire confiance à un JWT une fois décodé ?
Non. L'en-tête et la charge utile d'un JWT sont encodés en Base64url, ni chiffrés ni protégés : n'importe qui peut donc les lire et n'importe qui peut forger un jeton avec des revendications arbitraires. Seule la vérification de la signature contre la clé de l'émetteur prouve qui l'a émis. Décoder sert à déboguer — appliquez exp, nbf et l'audience côté serveur, car l'horloge d'un client peut être fausse ou mentir délibérément.
De combien de caractères un mot de passe a-t-il réellement besoin ?
Cela dépend du vivier de caractères, car l'entropie vaut longueur × log2(taille du vivier). Avec majuscules, minuscules, chiffres et symboles — un vivier de 87 caractères — chaque caractère vaut environ 6,44 bits, si bien que 13 caractères font à peu près 84 bits et 20 caractères environ 129. Les minuscules seules donnent 4,70 bits par caractère : 8 caractères en minuscules font donc environ 38 bits et sont attaquables par force brute. Visez 80 bits ou plus sur les comptes qui comptent.
Une Content-Security-Policy arrête-t-elle le XSS ?
Elle contient le XSS plutôt qu'elle ne le corrige. Une politique stricte empêche un script injecté de s'exécuter ou d'exfiltrer des données, mais seulement dans les navigateurs qui appliquent la CSP, et seulement si script-src évite 'unsafe-inline' et 'unsafe-eval'. Corrigez l'injection par un encodage de sortie correct et servez-vous de la CSP pour limiter les dégâts du bogue que vous avez manqué. Déployez d'abord avec Content-Security-Policy-Report-Only, puis confirmez que l'en-tête appliqué est bien présent dans la réponse réelle.
Puis-je cacher une clé d'API en l'encodant en Base64 dans une charge utile ?
Non. Base64 est un encodage, pas un chiffrement : il n'utilise aucune clé, et quiconque détient la charge utile récupère les octets d'origine en une commande, raison pour laquelle un décodeur n'a besoin de rien de votre part pour la lire. Le problème profond est l'emplacement plutôt que le format — tout secret livré à un navigateur ou à un binaire mobile est déjà divulgué, quel que soit son emballage. Gardez la clé de longue durée côté serveur et donnez au client quelque chose qui prouve l'authenticité sans être le secret : un jeton de courte durée, ou une requête signée en HMAC dont la clé ne quitte jamais votre infrastructure.