flawopen.com/Desserialização insegura/Segurança do pickle em Python
O pickle.load() do Python é seguro para dados não confiáveis?
Não. Trate o pickle como um programa dentro de uma encomenda, não como um registro passivo: carregá-lo pode acionar a reconstrução antes de a aplicação validar o objeto. Use um formato somente de dados para entradas que cruzam uma fronteira de confiança.
import pickle # Never accept pickle bytes from a request, upload, # shared cache, or other untrusted source. obj = pickle.loads(untrusted_bytes)
import json
def parse_profile(raw: bytes) -> dict[str, str]:
if len(raw) > 65_536:
raise ValueError("Payload too large")
try:
value = json.loads(raw)
except (json.JSONDecodeError, UnicodeDecodeError):
raise ValueError("Invalid JSON") from None
if not isinstance(value, dict) or set(value) - {"display_name", "theme"}:
raise ValueError("Invalid profile")
name = value.get("display_name")
theme = value.get("theme")
if not isinstance(name, str) or len(name) > 80:
raise ValueError("Invalid display name")
if theme not in {"light", "dark"}:
raise ValueError("Invalid theme")
return {"display_name": name, "theme": theme}
- Fluxo pickle:
- Sequência de bytes específica do Python que descreve a reconstrução de objetos, incluindo referências a globais e comportamento de reconstrução.
- Unpickling:
- Interpretação do fluxo e reconstrução do grafo de objetos; o processo pode invocar funções.
- Fronteira de confiança:
- Ponto em que bytes podem ser controlados ou alterados por usuário, serviço, upload ou armazenamento compartilhado.
- CWE-502:
- Desserialização de dados não confiáveis; o impacto depende de um atacante poder fornecer ou adulterar os dados carregados.
Bytes não confiáveis chegam ao pickle
Um upload, solicitação, cache ou artefato pode levar dados pickle controlados ou adulterados até o processo.
O unpickler resolve globais
O interpretador processa instruções de reconstrução; find_class() pode importar e retornar globais nomeados, inclusive funções.
O carregamento aciona comportamento
As instruções podem invocar funções durante load() ou loads(), antes da validação do objeto retornado.
O impacto depende das permissões do processo
O comportamento executa com as permissões do processo Python. Rede, segredos, arquivos e isolamento determinam o alcance.
Por que o carregamento do pickle cruza uma fronteira de execução de código
Um fluxo pickle pode nomear globais e funções de reconstrução. Durante o unpickling, Unpickler.find_class() resolve globais, inclusive funções; opcodes podem invocar a reconstrução. O passo perigoso é pickle.load() ou pickle.loads(): não existe uma chamada posterior separada para executar. O código resultante usa as permissões do processo. Esse comportamento faz parte do formato; não use pickle para intercambiar dados não confiáveis.
O que JSON resolve — e o que não resolve
A documentação do Python alerta que unpickling de dados não confiáveis ou adulterados pode executar código arbitrário, enquanto decodificar JSON não cria, por si só, essa via de execução. JSON não valida a entrada automaticamente: limite o tamanho, exija o tipo superior e os campos esperados, valide valores com um esquema e aplique autorização separadamente. Se um fluxo legado ainda precisar de pickle, autentique os bytes exatos com uma chave protegida antes de carregar; uma assinatura só comprova origem e integridade sob as premissas da chave e não torna seguro um conteúdo malicioso assinado por fonte confiável. Migre para formato somente de dados.
- ✓Remova
pickle.load()epickle.loads()de rotas que recebem solicitações, uploads, caches compartilhados ou artefatos de origem incerta. - ✓Use JSON ou outro formato somente de dados e imponha limite de tamanho, esquema, campos permitidos, limites de valores e autorização do endpoint.
- ✓Se um fluxo interno confiável ainda usar pickle temporariamente, valide HMAC ou assinatura dos bytes exatos antes do carregamento, proteja a chave e reduza as permissões do processo.
- ✓Procure consumidores de pickle no código e nos fluxos de dados; identifique quem pode gravar ou adulterar cada origem e migre ou isole usos inseguros.
Perguntas frequentes
Sobrescrever find_class() pode reduzir riscos restringindo globais, mas provar que um loader é seguro em todos os protocolos e comportamentos alcançáveis é difícil. Não trate uma lista de permissões como defesa padrão para bytes controlados pelo usuário; prefira formato somente de dados.
Sim. JSON evita a execução arbitrária de código típica do pickle durante a decodificação, mas a aplicação ainda deve validar tipos, campos, tamanhos, limites e autorização. Separe análise JSON das regras de negócio.