Aller au contenu

Sécurité ​

Pivotick s'exécute entièrement dans le navigateur : il n'y a pas de serveur, pas de session et pas de persistance propre. La limite qui compte est celle entre les données de votre graphique et le DOM de votre page — Pivotick restitue les données que vous lui transmettez dans le document que possède votre application.

Si ces données proviennent d'un endroit que vous ne contrôlez pas entièrement (un flux d'informations sur les menaces, un miroir CVE, un ensemble de données importé, le téléchargement d'un autre utilisateur), traitez-les comme non fiables et lisez le reste de cette page.

Ce que Pivotick garantit ​

Tout ce que la bibliothèque restitue à partir de vos données est inséré sous forme de text, pas de balisage. Cela couvre les étiquettes de nœuds et de bords, les descriptions, les identifiants, les clés et valeurs de propriété et le contenu des notes :

  • Les étiquettes, les descriptions et les noms/valeurs de propriété sont écrits avec textContent.
  • Notez que le contenu est Markdown, rendu avec marked puis nettoyé avec DOMPurify par rapport à une liste verte des balises que Markdown lui-même produit. <style>, les éléments du formulaire et les attributs style en ligne n'y figurent pas.
  • Le balisage style.svgIcon est nettoyé (profil SVG) avant d'atteindre le document, donc les gestionnaires d'événements, <script> et <foreignObject> sont supprimés, tout comme <style> et <a>. Un <style> en ligne n'est pas limité à l'icône, et un <a> transformerait la sélection du nœud en une navigation. Les attributs qui survivent sont la liste verte SVG de DOMPurify plus dominant-baseline et alignment-baseline, de sorte que le texte peut être centré de la même manière que Pivotick centre ses propres glyphes. <use> est carrément supprimé, donc inline les symboles de sprite plutôt que de les référencer.
  • style.imagePath est limité aux schémas http:, https:, data: et blob:.
  • Les couleurs des données, le style.color d'un nœud et le color d'une note, doivent être analysées comme des couleurs CSS avant d'atteindre le document, afin qu'elles ne puissent pas faire passer clandestinement un url() dans un background.
  • Les valeurs de propriété rendues sous forme de liens portent rel="noopener noreferrer", et celles qui quittent votre origine, //host/path inclus, s'ouvrent dans un nouvel onglet plutôt que de remplacer le vôtre.

Un **string s'affiche donc toujours sous forme de texte. ** Partout où une option accepte string | HTMLElement, renvoyer une chaîne vous donne du texte ; pour rendre votre propre HTML, construisez et renvoyez un HTMLElement :

ts
// Renders the literal characters "<b>hi</b>"
propertiesPanel: { render: () => '<b>hi</b>' }

// Renders bold text
propertiesPanel: { render: () => {
    const el = document.createElement('b')
    el.textContent = 'hi'
    return el
} }

Modifié dans 1.4.0 / 1.5.0

Les versions antérieures analysaient des chaînes telles que HTML — valeurs de propriété dans 1.3.0 et versions antérieures, toutes les autres options string | HTMLElement (panneaux supplémentaires, entrées de menu contextuel, moteurs de rendu personnalisés) jusqu'à 1.4.0. Si vous comptiez sur cela pour injecter du balisage, passez au renvoi d'un élément.

Éviers de confiance HTML ​

Quelques options existent spécifiquement pour que vous puissiez fournir votre propre balisage. Pivotick insère ce que vous lui donnez verbatim, donc ne les construisez jamais à partir de données non fiables :

OptionsOù
rawHeader / rawBodyOptions Modal et SlidePanel
render.defaultNodeStyle.htmlcontenu du nœud dessiné dans un <foreignObject>

Si vous avez besoin de données dans l'un d'entre eux, placez-les avec textContent sur un élément que vous avez créé, plutôt que de les interpoler dans une chaîne de balisage :

ts
// Unsafe: node.data.label lands in innerHTML
uiManager.createModal({ rawBody: true, body: `<h1>${node.getData().label}</h1>` })

// Safe
const title = document.createElement('h1')
title.textContent = node.getData().label
uiManager.createModal({ body: title })

Demandes sortantes ​

Les nœuds peuvent référencer des images, via style.imagePath ou un <image href> à l'intérieur de style.svgIcon. Le rendu d'un tel nœud permet aux navigateurs de vos utilisateurs de récupérer cette URL. Si l'URL provient de données non fiables, celui qui l'a écrit apprend que le graphique a été consulté, ainsi que l'adresse IP du spectateur, l'heure et User-Agent — un pixel de suivi.

Les restrictions de schéma ne peuvent pas empêcher cela, car https: doit être autorisé pour que la fonctionnalité fonctionne. Si vos données ne sont pas fiables et que cela vous intéresse, supprimez/réécrivez les références d'image avant de transmettre les données, ou limitez-les à l'aide d'une politique de sécurité du contenu.

Pivotick n'a besoin ni de eval ni de <script> en ligne, il fonctionne donc selon une politique stricte. Un CSP est le moyen le moins cher d'atténuer toute injection — dans la bibliothèque, dans votre propre code ou dans une autre dépendance :

Content-Security-Policy:
    default-src 'self';
    script-src 'self';
    img-src 'self' data: blob: https://images.example.com;
    style-src 'self' 'unsafe-inline';
    form-action 'self';
  • script-src sans 'unsafe-inline' est ce qui neutralise les gestionnaires d'événements injectés.
  • img-src est l'endroit où vous déterminez de quels hôtes les images de nœuds peuvent provenir.
  • form-action limites où n'importe quel formulaire injecté pourrait être publié, quoi que dise son action.
  • style-src 'unsafe-inline' est actuellement requis : le moteur de rendu définit les styles en ligne et la feuille de style de Pivotick est normalement injectée par votre bundler. Servez le CSS sous forme de fichier et utilisez un nom occasionnel ou un hachage si vous devez le supprimer.

Signaler une vulnérabilité ​

Veuillez signaler les vulnérabilités suspectées via les GitHub avis de sécurité plutôt que via un problème public.