- Dans une réalité où même des fonctions simples mobilisent des milliers de dépendances et des dizaines de millions de lignes de code, l’embonpoint des logiciels devient en soi une cause majeure de vulnérabilités de sécurité
- La sécurité ne dépend pas seulement de la densité de bugs, mais aussi de la quantité totale de code accessible aux attaquants, et une surface d’attaque inutilement large peut mener à de véritables compromissions
- Les écosystèmes Electron JS, Node.js, les images Docker et les dépendances npm·PyPI brouillent le volume et la provenance du code déployé, au point que même une application ouvrant une porte de garage peut impliquer plus de 50 millions de lignes de code actives
- Rust, les sanitizer et les fuzzer améliorent la qualité du code, mais des échecs de conception logique comme l’exécution automatique de code présent dans des documents sont difficiles à empêcher par la seule élimination des bugs
- Trifecta fournit une fonction de partage d’images avec 1 600 lignes de nouveau code, environ 5 dépendances clés et un total de 3 MB, montrant qu’on peut encore créer des logiciels modernes avec un code et des dépendances limités
Un état dangereux pour la sécurité logicielle
- L’état récent de la sécurité logicielle est très mauvais
- Des compromissions graves se sont produites au cours de l’année écoulée dans des logiciels standards de l’industrie comme Ivanti, MOVEit, Outlook, Confluence, Barracuda Email Security Gateway et Citrix NetScaler ADC·NetScaler Gateway
- Même des entreprises très bien dotées en ressources comme Apple et Google ont commis des erreurs de sécurité mettant leurs clients en danger
- L’idée que les logiciels sont devenus trop dangereux a banalisé le conseil de ne pas les exécuter soi-même, mais de les confier au X as a service ou au cloud
- L’hypothèse selon laquelle le cloud rendrait un logiciel vulnérable digne de confiance vacille elle aussi
- La plateforme email de Microsoft a été piratée, y compris des emails gouvernementaux confidentiels
- Des inquiétudes persistent quant à la sécurité du cloud Azure
- Okta a subi une deuxième compromission en moins de deux ans, suivie d’une série suspecte de piratages touchant ses utilisateurs
- L’UE fait avancer trois textes législatifs pour traiter la sécurité logicielle
- NIS2 : vise les services essentiels
- Cyber Resilience Act : vise presque tous les logiciels commerciaux et appareils électroniques
- Product Liability Directive : étend le champ de la responsabilité aux logiciels
Les vulnérabilités viennent à la fois de la qualité et de la quantité de code
- La sécurité logicielle repose sur deux axes
- La densité des problèmes de sécurité dans le code source
- La quantité de code à laquelle les hackers peuvent accéder
- Plus il y a de code, plus le risque augmente
- Même avec une faible densité de bugs, on peut trouver des failles exploitables dans des millions de lignes de code
- Le cas d’iMessage montre quels problèmes crée l’élargissement de la surface d’attaque
- Même un iMessage non sollicité est traité immédiatement sur l’iPhone pour générer un aperçu
- Apple prenait en charge divers formats d’image, jusqu’à des PDF contenant des polices compressées inhabituelles
- Ce vieux format embarquait en pratique un langage de programmation, que des attaquants pouvaient utiliser pour explorer d’autres faiblesses du téléphone
- Apple aurait pu réduire la surface d’attaque en limitant les aperçus à beaucoup moins de formats d’image, voire à un seul format « known good »
- Le Cyber Resilience Act de l’UE précise lui aussi que les fournisseurs doivent minimiser la surface d’attaque
Un meilleur code ne suffit pas
- Des efforts existent déjà pour améliorer la qualité du code
- Des langages à sûreté mémoire comme Rust
- Des outils de renforcement de la sécurité comme AddressSanitizer
- Des fuzzer qui modifient automatiquement les entrées pour trouver vulnérabilités et bugs
- Mais beaucoup de problèmes de sécurité viennent de la logique sous-jacente plus que de bugs dans le code lui-même
- La vulnérabilité email de Barracuda provenait d’une bibliothèque tierce qui, en analysant des feuilles de calcul Excel pour y chercher des virus, exécutait en réalité du code
- La décision d’ajouter une fonction qui exécute automatiquement du code présent dans un document ne se résout pas simplement en supprimant tous les bugs du code
Ne pas savoir ce que l’on déploie
- Les logiciels modernes sont devenus si volumineux qu’il est difficile de savoir ce qui est réellement déployé
- Dans “A Plea for Lean Software” en 1995, Niklaus Wirth critiquait déjà des logiciels devenus gros comme des mégaoctets
- Son système d’exploitation Oberon faisait 200 KB, éditeur et compilateur compris
- Aujourd’hui, certains projets dépassent 200 KB rien qu’avec leurs fichiers de configuration
- Une application typique d’aujourd’hui peut être construite sur Electron JS
- Electron JS embarque Chromium et Node.js
- Node.js donne accès à des dizaines de milliers de packages JavaScript
- Le simple usage d’Electron JS pourrait déjà représenter au minimum 50 millions de lignes de code, dépendances comprises
- Les applications importent des centaines voire des milliers de packages auxiliaires, dont les dépendances tirent à leur tour d’autres dépendances
- Le contenu exact d’un build peut changer d’un jour à l’autre
- Certains packages peuvent, par défaut, exposer les utilisateurs à des annonceurs ou des courtiers en données
- Une application qui contrôle des appareils domestiques peut aussi se connecter à la pile logicielle d’Amazon, laquelle peut elle aussi reposer sur Node.js et de multiples dépendances
- Au final, même pour ouvrir une porte de garage, plus de 50 millions de lignes de code actives peuvent tourner sur plusieurs images système d’exploitation et plusieurs serveurs
Le poids des conteneurs et de la supply chain des dépendances
- Autrefois, on distribuait la sortie du compilateur ou un ensemble de fichiers interprétés, et l’installation ainsi que la configuration forçaient à réfléchir à ce que contenait le package
- Aujourd’hui, on distribue souvent des conteneurs qui embarquent non seulement le logiciel, mais aussi les fichiers du système d’exploitation nécessaires à son environnement d’exécution
- En pratique, on se retrouve fréquemment à distribuer une image complète de disque d’ordinateur
- Docker Hub contient de nombreuses images de plus de 350 MB
- Les conteneurs peuvent servir à de bonnes fins, mais selon leur usage réel, ils peuvent augmenter fortement la quantité de code déployé
- On ignore aussi si les mises à jour de sécurité des dépendances atteignent vraiment l’application finale
- Il est difficile de savoir si des bugs de traitement d’image qu’Apple et Google ont corrigés en urgence subsistent encore dans des applications Electron
- L’écosystème npm a un historique de prise de contrôle de dépôts de packages, de détournements et de résurrection de packages portant le même nom
- PyPI a connu des problèmes similaires
- Les dépendances doivent être examinées, mais on peut difficilement attendre de quelqu’un qu’il en vérifie des milliers régulièrement
- Tout réimplémenter soi-même n’est pas non plus la solution, et certains bons modules comme SQLite ont sans doute plus de chances d’être sûrs qu’une réécriture maison
Trifecta : un outil de partage d’images construit avec peu de code
- Trifecta est un logiciel autonome de partage d’images minimaliste, mais réellement utilisable
- Il permet de partager facilement des images par glisser-déposer dans le navigateur
- Avec imgur, de nombreux cookies et trackers s’installent dans le navigateur, et les personnes qui consultent l’image partagée peuvent elles aussi se voir imposer des trackers
- Même parmi les outils auto-hébergés de partage d’images, beaucoup reposent sur de gros frameworks jugés difficiles à approuver sur le plan de la confiance
- Trifecta a été conçu pour rester assez petit pour que l’on puisse examiner tout le code en quelques heures
- 1 600 lignes de nouveau code source
- Environ 5 dépendances importantes
- 3 MB de code au total
- Une autre solution de partage d’images citée à titre de comparaison est distribuée sous la forme d’une image Docker de 288 MB
- Une autre solution de partage de photos fondée sur Node comptait 1 600 dépendances et plus de 4 millions de lignes de JavaScript
- Trifecta n’est pas destiné à un site public où n’importe qui peut téléverser des images, mais convient à un usage en entreprise ou personnel
Le problème de prendre la complexité pour de la puissance
- L’une des réactions fréquentes à Trifecta consistait à recommander un déploiement via un bundle Amazon Web Services
- Une réponse en décalage avec l’objectif d’un logiciel autonome ne dépendant pas de services externes
- Certains ont aussi estimé que Docker était traité injustement, même s’il est reconnu que les conteneurs peuvent être utilisés à bon escient
- Dans son article de 1995, Niklaus Wirth soulignait que les gens ont tendance à confondre complexité et sophistication
- Comme le disait Tony Hoare, il existe deux façons de concevoir un logiciel
- Le rendre si simple que les erreurs sont manifestement absentes
- Le rendre si complexe qu’il semble manifestement exempt d’erreurs
- Wirth considérait la pression sur les délais comme une cause majeure de l’obésité logicielle
- La pression temporelle empêche une planification réfléchie
- Elle pousse à ajouter et modifier rapidement au lieu d’améliorer une solution acceptable
- Elle finit par éroder progressivement les standards de qualité et l’exigence de finition des ingénieurs
- L’explosion du logiciel n’est pas une loi de la nature, mais quelque chose que les ingénieurs logiciels doivent chercher à réduire
Réduire la quantité de code devient une mesure de sécurité
- Le monde déploie actuellement beaucoup trop de code
- La majeure partie est du code tiers
- Une partie est incluse involontairement
- L’essentiel n’est pas suffisamment inspecté
- Il en résulte une immense surface d’attaque, au sein de laquelle de grandes quantités de code banal sont exposées
- Les efforts pour améliorer la qualité du code se poursuivent, mais de nombreuses exploitations proviennent d’échecs logiques, domaine où les progrès de détection restent relativement limités
- Réduire simplement la quantité de code exposée au monde peut déjà apporter une amélioration majeure
- Le délai de mise sur le marché des produits peut s’allonger, mais les textes législatifs à venir pourraient pousser les fournisseurs à traiter la sécurité plus sérieusement
- Trifecta et Oberon montrent qu’il est possible d’offrir beaucoup de fonctionnalités avec un code et des dépendances limités
1 commentaires
Avis de Hacker News
Dans A Deepness in the Sky de Vernor Vinge, l’humanité s’est répandue parmi les étoiles avec seulement des technologies subluminiques, et les vaisseaux interstellaires sont un mélange d’anciennes technologies issues de plusieurs systèmes stellaires et civilisations
Les systèmes informatiques aussi ont évolué pendant si longtemps que presque plus personne ne comprend la majeure partie du code ; on se contente de l’utiliser et de reconstruire par-dessus
En particulier, l’un des personnages est un ancien ingénieur systèmes qui, après avoir longtemps alterné état de stase et voyages, fait partie des humains vivants les plus âgés ; dans un futur où tout le monde a empilé de nombreuses couches par-dessus, connaître le fonctionnement et les vulnérabilités de son époque devient au contraire un avantage majeur
Je pense que Vinge avait mis le doigt sur quelque chose
Le premier est un vrai mystère que la science moderne et des gens très intelligents doivent résoudre, tandis que le second relève plutôt d’un manque d’intérêt
Si l’on payait suffisamment, un ingénieur compétent démonterait la machine à laver et trouverait précisément la panne, mais personne ne paiera ce coût : on la jettera simplement pour en acheter une nouvelle
Les connaissances sur les anciens logiciels relèvent clairement du second cas. Si l’on creuse n’importe quelle partie, on peut finir par la comprendre entièrement, mais la plupart du temps, il est beaucoup moins cher et plus pratique de l’ignorer ou d’ajouter encore une couche par-dessus
Elle raconte une humanité future qui a oublié l’arithmétique de base, et où, lorsque quelqu’un la redécouvre, les puissants veulent l’utiliser pour la guerre ; je comprends le message qu’elle cherche à faire passer, mais le postulat est tellement irréaliste et ridicule qu’il en perd sa force, à mon avis
Pour approfondir la discussion, voir http://lambda-the-ultimate.org/node/4424
Nous sommes déjà confrontés à ce genre de problème. Mon oncle, qui a la soixantaine, maintient un vieux logiciel de transport routier écrit en COBOL, et il existe des emplois liés à ce type de technologies anciennes. Si cela vous intéresse, je peux vous mettre en relation
Le problème de fond est le même que dans l’affaire left-pad. On se moque des ingénieurs juniors sans supervision qui installent des dépendances n’importe comment, mais après des décennies et plusieurs générations de développeurs, la plupart des logiciels finissent, dans une certaine mesure, par dépendre de dépendances dont on ne sait pas grand-chose
Imaginons qu’il faille déployer une mise à jour en 2100 : elle passera par le système de gestion des dépendances npm de l’époque. En même temps, il pourrait y avoir, à l’échelle du système solaire, des appareils dépendants nécessitant des mises à jour de sécurité, des milliers de milliards d’appareils et des caches intermédiaires dont on ne sait pas s’ils sont à jour. Je n’ose pas imaginer à quoi ressemblerait un tel arbre de dépendances
Travailler dans un environnement où il faut fouiller le code du framework pour atteindre le cœur du sujet est aussi frustrant. On a l’impression de perdre son temps
La bloatware se voit dans la plupart des bibliothèques npm. Les auteurs ne connaissent pas les bons principes de conception et veulent que chaque bibliothèque fasse tout
Une bibliothèque censée convertir des encodages de chaînes se retrouve par exemple avec, dans le même dépôt, le chargement et l’enregistrement de fichiers, le téléchargement depuis Internet, et même un outil en ligne de commande. Une bibliothèque devrait faire une seule chose, la sienne, et laisser le reste à l’utilisateur
Côté Rust, ça ne semble pas beaucoup mieux. Si vous essayez de corriger la documentation de Rust, vous verrez qu’environ 1 000 crates sont installées
Le problème n’est pas le langage, mais le fait que n’importe qui peut publier une bibliothèque, et que, dans les faits, n’importe qui le fait. Les gens qui veulent « juste que ça marche » choisissent la bibliothèque qui a le plus de fonctionnalités, et réclament encore plus de fonctions parce qu’ils ne veulent pas écrire trois lignes de code en dehors de la bibliothèque. Du genre : « Est-ce que vous pourriez aussi ajouter le rendu PDF ? »
Je ne sais pas trop quelle est la solution, mais j’ai pensé à créer un groupe de défense du Low Dependency et un badge, pour donner envie aux auteurs de bibliothèques de l’obtenir, et aux utilisateurs de le rechercher au moment de choisir une bibliothèque
À l’inverse, si vous voulez une bibliothèque avec peu de dépendances, vous allez en prendre quelques-unes qui font beaucoup de choses
De mon point de vue, une bibliothèque un peu épaisse, avec peu de dépendances et écrite par un auteur de confiance, est préférable. Lodash est gros, mais sa version en modules ES6 prend en charge le tree shaking et joue en pratique le rôle de bibliothèque standard qui manquait à JavaScript. date-fns fait quelque chose de similaire pour Date. Pour combler les lacunes de la bibliothèque cœur de JavaScript, j’ajoute presque toujours ces deux-là par défaut à mes projets
J’ai travaillé autrefois en mission Ruby on Rails, et les problèmes de performance étaient tellement graves que nous développions en mode release. Le serveur n’arrivait même plus à détecter les changements de fichiers pour recharger automatiquement
Un jour, à bout, j’ai commencé à creuser, et il y avait tellement de gems importées que je ne me souviens même plus du nombre. L’une d’elles servait littéralement à économiser 3 lignes de code
Après ça, je me suis tenu à l’écart de la communauté RoR. Récemment, après plusieurs années, j’ai repris une mission RoR ; ce n’est plus aussi mauvais qu’avant, mais ce n’est toujours pas bon
Certaines communautés n’ont aucun respect pour les risques qu’apportent les dépendances
En revanche, le fait que n’importe quel dépôt Git puisse héberger une bibliothèque Go, et que n’importe qui puisse l’utiliser depuis cette URL, est vraiment pratique
D’abord, les créateurs de paquets veulent en faire une carrière, et le seul moyen d’obtenir de l’attention est de créer une multitude de paquets. Ils continuent donc à créer des paquets qui dépendent de leurs autres paquets, et essaient de faire entrer un ou deux paquets utiles dans le code des autres
Ensuite, il y a ceux qui croient que résoudre un problème implique toujours d’ajouter un nouveau paquet. Ils ne se soucient ni du nombre de dépendances, ni de savoir si le problème réel est difficile. Au lieu d’apprendre à résoudre le problème, ils apprennent donc l’API d’un wrapper à 4 étoiles sur GitHub
Idéalement, un tel outil passerait le temps fastidieux nécessaire à élaguer les paquets inutiles, à réduire au minimum la responsabilité de chaque paquet, à remettre l’environnement en ordre de manière raisonnable, puis à le mettre en cache de façon indépendante pour supprimer la dépendance au LLM. Il ne devrait faire appel à un vérificateur de mises à jour ou à un curateur que lorsqu’un problème survient
Honnêtement, je pense que c’est l’un des pires problèmes du logiciel moderne, et qu’il rend plus de 50 % des projets inutilisables. C’est un problème ennuyeux mais soluble, exactement le genre de tâche qui conviendrait à un bon agent LLM, et il serait très utile d’en avoir un
« Avez-vous déjà vu un avion moderne ? Avez-vous suivi, d’année en année, l’évolution de ses lignes ? Avez-vous déjà songé que, non seulement pour les avions mais pour tout ce que l’homme fabrique, les efforts industriels de l’humanité, ses calculs et ses nuits passées sur les plans finissent par converger vers un principe unique et dominant : la simplicité ultime ?
C’est comme s’il existait une loi naturelle imposant que les courbes d’un meuble, la quille d’un navire ou le fuselage d’un avion soient affinés par des générations d’expériences d’artisans, jusqu’à s’approcher de cette pureté primitive des courbes d’une poitrine ou d’une épaule humaine. Il semble que la perfection soit atteinte non pas lorsqu’il n’y a plus rien à ajouter, mais lorsqu’il n’y a plus rien à retrancher. »
— Antoine de Saint-Exupéry, Terre des Hommes
Quand on l’écrit sous la forme « ouvrir une porte de garage peut nécessiter plus de 50 millions de lignes de code actif et des images de systèmes d’exploitation sur plusieurs serveurs », ça paraît vraiment délirant
Quand je pense à la quantité de code qui tourne sur la machine avec laquelle je tape ce texte, ça donne le vertige. Du code que je n’ai jamais examiné, et qui n’a probablement presque jamais fait l’objet d’un examen rigoureux
Bon, je retourne installer des dépendances npm
La comparaison selon laquelle « le logiciel est désormais considéré comme si dangereux qu’on dit aux gens de ne pas l’exécuter eux-mêmes. On leur conseille plutôt de le confier à un fournisseur de “X as a service”, ou tout simplement au “cloud”. Comparez cela à une situation imaginaire où les voitures prendraient feu si souvent qu’on conseillerait de ne pas conduire soi-même, mais de confier la conduite à un professionnel toujours accompagné de pompiers spécialisés » est tellement bonne que j’aurais envie de la réutiliser
Mon ex-petite amie se méfiait du « cloud » pour des raisons rationnelles liées au fait d’avoir grandi dans l’ancien bloc de l’Est. Mais l’alternative consistait à espérer ne pas perdre le PC portable HP acheté au prix le plus bas. Après un peu de pédagogie, elle a au moins pu être rassurée sur ce point
Le problème, c’est le manque général d’éducation et le manque de prise en compte de ses conséquences. Au bout du compte, il faut accepter le risque, apprendre soi-même, ou s’en remettre aux fournisseurs SaaS et cloud. J’ai vu beaucoup de larmes, et peu de gens apprendre par eux-mêmes
C’est une question de responsabilité individuelle, mais comme personne ne veut l’assumer, confier cela à des experts peut être une solution moins mauvaise que se faire confiance à soi-même. La vraie réponse, c’est l’éducation, mais c’est désespérément difficile
Le logiciel ne peut pas devenir plus léger. Pour cela, il faut du temps, du talent et des personnes très bien payées, pas seulement quelqu’un qui assemble des exemples de 12 stacks techniques différentes pour fabriquer une combinaison Frankenstein
Je suis développeur indépendant, et quelqu’un qui a appris node.js l’an dernier et assemble en une journée node.js, des conteneurs, un service quelconque de base de données hébergée chez AWS, Lambda, du stockage objet, Cloudflare, YAML, React, Vite et d’autres dépendances pour produire une web app standardisée mais toujours fragile proposera toujours un prix inférieur au mien
Un logiciel léger, rapide, peu coûteux à exécuter et moins cher à maintenir revient moins cher à long terme, mais il est difficile à écrire de manière rentable
Autrefois, il y avait ce rêve où tout le monde utiliserait les hooks et routines standard fournis par le système pour les interfaces, etc. Pensez à des choses comme Macintosh Toolbox ou QuickDraw
On disait que le travail principal du développeur devait être d’écrire la logique du programme, et que les changements ou ajouts devaient être transparents. Les appels système devaient accomplir les mêmes tâches sans accroc même si le code interne changeait, et les nouvelles fonctionnalités devaient être des sur-ensembles des anciennes, de sorte que l’ancien code compile ou s’exécute sans problème tandis que les nouveaux logiciels gagnent davantage de capacités
On pensait que cela faciliterait la maintenance, normaliserait les interfaces et rendrait aussi le code plus léger, puisqu’il dépendrait beaucoup des appels système. L’ambiance était qu’il fallait éviter les bibliothèques externes
Ce rêve s’est vite effondré : pensez aux DLL. Une grande partie de la gestion de paquets et du packaging actuels semble surtout consister à garantir que les bonnes bibliothèques sont présentes
À l’époque, le développement logiciel à grande échelle en était encore presque à ses balbutiements, donc on comprend que les choses ne se soient pas passées comme espéré. Maintenant que l’expérience collective sur ces problèmes est beaucoup plus grande, je me demande si la conclusion est que ce rêve est irréalisable de manière saine, ou si l’état désordonné actuel a été suffisamment vécu pour ouvrir la voie à une tentative moderne
Si l’on veut des logiciels rapides, légers, stables et sûrs, même s’il est difficile d’obtenir les quatre à la fois, je ne suis pas sûr que la situation actuelle aille dans cette direction
Les premiers Lisp mettaient très peu de choses dans le langage, mais Raku pousse jusque dans la spécification du langage de petites choses qui iraient normalement dans une bibliothèque npm
C laissait décider soi-même comment construire le code, mais la plupart des nouveaux langages compilés fournissent avec eux une forme d’outil de build
Dans ce paysage, certaines choses fonctionnent assez bien, mais elles se font hors du contexte « toi, la machine, un nouveau projet » qui guidait les travaux de Wirth. Le problème, c’est qu’elles ont tendance à s’accompagner du seuil imposé par des dépendances énormes comme des bases de données ou des moteurs de navigateur, et si la manière dont ces dépendances ont été créées ne vous plaît pas, vous finissez malheureux
C’est ce que je répète sans cesse à propos de Rust
Si 70 % des anciennes vulnérabilités C++ sont réellement liées à la mémoire, il est possible qu’il y ait 70 % de vulnérabilités en moins par ligne de code qu’en C++
Mais si, en Rust, on importe des centaines de paquets et que le nombre de lignes de code est multiplié par 10, c’est une autre histoire
30 % de 100 000 lignes, en volume total, c’est plus que 100 % de 10 000 lignes
Même quelque chose comme QT, s’il avait été écrit en Rust, aurait constitué à lui seul des centaines de crates, mais la quantité de code et le niveau de risque assumé auraient été exactement les mêmes
Mais le gros problème, ce sont les vulnérabilités. Vaut-il mieux corriger un bug dans une bibliothèque partagée et ainsi corriger des centaines de bibliothèques, ou corriger des centaines de bibliothèques une par une ?
Le fait que Rust facilite l’import de nombreuses petites dépendances plutôt que de quelques énormes dépendances n’a rien à voir. Cela ne veut pas dire qu’on écrit plus de code
Par exemple, compte-t-on la crate
regexde Rust comme une dépendance ? En C++, c’est dans la bibliothèque standardCompte-t-on Boost comme une seule dépendance en C++ ? En Rust, cela correspondrait à une trentaine de crates distinctes
Combien y a-t-il eu d’exécutions de code à distance dans les programmes Rust par rapport au C++ ? Je pense que la fréquence des exécutions de code à distance en C++ dépasse de très loin celle de Rust, bien au-delà de 70 %
On dit souvent que les apps d’aujourd’hui sont généralement faites en Electron JS, mais on semble ne pas assez savoir qu’il est aussi possible d’utiliser les contrôles web natifs de chaque plateforme sans embarquer Electron.
Avec cette approche, l’application distribuée peut ne peser que quelques kilo-octets. Elle laisse la liberté d’utiliser n’importe quel langage backend ou stack technique, tant qu’il est possible de communiquer avec la vue web.
Aujourd’hui, les PWA ne devraient-elles pas être possibles pour une assez grande part des applications ?
Je ne suis pas sûr, mais Discord ne pourrait-il pas aussi être une PWA plutôt qu’une app Electron ?
Le plus gros manque serait sans doute quelque chose de puissant équivalent à SQLite, par rapport à IndexedDB ; cela dit, la plupart des apps n’ont probablement pas absolument besoin d’un langage de requête de plus haut niveau que le modèle en B-tree d’IndexedDB.
Un nouvel hommage à la philosophie suckless. Hourra.
[0 ]https://suckless.org/