Segurança
Pivotick roda inteiramente no navegador: não há servidor, nem sessão e nem persistência própria. O limite que importa é aquele entre seus dados do gráfico e o DOM da sua página — Pivotick renderiza os dados que você entrega no documento que seu aplicativo possui.
Se esses dados vierem de algum lugar que você não controla totalmente – um feed de informações sobre ameaças, um espelho CVE, um conjunto de dados importado, upload de outro usuário – trate-os como não confiáveis e leia o restante desta página.
O que Pivotick garante
Tudo o que a biblioteca renderiza a partir dos seus dados é inserido como text, não como marcação. Isso abrange rótulos de nós e bordas, descrições, ids, chaves e valores de propriedades e conteúdo de notas:
- Rótulos, descrições e nomes/valores de propriedades são escritos com
textContent. - O conteúdo da nota é Markdown, renderizado com
markede depois higienizado com DOMPurify em relação a uma lista de permissões das tags que o próprio Markdown produz.<style>, os elementos do formulário e os atributosstyleembutidos não estão nele. - A marcação
style.svgIconé higienizada (perfil SVG) antes de chegar ao documento, portanto, os manipuladores de eventos<script>e<foreignObject>são removidos, assim como<style>e<a>. Um<style>embutido não tem como escopo o ícone, e um<a>transformaria a seleção do nó em uma navegação. Os atributos que sobrevivem são a lista de permissões SVG do DOMPurify maisdominant-baselineealignment-baseline, para que o texto possa ser centralizado da mesma forma que Pivotick centraliza seus próprios glifos.<use>é removido imediatamente, portanto, símbolos de sprite embutidos em vez de referenciá-los. style.imagePathestá restrito aos esquemashttp:,https:,data:eblob:.- As cores dos dados,
style.colorde um nó ecolorde uma nota, devem ser analisadas como CSS cores antes de chegarem ao documento, portanto, não podem contrabandear umurl()para umbackground. - Os valores de propriedade renderizados como links carregam
rel="noopener noreferrer", e qualquer um que saia de sua origem, incluindo//host/path, abre em uma nova guia em vez de substituir a sua.
Portanto, um string sempre é renderizado como texto. Sempre que uma opção aceita string | HTMLElement, retornar uma string fornece texto; para renderizar seu próprio HTML, construa e retorne um HTMLElement:
// 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
} }Alterado em 1.4.0/1.5.0
Versões anteriores analisavam strings como HTML — valores de propriedade em 1.3.0 e anteriores, todas as outras opções string | HTMLElement (painéis extras, entradas de menu de contexto, renderizadores personalizados) até 1.4.0. Se você estava confiando nisso para injetar marcação, mude para o retorno de um elemento.
Pias HTML confiáveis
Existem algumas opções especificamente para que você possa fornecer sua própria marcação. Pivotick insere o que você fornece verbatim, então nunca construa estes a partir de dados não confiáveis:
| Opção | Onde |
|---|---|
rawHeader / rawBody | Opções Modal e SlidePanel |
render.defaultNodeStyle.html | conteúdo do nó desenhado em um <foreignObject> |
Se você precisar de dados dentro de um deles, coloque-os com textContent em um elemento que você criou, em vez de interpolá-los em uma string de marcação:
// 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 })Solicitações de saída
Os nós podem fazer referência a imagens, via style.imagePath ou um <image href> dentro de style.svgIcon. A renderização de tal nó faz com que os navegadores dos usuários busquem esse URL. Se o URL vier de dados não confiáveis, quem o escreveu saberá que o gráfico foi visualizado, juntamente com o endereço IP do visualizador, o tempo e User-Agent — um pixel de rastreamento.
As restrições do esquema não podem impedir isso, porque https: deve ser permitido para que o recurso funcione. Se seus dados não forem confiáveis e isso for importante para você, remova/reescreva as referências de imagem antes de entregar os dados ou restrinja-os com uma Política de Segurança de Conteúdo.
Política de segurança de conteúdo recomendada
Pivotick não precisa de eval nem de <script> embutido, portanto funciona sob uma política estrita. Um CSP é a maneira mais barata de atenuar qualquer injeção — na biblioteca, em seu próprio código ou em outra dependência:
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-srcsem'unsafe-inline'é o que neutraliza os manipuladores de eventos injetados.img-srcé onde você determina de onde as imagens dos nós de hosts podem vir.form-actionlimites onde qualquer formulário injetado poderia postar, seja lá o que foractiondiz.style-src 'unsafe-inline'é atualmente necessário: o renderizador define estilos embutidos e a folha de estilo de Pivotick normalmente é injetada pelo seu empacotador. Sirva o CSS como um arquivo e use um nonce ou hash se precisar eliminá-lo.
Relatando uma vulnerabilidade
Por favor, relate suspeitas de vulnerabilidades através de GitHub avisos de segurança em vez de um problema público.