Sécurité et données : votre travail reste en local
PanelCraft est une application de bureau conçue pour fonctionner hors ligne. Vos projets, tarifs, fiches clients et images de décors sont stockés sur votre propre machine, et l’application est construite pour qu’un fichier hostile ou un composant défaillant ne puisse pas aller au-delà de ce dont il a besoin.
Questions de sécurité : hello@panelcraft.store.
Hors ligne par conception
Conception, débit, prix, plans, documents, export d’usinage et vue en pièce s’exécutent tous en local. L’interface de l’application n’a le droit de rien charger depuis le réseau : sa politique de contenu limite chaque type de source à l’application elle-même, et la session par défaut annule toute requête sauf les fichiers locaux, les URL data et blob.
Une seule chose a besoin d’internet : la licence. L’application s’active une fois, puis vérifie la licence en ligne quand une vérification est due. Si elle ne peut pas joindre le service de licences, elle continue de fonctionner pendant une période de grâce de plusieurs jours : un atelier à la mauvaise connexion n’est donc pas interrompu. Les erreurs de réseau et de serveur ne suppriment jamais une licence existante ; seul un refus explicite du service le fait.
Aucun projet, tarif, fiche client, image de décor ni photo de pièce n’est jamais envoyé.
Où vivent vos données
Tout est stocké sur votre ordinateur, à des endroits que vous pouvez retrouver et sauvegarder.
| Données | Emplacement | Remarques |
|---|---|---|
| Projets | Là où vous enregistrez le fichier .panelcraft | Écrits de façon atomique (fichier temporaire, puis renommage). L’ouverture lit 50 Mo au plus. |
| Index des projets, clients, devis | Une base SQLite locale dans le dossier de données de l’application | Conservée en mémoire et enregistrée de façon atomique après chaque transaction. Un fichier illisible est renommé à part, jamais supprimé. |
| Bibliothèques et stock | Fichiers JSON dans le dossier de données de l’application | Lus sur 10 Mo au plus, validés avant usage. |
| Images de décors | Le dossier de données de l’application, stockées par empreinte de contenu | Validées d’après le contenu : 8 Mo, 16 à 8192 px, 36 mégapixels par image. |
| Photo de la vue en pièce | Une copie réduite dans le dossier de données de l’application | 10 Mo au plus, validée par ses octets magiques, dossier nommé d’après une empreinte de l’identifiant du projet. |
| Licence | Deux copies d’un fichier d’état de licence dans le dossier de données de l’application | La copie valide à la date de vérification la plus récente l’emporte : supprimer ou modifier une copie ne remet donc pas le compteur d’essai à zéro. |
Les exports quittent l’application sous forme de simples fichiers : PDF, CSV, DXF, SVG et images. Vous choisissez où ils sont écrits, et l’application ne décide jamais d’un chemin à votre place.
Contre quoi la conception protège
Le modèle de menaces nomme quatre adversaires. Un fichier malveillant ou corrompu que vous ouvrez ou importez (un projet, un CSV, une bibliothèque, une image ou une base de données) est traité comme une donnée non fiable. Une interface compromise, par exemple par une faille dans une dépendance, l’est aussi : elle ne doit pas pouvoir lire ou écrire des fichiers arbitraires, exécuter du code dans le processus principal, contourner la licence ni atteindre le réseau. Un utilisateur local qui altère les fichiers de licence ou l’horloge est géré à un niveau raisonnable. Et la chaîne d’approvisionnement, les dépendances npm et Electron lui-même, est maintenue réduite et examinée.
Sont hors du périmètre un attaquant qui exécute déjà du code sous votre identité, un système d’exploitation malveillant et l’accès physique à la machine. Aucune application de bureau ne peut s’en défendre, et nous ne prétendons pas le faire.
Les mesures
| Domaine | Mesure |
|---|---|
| Isolation du processus de rendu | Processus de rendu isolé (sandbox) avec isolation du contexte et sans intégration Node. Aucun contenu distant ni vue web intégrée. Sandbox de l’application activée pour chaque fenêtre. |
| Appels au processus principal | Chaque appel est contrôlé : l’émetteur doit être le cadre principal de la page empaquetée, chaque argument est vérifié en type et borné en taille, les champs inconnus sont écartés, et les extensions d’export figurent sur une liste blanche. |
| Chemins de fichiers | L’interface ne choisit jamais où lire ou écrire. Les lectures viennent des boîtes de dialogue d’ouverture natives, les écritures des boîtes d’enregistrement natives ou de fichiers appartenant à l’application. Un chemin n’est accepté pour l’enregistrement que si vous l’avez choisi dans une boîte de dialogue pendant la session ou s’il figure déjà dans l’index écrit par le processus principal. |
| E/S de fichiers bornées | Les lectures sont plafonnées en taille (projet 50 Mo, CSV 10 Mo, magasins 10 Mo, base de données 512 Mo, licence 64 Ko) et doivent porter sur des fichiers ordinaires, ni périphériques ni répertoires. Les écritures utilisent un nom temporaire aléatoire ouvert en exclusivité puis renommé : un lien piégé n’est jamais suivi. |
| Données mal formées | Le texte des projets, bibliothèques et stocks doit s’analyser comme un objet ou un tableau JSON avant usage. Les erreurs d’analyse deviennent un message clair, jamais un plantage. |
| Politique de contenu | Politique de production : sources de scripts, de styles, d’images, de polices et de connexions limitées à l’application elle-même ; pas d’eval ; pas de script ni de style en ligne ; pas de cadres ni d’objets ; pas de base ni de cibles de formulaire. |
| Rendu PDF | Une fenêtre cachée sans JavaScript, avec sa propre session en mémoire qui annule tout sauf les URL data, permissions refusées, navigation et fenêtres contextuelles refusées, et un délai de 60 secondes. Le balisage est de nouveau nettoyé dans le processus principal, une politique est injectée comme premier élément, et les scripts, cadres, objets, éléments embarqués, éléments base et link et gestionnaires d’événements sont supprimés. Le texte saisi est échappé à la génération des documents. |
| Navigation | La fenêtre ne peut naviguer que vers sa propre page ; les nouvelles fenêtres sont toujours refusées ; les liens web s’ouvrent dans le navigateur du système ; les vues web et les demandes de permissions sont refusées. |
| Images | Les décors et les photos de pièces sont validés d’après le contenu (octets magiques et taille en pixels dans l’en-tête), refusés s’ils sont des liens, des répertoires ou trop volumineux, stockés sous une empreinte et décodés sans assouplir la politique de contenu. |
| Base de données | Chaque requête est une instruction préparée avec paramètres liés. Le seul endroit qui construit une liste de colonnes utilise des littéraux fixes. Les caractères génériques sont échappés, et des tests adverses couvrent les charges d’injection. |
| Durcissement de l’exécution | L’application empaquetée bascule les fusibles d’exécution : le mode d’exécution node est désactivé, la variable NODE_OPTIONS et les options d’inspection sont désactivées, le chiffrement des cookies est activé, seule l’archive empaquetée peut être chargée et son intégrité est contrôlée. |
Une licence sans surveillance
Une licence est un jeton signé : un ensemble de déclarations (formule, fonctions, expiration, limite d’appareils, jours de grâce) et une signature Ed25519 sur ces déclarations. L’application vérifie la signature sur votre machine avec une clé publique intégrée ; la clé privée n’existe que sur le serveur de licences. Les contrôles de fonctions s’exécutent dans le processus principal, dans les gestionnaires qui enregistrent, exportent et lisent les données : une interface modifiée ne peut donc pas activer des fonctions.
La gestion du temps est monotone. L’application retient la date la plus récente qu’elle a vue et ne revient jamais en arrière : reculer l’horloge ne prolonge donc ni un essai ni une période de grâce. L’essai et la période de grâce sont comptés à partir de cette horloge.
L’appel de licence envoie une clé de licence et un identifiant d’appareil, et rien sur vos projets.
Dépendances et tests
Le JavaScript livré est réduit : React, three.js, une petite bibliothèque d’état, un moteur SQLite compilé en WebAssembly et les paquets propres au projet. Le moteur SQLite n’exige aucune compilation native, ce qui supprime toute une catégorie de problèmes de compilation par plateforme.
Le comportement de sécurité est couvert par des tests : contrôles de l’émetteur, validation des chemins et des arguments, traversée de répertoires et écritures par liens, JSON surdimensionné ou mal formé, durcissement du balisage d’impression, liste d’autorisation d’URL et politique de contenu ; charges d’injection SQL ; octets magiques des décors, tailles d’en-tête, bombes de décompression, traversée, liens et falsification ; et tests de bout en bout qui falsifient des chemins, tentent des exports dangereux, enfreignent la politique de contenu, naviguent, ouvrent des fenêtres, envoient des appels depuis une fenêtre étrangère et fournissent des fichiers hostiles et un balisage PDF hostile.
Si vous découvrez un problème de sécurité, écrivez à hello@panelcraft.store avec les détails.
Le logiciel en images
Essayez-le sur votre propre machine
Téléchargez PanelCraft pour Windows ou macOS et menez-y un vrai projet, du dessin au devis. L’essai de 14 jours inclut toutes les fonctions Studio.
Une question avant de commencer ? Écrivez à hello@panelcraft.store ou consultez la FAQ.





