Back to sh0
sh0

Nous avons audité notre propre plateforme et trouvé 88 problèmes de sécurité

Nous avons mené 4 audits de sécurité complets sur notre propre PaaS et trouvé 88 problèmes -- 9 critiques, 12 élevés, 45 moyens. Voici chaque découverte, chaque correctif, et ce que nous avons appris.

Juste Thales Gnimavo & Claude | March 26, 2026 5 min sh0
EN/ FR/ ES
securityauditrustvulnerabilitypaasowasphardening

Le 12 mars 2026 -- douze jours après le début de la construction de sh0.dev -- nous avons arrêté d'écrire des fonctionnalités et audité tout ce que nous avions construit jusque-là. Pas une revue superficielle. Un audit de sécurité systématique, phase par phase, sur l'ensemble de la base de code : gestionnaire de proxy, pipeline de déploiement, module d'authentification, monitoring, moteur de sauvegarde, tableau de bord, gestion Compose, RBAC, environnements de prévisualisation, hooks de déploiement, infrastructure-as-code, mise à l'échelle horizontale, et monitoring de disponibilité.

Nous avons trouvé 88 problèmes. Neuf étaient critiques. Douze étaient de sévérité élevée. Quarante-cinq étaient moyens. Vingt-deux étaient faibles.

Cet article n'est pas un article sur la sécurité de sh0. C'est un article sur ce que nous avons trouvé, comment nous l'avons corrigé, et pourquoi auditer son propre code -- brutalement, systématiquement, avant que quiconque d'autre ne le fasse -- est l'une des activités à plus fort levier en ingénierie logicielle.


Les quatre rounds d'audit

Nous avons divisé l'audit en quatre rounds, chacun couvrant un ensemble de phases d'implémentation :

RoundPhases couvertesPortéeDécouvertes
1Phases 1-6Infrastructure de base (Docker, Git, base de données, conteneurs)Couvert dans des sessions précédentes
2Phases 7-12Proxy, Pipeline de déploiement, Auth, Monitor, Sauvegarde, Tableau de bord88 découvertes
3Phases 13-19Alertes, RBAC, Templates, Compose, i18n45 découvertes
4Phases 20-25Compose V2, Environnements de preview, Hooks de déploiement, IaC, Scaling, Uptime51 découvertes

Les neuf découvertes critiques

1. Injection de commande dans la sauvegarde de base de données (Phase 11)

Le moteur de sauvegarde interpolait le paramètre db_name directement dans les commandes shell passées à pg_dump, mysqldump et mongodump. Une base de données nommée test; rm -rf / exécuterait des commandes arbitraires à l'intérieur du conteneur.

Le correctif : validation stricte du nom de base de données avant toute construction de commande.

2. Handler WebSocket sans authentification

Le handler WebSocket stream_logs acceptait les connexions sans vérifier AuthUser. N'importe quelle requête pouvait streamer les logs de n'importe quelle application.

3. Attaque par timing sur la comparaison des clés API

Nous utilisions == pour comparer les hashs de clés API. Le correctif : subtle::ConstantTimeEq.

4-5. Pas de limitation de débit sur connexion/TOTP + codes de secours non stockés

Tentatives de connexion illimitées rendant le brute-force trivial. Nous avons construit un limiteur de débit à fenêtre glissante en mémoire : 5 tentatives de connexion par 15 minutes.

6-8. SSRF via URLs non validées

Trois découvertes liées dans le gestionnaire de proxy. L'URL admin de Caddy, les adresses upstream et les configurations de domaines acceptaient toutes des entrées arbitraires. Un attaquant pouvait pointer le proxy vers http://169.254.169.254 (endpoint de métadonnées d'instance cloud).

9. Pas de verrouillage de déploiement concurrent

Deux déploiements simultanés vers la même application pouvaient causer des conflits de ports et des collisions de noms de conteneurs. Nous avons ajouté un verrou de déploiement par application utilisant DashMap<String, Arc<Mutex<()>>>.


Le processus de correction : équipes parallèles, zéro chevauchement de fichiers

Avec 88 découvertes à corriger dans le Round 2 seul, la remédiation séquentielle n'était pas une option. Nous avons organisé les correctifs en quatre équipes parallèles, chacune responsable d'un ensemble de crates sans fichiers en commun :

  • Équipe A : sh0-proxy (4 correctifs, 15 nouveaux tests)
  • Équipe B : sh0-auth + sh0-db (3 correctifs, 9 nouveaux tests)
  • Équipe C : sh0-backup (5 correctifs, 13 nouveaux tests)
  • Équipe D : sh0-api + sh0-docker + sh0-git (13 correctifs, ~15 nouveaux tests)

Après les trois sessions de remédiation : - cargo test : 312 tests passants - cargo clippy -- -D warnings : zéro warning - cargo build --release : compilation propre


Schémas récurrents

  1. Validation des entrées à la frontière. Chaque endroit où l'entrée utilisateur entre dans le système a besoin de validation.
  2. SSRF partout où des URLs sont acceptées. Si votre système fait des requêtes HTTP vers des URLs fournies par l'utilisateur, vous avez besoin de filtrage d'IP privées.
  3. Canaux auxiliaires de timing. Toute comparaison de secrets doit être en temps constant.
  4. Autorisation manquante après authentification. Vérifier qu'un utilisateur est connecté n'est pas la même chose que vérifier qu'il a la permission.
  5. Unwraps provoquant des panics. Chaque .unwrap() dans un handler de requête est un vecteur de déni de service.

Pourquoi s'auditer soi-même d'abord

Le conseil standard est d'engager un testeur de pénétration tiers. C'est un bon conseil. Mais un audit tiers sur du code que vous n'avez jamais revu vous-même est un gaspillage d'argent. Ils passeront la moitié de leur temps à trouver des problèmes que vous auriez pu trouver avec une lecture attentive.

Nous avons trouvé 88 problèmes dans le Round 2 seul. Si un auditeur externe les avait trouvés, cela aurait été une prestation coûteuse. Au lieu de cela, nous les avons trouvés nous-mêmes, corrigés en une seule session, et ajouté 34 tests de régression pour s'assurer qu'ils ne reviennent jamais.


Prochain dans la série : Migration des jetons localStorage vers les cookies HTTP-Only.

Share this article:

Responses

Write a response
0/2000
Loading responses...

Related Articles

Claude sh0

L'autoscaler qui comparait une espace à un T : deux bugs High, une journée, avant et après

Un autoscaler qui ne décidait jamais parce que SQLite comparait une espace à un T, et un proxy qui servait des 502 à chaque redéploiement. Même machine, mêmes applications, avant et après, en une journée, clos sur des observations datées plutôt que sur des tests verts.

7 min Sep 25, 2026
sh0rustsqliteautoscaling +6
Claude sh0

La preuve, c'est la clé, pas son hash : renouveler une licence signée sans migration

Un serveur auto-hébergé récupère sa licence renouvelée en présentant la clé signée elle-même comme preuve de possession. La conception par hash suggérée par le prompt aurait échoué au moment précis du renouvellement. Puis la preuve en production : un vrai cycle de facturation, une clé re-signée, et un journal serveur qui dit que personne n'a rien eu à faire.

8 min Sep 25, 2026
sh0licensinged25519stripe +3
Thales & Claude zerosuite

Aucun code livré : mener une recherche d'emploi comme un projet logiciel, avec une IA qui prépare tout et n'envoie rien

Un jour, une session avec une IA, aucune ligne de code produit : une recherche d'emploi menée avec les outils que ZeroSuite utilise pour livrer ses logiciels, en méthode valable pour tout métier. Un dépôt privé, un seul fichier de suivi où « envoyé » veut dire « daté », des règles qui refusent la phrase improuvable, une feuille de route CASP qui se termine au contrat signé, et une automatisation qui remplit les brouillons sans jamais appuyer sur Envoyer. Avec un guide pas à pas à télécharger.

18 min Sep 24, 2026
job-searchcareercaspclaude-code +7