Pular para o conteúdo

Incidente · Pleno

ChatGPT 20/03/2023: bug no redis-py expõe dados de outros usuários

Incidente real. Pontos centrais: corrupção de pool em requisição cancelada e checagem de dono do dado.

12 min de leitura · Incidente em 2023-03-20, durou · Fonte: OpenAI · Conteúdo revisado em 23 de outubro de 2026

Resposta curta

Incidente real. Pontos centrais: corrupção de pool em requisição cancelada e checagem de dono do dado. A OpenAI tirou o ChatGPT do ar por causa de um bug numa biblioteca de código aberto: alguns usuários viam títulos do histórico de outro usuário ativo. O problema veio à tona em 20 de março de 2023.

01 · CONTEXTO

Um cache de dados de usuário compartilhado por todos

A OpenAI tirou o ChatGPT do ar por causa de um bug numa biblioteca de código aberto: alguns usuários viam títulos do histórico de outro usuário ativo. O problema veio à tona em 20 de março de 2023. Também era possível que a primeira mensagem de uma conversa recém-criada aparecesse no histórico de outra pessoa, se as duas estivessem ativas na mesma época.

O servidor usa o Redis como cache de informações de usuário, para não consultar o banco a cada requisição, e o Redis Cluster para distribuir a carga por várias instâncias. O servidor é em Python, roda com Asyncio e fala com o Redis pela biblioteca redis-py.

  1. O usuário envia a requisição ao servidor da aplicação.

    Diagrama da arquitetura: Cache de dados de usuário com Redis Cluster
    CLUsuário
    CPServidor da aplicação
    CHRedis Cluster
    DBBanco de dados
  2. O servidor consulta o cache com as informações do usuário.

    Diagrama da arquitetura: Cache de dados de usuário com Redis Cluster
    CLUsuário
    CPServidor da aplicação
    CHRedis Cluster
    DBBanco de dados
  3. O cache é um Redis Cluster, que distribui a carga por várias instâncias.

    Diagrama da arquitetura: Cache de dados de usuário com Redis Cluster
    CLUsuário
    CPServidor da aplicação
    CHRedis Clustercluster
    DBBanco de dados
  4. Com o cache, o servidor evita consultar o banco a cada requisição.

    Diagrama da arquitetura: Cache de dados de usuário com Redis Cluster
    CLUsuário
    CPServidor da aplicação
    CHRedis Cluster
    DBBanco de dados

02 · O BUG

Uma conexão reaproveitada com dados de outra requisição

A biblioteca mantém um pool de conexões compartilhado entre o servidor e o cluster e reaproveita cada conexão em outra requisição quando a anterior termina. Com Asyncio, requisição e resposta se comportam como duas filas: quem chama coloca a requisição na fila de entrada, retira a resposta da fila de saída e só então devolve a conexão ao pool.

  1. O servidor coloca a requisição de A na fila de entrada de uma conexão do pool e depois lerá a resposta na fila de saída.

    Diagrama da arquitetura: Conexão compartilhada corrompida por cancelamento
    CLUsuário A
    CLUsuário B
    CPServidor assíncrono
    CHRedis Cluster
  2. A requisição de A é cancelada depois de entrar na fila de entrada e antes de a resposta sair da fila de saída, e a conexão fica corrompida.

    Diagrama da arquitetura: Conexão compartilhada corrompida por cancelamento
    CLUsuário A
    CLUsuário B
    CPServidor assíncronoconexão corrompida
    CHRedis Cluster
  3. Uma requisição sem relação, a de B, reaproveita a conexão do pool e a próxima resposta pode trazer dados deixados nela.

    Diagrama da arquitetura: Conexão compartilhada corrompida por cancelamento
    CLUsuário A
    CLUsuário B
    CPServidor assíncrono
    CHRedis Cluster
  4. Na maioria dos casos o dado deixado não é do tipo esperado e o resultado é um erro de servidor, que o usuário resolve tentando de novo.

    Diagrama da arquitetura: Conexão compartilhada corrompida por cancelamento
    CLUsuário A
    CLUsuário B
    CPServidor assíncrono
    CHRedis Cluster
  5. Em alguns casos o dado tem o tipo esperado, parece válido e é entregue a B mesmo pertencendo a outro usuário.

    Diagrama da arquitetura: Conexão compartilhada corrompida por cancelamento
    CLUsuário A
    CLUsuário Bdado de outro usuário
    CPServidor assíncrono
    CHRedis Cluster

O ponto frágil é o cancelamento: se a requisição é cancelada depois de entrar na fila de entrada e antes de a resposta sair da fila de saída, a conexão se corrompe e a próxima resposta, de uma requisição sem relação, pode receber dados deixados nela. A cobertura do The Hacker News descreve o mesmo mecanismo: requisições canceladas podiam corromper conexões e devolver dados inesperados do cache.

SituaçãoResultado
Dado deixado na conexão não tem o tipo esperado (maioria dos casos)Erro de servidor sem recuperação; o usuário precisa tentar de novo
Dado deixado na conexão tem o tipo esperado (alguns casos)O que volta do cache parece válido, mesmo pertencendo a outro usuário

03 · GATILHO E ALCANCE

Uma mudança no servidor e o que ficou visível

Às 1h, horário do Pacífico, da segunda-feira 20 de março, a OpenAI introduziu sem querer uma mudança no servidor que causou um pico de cancelamentos de requisições ao Redis. Isso criou uma pequena probabilidade de cada conexão devolver dado errado. O bug só aparecia no cliente Asyncio do redis-py para Redis Cluster, e já foi corrigido.

A investigação mostrou que o mesmo bug pode ter exposto informações de pagamento de 1,2% dos assinantes do ChatGPT Plus ativos numa janela de nove horas. A OpenAI afirma que números completos de cartão não foram expostos em nenhum momento.

OndeO que podia aparecer
Histórico de conversasTítulos de conversas de outro usuário ativo
Histórico após criar uma conversaA primeira mensagem de uma conversa recém-criada, se ambos estivessem ativos na mesma época
E-mail de confirmação de assinaturaAlguns e-mails da janela foram enviados aos usuários errados
Gerenciar assinaturaNome, e-mail, endereço de pagamento, tipo e final do cartão e validade de outro assinante ativo

04 · A RESPOSTA

Corrigir a biblioteca e checar o dono do dado

Ao identificar o bug, a OpenAI procurou os mantenedores do Redis com um patch. Entre as ações para melhorar os sistemas, adicionou checagens redundantes para garantir que o dado devolvido pelo cache corresponda ao usuário que pediu; a cobertura do The Hacker News registra a mesma medida.

Também examinou os logs por programa para garantir que as mensagens só ficassem disponíveis ao usuário correto, correlacionou várias fontes de dados para identificar os afetados e notificá-los, melhorou o logging para confirmar que o problema parou e melhorou a robustez e a escala do cluster Redis para reduzir erros de conexão sob carga extrema.

  1. O servidor pede o dado de usuário ao cache.

    Diagrama da arquitetura: Cache com checagem do dono do dado
    CLUsuário
    CPServidor da aplicação
    CHRedis Cluster
    NWLogs e monitoramento
  2. Antes de usar o que veio do cache, uma checagem redundante confere se o dado corresponde ao usuário que pediu.

    Diagrama da arquitetura: Cache com checagem do dono do dado
    CLUsuário
    CPServidor da aplicaçãocheca o dono
    CHRedis Cluster
    NWLogs e monitoramento
  3. Logging melhor ajuda a identificar quando o problema ocorre e a confirmar que ele parou.

    Diagrama da arquitetura: Cache com checagem do dono do dado
    CLUsuário
    CPServidor da aplicação
    CHRedis Cluster
    NWLogs e monitoramentomais visibilidade
  4. O cluster Redis ficou mais robusto e escalável para reduzir erros de conexão sob carga extrema.

    Diagrama da arquitetura: Cache com checagem do dono do dado
    CLUsuário
    CPServidor da aplicação
    CHRedis Clustermais robusto
    NWLogs e monitoramento

05 · LIÇÕES

Perguntas para o seu desenho

O caso sugere perguntas para o seu cache de dados de usuário. Cada valor lido carrega uma identificação de dono que o servidor confere antes de usar? O que acontece com uma conexão compartilhada quando uma requisição é cancelada no meio? Existe monitoramento que avise quando o dado devolvido não bate com quem pediu?

Perguntas frequentes

O que é ChatGPT 20/03/2023: bug no redis-py expõe dados de outros usuários?

Incidente real. Pontos centrais: corrupção de pool em requisição cancelada e checagem de dono do dado.

O que o design de ChatGPT 20/03/2023: bug no redis-py expõe dados de outros usuários cobre?

Ele está organizado nestas seções: Um cache de dados de usuário compartilhado por todos, Uma conexão reaproveitada com dados de outra requisição, Uma mudança no servidor e o que ficou visível, Corrigir a biblioteca e checar o dono do dado e Perguntas para o seu desenho.

Quanto tempo leva ChatGPT 20/03/2023: bug no redis-py expõe dados de outros usuários e qual é o nível?

Leva cerca de 12 minutos para ler e tem nível Pleno.

Agora projete você mesmo

Rode este caso como uma entrevista na escola de System Design: você toma as decisões, o tutor as questiona e você vê a nota do seu desenho.