test(hosts): extend the socket-level pass to the two workstation routes #26
No reviewers
Labels
No labels
autopilot:pending-human
source:analyste
source:defenseur
source:human
source:medic
status:approved
status:blocked
status:in-progress
status:needs-clarification
status:needs-fix
status:ready
status:review
status:triage
type:bug
type:feature
type:infra
type:refactor
type:schema
type:security
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: maximus/vps-health-api#26
Loading…
Reference in a new issue
No description provided.
Delete branch "issue-16-hosts-monitoring-commissioning"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Etend
test-curl.shaux deux routes postes, et documente la mise en service.Volontairement
Refs #16et pasFixes #16: plusieurs criteres d'acceptation ne sont pas encore tenus (ops VPS bloquees, deploiement Vercel bloque en amont). L'issue se ferme a la main quand le dernier tombe, pas au merge de cette PR.Ce que contient la PR
test-curl.sh: 17 -> 41 cas. Les 24 nouveaux couvrentPOST /hosts/<id>etGET /hostsau niveau socket — le 413 rendu avant que la connexion soit coupee, les deux tokens qui se refusent mutuellement leurs routes, le 401 avant le 403, la regex de route qui transforme un id malforme et une traversee en 404 avant tout handler, et le round trip ingestion -> persistance -> lecture.HOSTS_INGEST_TOKEN, pour observer le 503 fail-closed — c'est le seul comportement du lot qu'une instance unique ne peut pas montrer.CLAUDE.md: le compte vitest etait perime (244 -> 251,auth.test.js19 -> 26) ettest-curl.shn'y figurait pas.Deux cas ont demande de l'attention pour valoir quelque chose :
__proto__comme du texte. Ecrit__proto__:dans un litteral objet, il aurait pose le prototype etJSON.stringifyn'aurait rien emis — le cas aurait teste un payload qui ne portait jamais la cle.set -ependant que le serveur detruit la socket juste apres avoir vide la reponse. Toutes les sondes passent par un helper qui absorbe ca ; un curl qui n'a vraiment rien recu rapporte000, ce qui fait echouer le cas au lieu de le laisser passer en silence.Le trap
EXITdeferencait unSERVER_PIDnon initialise sousset -u: il tombait en erreur au lieu de nettoyer quand quoi que ce soit echouait avant le boot.Verification
npm test: 251 cas vertsbash test-curl.sh: 41 cas verts, joue 3 fois de suite pour le cas 413Hors PR, deja fait
HOSTS_INGEST_TOKENetHOSTS_ALLOWED_IDS=thinkpadposees,is_runtime=true is_buildtime=falseverifie sur les 4 rows (jumeaux preview compris)la-compagnie-maximus@7e3ee04: procedure d'ajout d'un poste dansdocs/coolify-ops.md, rotation conjointe des deux tokens dansdocs/secret-rotation-ops.mdReste a faire
Detaille en commentaire sur #16.
Refs #16
maximus referenced this pull request2026-09-25 00:34:09 +00:00
Revue adversariale — APPROVE
Resume : l'extension de
test-curl.shest solide et verifiee par mutation, pas sur parole. Un seul cas (la traversee, cas 23) ne teste pas ce qu'il annonce ; c'est sans risque pour la production, mais a corriger.Verification effectuee (copie hors depot du head
50a829b, ports 3098/3099 libres au prealable)bash test-curl.sh: 41/41 verts.npx vitest run: 251 cas,auth.test.js26 : les compteurs deCLAUDE.mdsont exacts.diff:HOST_ROUTE_REelargi a^/hosts/(.+)$ThinkPad-> 403). Le cas 23 reste vert.req.destroy()nu000) : le helperhttp_coden'avale pas l'erreur de transport. Le piege ducatch { return 413 }est evite.sanitizeSnapshotrecopie...payloada l'ecriture__proto__,injected)Suggestions (non bloquantes)
test-curl.sh, cas 23 : la traversee n'atteint jamais le serveur sous cette forme. curl normalise/hosts/../../etc/passwdcote client : la ligne de requete emise estPOST /etc/passwd(capturee avecnc). Le 404 vient donc de la table de routes, pas de la regex, et le cas passe meme avec la regex elargie.--path-as-isne sauve rien, puisqueURL()normalise a son tour cote serveur. La forme qui exerce vraiment la regex est encodee :"$BASE_URL/hosts/..%2f..%2fetc%2fpasswd". Elle rend 404 sur le code actuel et 403 sous la regex elargie, donc elle rougit la ou il faut. Garder la forme../pour documenter la normalisation, en la renommant, et ajouter la forme encodee comme vraie garde. Le corps de la PR (« la regex de route qui transforme ... une traversee en 404 ») decrit pour l'instant ce que seul le cas 22 prouve.own.includes("polluted")ne peut jamais etre vrai.pollutedest imbrique sous__proto__, etJSON.parsecree une cle propre nommee__proto__. La cle a tester est__proto__. La lecture repasse de toute facon par la liste blanche, et l'assertion sur disque tient la garde (mutation 3), donc rien ne passe entre les mailles. Cette assertion-la reste decorative.000. C'est acceptable, mais unfail "server on :3099 never came up"explicite rendrait le diagnostic immediat. Le script ne verifie pas non plus que l'ecouteur est bien le serveur qu'il vient de lancer (port pris par un voisin :EADDRINUSEavale par>/dev/null 2>&1). Le defaut existait deja ; il pese davantage avec deux ports.Conformite
test(hosts): ...: format conventionnel respecte. Aucun secret : les tokens sont des valeurs de test.Refs #16volontaire et coherent avec le travail restant. Le label de #16 (status:in-progress) n'est pas bascule enstatus:approved: l'issue reste ouverte sur des criteres hors PR.