Résumé
- Le nouveau test force le stockage temporaire sur disque et confirme que
FileUpload.getBytes()de Wicket restitue exactement les octets écrits. organizations.xlsxn’est qu’un court texte UTF-8 etcarta-ce.pdfun en-tête suivi d’un commentaire : aucun des deux n’est analysé comme le document que son nom suggère.- Une preuve solide doit conserver ce test rapide, puis lui adjoindre des reçus séparés pour le format réel, les règles métier, l’autorisation et les limites de ressources.
La précision se joue dans le nom
Le 11 septembre 2026, un commit du dépôt public elections-open-source de LACNIC a ajouté une méthode intitulée wicketFileUploadGetBytesWorksForDiskBackedExcelAndPdf. Ce nom rassemble dans une seule phrase trois objets : Wicket, un stockage de secours sur disque, puis Excel et PDF. Le code confirme pleinement les deux premiers. Pour les deux formats, il confirme seulement que des octets associés à certains noms de fichier font le trajet attendu.
Le montage est net. Une fabrique DiskFileItemFactory reçoit un répertoire temporaire JUnit et un tampon de taille 1. Avec ce seuil minuscule, tout contenu non vide bascule vers un fichier temporaire. Le test écrit les données, construit un FileUpload Wicket, appelle getBytes(), compare les tableaux octet par octet, puis supprime l’élément dans un bloc finally. C’est exactement le genre de sonde qui protège une jonction fragile après une évolution de dépendances : le composant multipartite et son enveloppe Wicket continuent-ils à s’accorder lorsque le contenu n’est plus conservé en mémoire ?
Les valeurs injectées fixent la portée. Le « tableur » est la chaîne ORGID, un saut de ligne, puis ALFA-001. La « lettre PDF » commence par %PDF-1.1, contient %carta, puis s’arrête. Le premier contenu n’est pas une archive OOXML ; le second n’offre ni objets, ni références croisées, ni fin de document. Le test leur attribue les noms organizations.xlsx et carta-ce.pdf, mais aucun analyseur Excel ou PDF n’est appelé.
Il ne faut donc pas déprécier l’assertion, mais la lire avec discipline. Elle prouve une identité de contenu à travers une frontière de stockage. Elle ne prouve ni que le contenu a la structure annoncée, ni que ses champs sont recevables, ni qu’un utilisateur est autorisé à l’envoyer, ni qu’une modification a été appliquée. Un fichier peut traverser le transport sans altération et échouer correctement à l’étape suivante.
Le dépôt contient d’autres niveaux de contrôle
Une lecture limitée à cette nouvelle méthode produirait une conclusion injuste. Dans la même classe de test, un faux JPEG composé de texte passe par le validateur de photographie et doit être rejeté pour format invalide. Un autre cas fabrique une véritable image PNG, la fait traiter, vérifie une sortie JPEG et contrôle que sa largeur et sa hauteur restent inférieures ou égales à 400 pixels. Ces cas ne vérifient pas seulement le transport : ils demandent au contenu de se laisser décoder et transformer.
Le chemin des classeurs d’organisations possède lui aussi ses propres barrières. Au bord de l’interface, OrganizationExcelFileValidator poursuit l’examen si le nom se termine par .xlsx ou si le type MIME déclaré correspond à OOXML. Ce « ou » est un filtre préliminaire, pas la décision finale. Pour les débiteurs et les suppressions, le validateur transmet le contenu à une vérification distante ; pour les insertions et mises à jour, la validation détaillée intervient à la soumission.
Plus loin, ExcelUtils écrit les octets dans un fichier temporaire, exige le type MIME OOXML, ouvre le contenu avec XSSFWorkbook d’Apache POI, choisit la première feuille, recherche les en-têtes attendus et parcourt les lignes. Les identifiants d’organisation manquants ou dupliqués, les colonnes absentes et les valeurs incompatibles produisent des erreurs propres au domaine. Le panneau d’administration exécute encore des vérifications adaptées à l’opération avant de demander la mise en file d’une modification, et refuse de lancer une seconde opération lorsque le traitement est déjà en cours.
Le recensement électoral suit une séparation comparable. Le panneau obtient le FileUpload, appelle une validation liée à l’élection puis, seulement si elle réussit, tente de placer la mise à jour dans la file de travail. Le nouveau test utilise bien la même manière d’extraire les octets. Il ne traverse cependant ni l’analyse du classeur, ni les exigences de colonnes, ni les décisions propres à l’élection.
Les lettres de résultat suivent un autre parcours. Le formulaire multipartite limite sa taille à 10 Mo. Lors de l’enregistrement, la page recharge l’élection, applique le contrôle d’accès et interrompt l’action si l’élection est close. Les trois lettres facultatives — espagnole, anglaise et portugaise — sont vérifiées avant que les octets choisis soient enregistrés avec le contexte de l’administrateur et de l’adresse cliente.
La reconnaissance PDF y est néanmoins minimale : isPdf accepte un tableau dont les quatre premiers octets sont %PDF. L’échantillon %PDF-1.1\n%carta\n satisfait cette condition. Il ne démontre pas qu’un lecteur PDF peut ouvrir le document ni que celui-ci respecte une politique documentaire. Le contrôle d’accès, l’état de l’élection, la limite du formulaire et la persistance existent bien ; leur présence ne transforme pas le préfixe en analyse structurelle.
Construire une chaîne de reçus
La bonne unité d’assurance n’est pas « l’upload fonctionne ». C’est un ensemble de reçus, chacun rattaché à une frontière et à une conséquence d’échec.
Le reçu de transport force les variantes en mémoire et sur disque. Il compare les octets, confirme explicitement l’état sur disque, observe la fermeture des flux et le nettoyage. La nouvelle méthode de LACNIC convient à ce niveau. Un nom plus exact — préservation des octets par FileUpload.getBytes() avec un élément stocké sur disque — éviterait que les extensions empruntent l’autorité des analyseurs.
Le reçu de format utilise de vrais documents produits par les outils adéquats. Pour OOXML, il faut un petit classeur valide contenant la feuille et les colonnes requises, mais aussi une archive ZIP qui n’est pas un classeur, un paquet tronqué et, selon la politique, un fichier chiffré. Pour PDF, il faut un document minimal complet reconnu par l’analyseur retenu, accompagné d’un simple en-tête, d’un fichier tronqué et des contre-exemples jugés pertinents. Un contrôle de signature peut ouvrir l’examen ; il ne devrait pas le conclure.
Le reçu métier vérifie ce que l’élection attend des cellules. Il distingue l’échec de l’ouverture du classeur de l’erreur de colonne, de ligne ou d’identifiant. Il garantit que les doublons, cellules vides, pays, voix et contacts produisent les retours prévus. Pour un recensement, il utilise une élection connue et observe les règles réellement appliquées plutôt qu’un en-tête isolé.
Le reçu de processus porte sur le droit et l’effet. Un administrateur autorisé peut agir sur une élection ouverte ; une session non autorisée ou une élection close ne le peut pas. Un fichier refusé ne crée aucune tâche. Un fichier accepté déclenche une seule opération, avec le contexte d’audit attendu. Les soumissions concurrentes rencontrent la protection « traitement en cours ». Pour les lettres, l’échec d’une langue doit intervenir avant que les trois valeurs soient modifiées.
Enfin, le reçu de ressources mesure ce que l’identité des octets ne dit jamais : plafond de requête, mémoire, emplacement temporaire, suppression, durée d’analyse et expansion d’un conteneur compressé. Commons FileUpload décrit le passage de la mémoire au disque selon un seuil et les limites de requête disponibles. Apache POI rappelle que le traitement de documents externes exige des protections supplémentaires ; ZipSecureFile expose notamment un ratio minimal de compression et une taille maximale d’entrée décompressée. L’OWASP recommande de superposer autorisation, liste d’extensions, type, signature et limites, y compris après décompression.
Ces recommandations générales ne constituent pas la preuve d’une défaillance chez LACNIC. Elles servent à définir les questions auxquelles une suite d’acceptation complète devrait répondre. Le dépôt observé montre Wicket 10.9.0 dans le module d’administration et un module WildFly référençant POI OOXML 5.0.0. Cela décrit le commit étudié, pas nécessairement un déploiement de production. La proximité temporelle d’une mise à niveau et d’un test ne prouve pas non plus un incident causal.
Une preuve étroite peut être une bonne preuve
Un test rapide de compatibilité a une grande valeur lors d’une mise à niveau. Il isole la frontière où Commons FileUpload remet un élément à Wicket et où le stockage temporaire peut changer le comportement. S’il échoue, les responsables savent que l’enquête doit commencer avant l’analyse des documents. S’il réussit, ils savent que les octets ont survécu à cette traversée. C’est déjà une information opérationnelle utile.
Le danger naît lorsque cette information devient, dans les notes de version ou la mémoire collective, « Excel et PDF sont testés ». Les noms de tests sont des métadonnées de gouvernance : ils circulent plus facilement que le code. Les ajuster maintenant coûte peu. Reconstituer leur vraie portée sous la pression d’un audit ou d’un incident coûte beaucoup plus.
Sources
- Présentation du système électoral LACNIC
- Commit LACNIC examiné
- Test de compatibilité multipartite
- Validateur Excel des organisations
- Tableau de bord des résultats
- Gestion des lettres de résultat
- Utilitaires de traitement des classeurs
- Panneau de téléversement des organisations
- Panneau de téléversement du recensement
- Source de FileUpload dans Wicket 10.9.0
- Documentation de Commons DiskFileItem
- Guide Commons FileUpload
- Recommandations de sécurité Apache POI
- Documentation Apache POI ZipSecureFile
- Guide OWASP sur les téléversements
- POM du module d’administration LACNIC
- Module POI OOXML de LACNIC
Briefing des membres
Contexte approfondi du profil
Connectez-vous avec le bon niveau d'adhésion pour débloquer le briefing complet et les notes de source.
Réservé à Strategic Circle
Strategic Circle
Ouvert à tous les lecteurs. Débloquez les briefings de profil après adhésion et connexion.
Rejoindre Strategic CircleRéservé aux membres de Leadership Alliance
Leadership Alliance
Réservé aux propriétaires et dirigeants qualifiés d'actifs IP ; connectez-vous pour débloquer les briefings Alliance.
Rejoindre Leadership Alliance
