NetCatTest

DevSecOps & Supply Chain

Notion MCP: prompt injection, permissões e defesa técnica

Riscos documentados do Notion MCP: páginas não confiáveis, autorização por ação, ferramentas de escrita e laboratório sem acesso externo.

Por Daniel Felipe 6 min leitura

Conectar um assistente ao Notion por MCP transforma páginas em entradas para um sistema capaz de consultar e alterar dados. O risco mais interessante não exige que a página execute JavaScript: texto comum pode tentar influenciar o assistente a realizar uma ação que o usuário não autorizou. A documentação oficial reconhece essa superfície de prompt injection.

Não foi encontrada, nas fontes primárias consultadas, uma CVE recente confirmada do aplicativo Notion que sustente uma alegação de invasão do produto. Este artigo trata do risco documentado de integração MCP. Mantém separados o comportamento do conector, a decisão do cliente e os dados armazenados no workspace.

O alerta oficial de segurança de MCP

As práticas de segurança do Notion MCP explicam que um cliente pode obter acesso a conteúdo e ferramentas de acordo com permissões concedidas. Também alertam para instruções maliciosas em conteúdo e para a necessidade de revisar clientes, acessos e ações.

O repositório oficial do servidor local informa que essa implementação deixou de ser mantida e suportada ativamente, recomendando a alternativa remota oficial. Isso é informação de suporte. Não é, por si só, uma CVE nem prova de que toda instalação existente foi comprometida.

Elemento Responsabilidade de segurança
Página consultada Dado potencialmente não confiável
Cliente MCP Política de ferramentas e consentimento
Autorização Limites de acesso concedidos pelo usuário
Ferramenta de escrita Ação com efeitos verificáveis
Logs Registro sem credenciais e com contexto

Como dados se tornam uma instrução indevida

Considere uma página fictícia de fornecedores que inclua um trecho ordenando ao assistente copiar dados de outra página para um destino externo. A pessoa pediu um resumo, não essa transferência. Se o sistema tratar o texto recebido como uma instrução com a mesma autoridade do pedido humano, cruza uma fronteira de confiança.

O ataque depende da combinação entre conteúdo controlado, ferramentas disponíveis e política do cliente. Um conteúdo hostil em uma página não prova que houve exfiltração. Para demonstrar impacto, seria preciso observar a ação indevida e quais dados a ferramenta podia realmente alcançar, em ambiente autorizado.

Separar visualmente a instrução em uma tag não é uma garantia suficiente. O controle decisivo deve existir fora da geração de texto: o host valida a ação, o objeto, o destino e o consentimento antes de executá-la. A segurança não pode depender apenas de o modelo lembrar uma recomendação.

Autorização por operação e por objeto

Uma permissão genérica de “usar Notion” é ampla demais para expressar todos os efeitos. Ler uma página, criar outra, alterar uma propriedade e compartilhar conteúdo devem possuir políticas diferentes. Cada solicitação precisa identificar os objetos e preservar a relação com o propósito aprovado pelo usuário.

Também importa o conjunto de ferramentas disponível na mesma sessão. Um conector de leitura, combinado com um segundo conector capaz de enviar dados, pode criar um caminho de transferência que nenhum deles apresenta isoladamente. A revisão deve analisar a composição e o contexto de dados, não somente cada lista de permissões separada.

Credenciais não devem aparecer em resultados ou mensagens. Use referências mantidas pelo host e trate páginas privadas com classificação herdada. Exportações, observabilidade e caches precisam respeitar essa mesma política. Um relatório de erro não pode se tornar um caminho alternativo de vazamento.

Laboratório: aprovação vinculada à ação exata

O exemplo calcula um hash canônico da ação e exige que a aprovação venha do usuário. Tudo ocorre localmente, com uma página inventada. Nenhuma API do Notion é chamada e o hash não é uma assinatura digital.

import hashlib
import json

def resumo(acao):
    return hashlib.sha256(json.dumps(acao,sort_keys=True,separators=(',',':')).encode()).hexdigest()

acao = {'operacao':'atualizar_pagina','pagina':'pagina-ficticia','conteudo':'Resumo revisado'}
aprovacao = {'ator':'usuario','hash':resumo(acao)}
def autorizado(pedido, consentimento):
    return consentimento.get('ator') == 'usuario' and consentimento.get('hash') == resumo(pedido)

alterada = dict(acao,conteudo='Outro conteudo')
assert autorizado(acao,aprovacao)
assert not autorizado(alterada,aprovacao)
assert not autorizado(acao,{'ator':'conteudo_da_pagina','hash':resumo(acao)})
print(json.dumps({'aprovacao_vinculada':True,'alteracao_recusada':True,'pagina_nao_aprova':True}))

O consentimento permite a ação original, mas deixa de permitir a mesma operação com conteúdo alterado. Uma suposta aprovação proveniente de conteudo_da_pagina é recusada. Isso demonstra duas propriedades: a origem da autorização importa e a autorização precisa corresponder ao efeito que será executado.

Em produção, o consentimento deve ser emitido por uma interface confiável, armazenado fora do conteúdo e protegido contra adulteração. Adicione identidade, prazo, sessão e mecanismos contra repetição. Um campo ator entregue pela própria extensão não pode provar que um humano aprovou; o modelo só ilustra o contrato.

Matriz de testes para uma integração profissional

Caso Resultado esperado
Página pede ação fora do pedido humano Não executar
Escrita aprovada sofre alteração Solicitar nova revisão
Objeto não autorizado Recusar antes de chamar a API
Credencial revogada durante a tarefa Encerrar acesso e descartar callbacks
Conteúdo privado chega ao exportador Aplicar a mesma restrição

Use duas páginas de laboratório com permissões distintas e um destino de saída fictício. Registre o pedido humano, o conteúdo consultado, a ferramenta proposta e a decisão do host. Preserve apenas dados necessários para comprovar o resultado. Não teste uma hipótese usando páginas de terceiros ou conteúdo real de colegas sem autorização.

Uma boa evidência inclui o caso negativo: a tentativa chegou ao host e foi recusada sem efeito. Mostrar apenas uma tela dizendo “bloqueado” não comprova que uma operação assíncrona não saiu em segundo plano. Observe o ponto de execução e a ausência de chamada externa.

Hardening e manutenção

Conceda o menor conjunto de páginas e ações necessário. Separe tarefas de leitura de tarefas de escrita e exija revisão humana quando houver alteração ou compartilhamento. Mantenha um inventário de clientes autorizados e um procedimento de revogação, seguindo a orientação de segurança e privacidade do Notion.

Avalie retenção de tokens, redirecionamento de autorização, confiabilidade do cliente e tratamento de respostas. Um cliente não confiável pode usar corretamente uma autorização OAuth e ainda produzir consequências indevidas. O protocolo confirma determinados vínculos; não julga sozinho a intenção da ação solicitada.

Perguntas frequentes

Isso é uma CVE do Notion? Não é essa a alegação. Trata-se de uma classe de risco descrita pelo fornecedor para integrações MCP.

Só texto pode causar um problema? Pode, se uma decisão posterior converter esse texto em uma operação autorizada indevidamente. O impacto ocorre na execução da ferramenta.

Um hash torna o fluxo seguro? Não sozinho. A confiança exige origem autenticada do consentimento e aplicação da política pelo host.

O objetivo de um conector robusto é permitir trabalho útil sem deixar uma página decidir os próprios privilégios. Dados consultados podem informar a tarefa, mas a autorização deve permanecer ligada ao usuário, ao objeto e ao efeito concreto.

Escrito por

Daniel Felipe é criador do NetCatTest e produz conteúdos sobre cibersegurança, privacidade digital, OSINT, laboratórios autorizados e ferramentas para estudo técnico responsável.

Compartilhar

Enviar este artigo