Programação Por Equipe DevBras

Capa do artigo: Falha crítica no Rails Active Storage: como corrigir

Falha crítica no Rails Active Storage: como corrigir

Falha crítica no Active Storage com ImageMagick deixa gravar e ler arquivos sem login. Veja se seu app Rails está afetado e como atualizar e se proteger.

A equipe do Rails publicou nesta quarta-feira (04/11/2026) as versões 8.1.4.1 e 8.0.5.2 com 21 correções de segurança. A mais grave está no Active Storage: num app que processa anexos com ImageMagick, um atacante sem login pode gravar arquivos no servidor só enviando um arquivo preparado. Se os anexos ficam no Disk service, ele também pode ler qualquer arquivo que o processo do app lê, como o secret_key_base e as credenciais de outros sistemas. Segundo o aviso oficial (GHSA-f3w6-w445-fwh9), isso pode virar execução remota de código ou acesso a outros sistemas.

A Rails classifica a falha como crítica, CVSS 9.8. Ela ainda não tem CVE. Se você cuida de algum app Rails que aceita upload de usuários, confira hoje. Abaixo estão como saber se o app está afetado, o passo a passo pra atualizar (Bundler, Docker e Kamal), a mitigação temporária no policy.xml do ImageMagick e o que fazer depois.

O que é a falha do Active Storage com ImageMagick

O ImageMagick escolhe o formato de leitura (o coder) pelo conteúdo do arquivo, não pela extensão. Alguns coders não trabalham só com a imagem: eles agem sobre outros arquivos citados dentro dela. O Active Storage não restringia nenhum desses coders, então o único limite era a policy de segurança do ImageMagick instalada no servidor.

O detalhe que deixa a falha séria: o analyzer do ImageMagick roda quando o arquivo é anexado. Segundo o aviso, basta anexar o upload. O app não precisa gerar variant, preview nem chamar analyze.

O commit da correção descreve a cadeia reportada: um SVG enviado chegava ao coder MSL pelo analyzer, e o MSL lê e grava os arquivos que o script dele indica. A Rails avisa que essa foi a cadeia reportada, mas que não assume que seja a única. O aviso não diz se a falha já está sendo explorada.

As outras correções dos mesmos releases

O anúncio do Rails 8.0.5.2 e 8.1.4.1 lista 21 falhas. Entre elas, outra no Active Storage, GHSA-v924-7rp8-4mxh (alta), com possível leitura de arquivos e execução de código em previews de vídeo, análise e processamento de imagem, além de um bypass de Strong Parameters, XSS em helpers do Action View e problemas de sessão. Mais um motivo pra atualizar em vez de só aplicar a mitigação.

Como saber se o seu app Rails está afetado

Pelo aviso oficial, o app está afetado se cumprir as três condições:

  1. Usa ImageMagick no Active Storage: config.active_storage.variant_processor = :mini_magick. Esse é o padrão pra apps em load_defaults 6.1 ou anterior. A partir do load_defaults 7.0, o padrão é :vips. Essa config também decide qual biblioteca analisa os uploads, não só quem gera as variantes.
  2. A policy do ImageMagick não bloqueia os coders envolvidos. Segundo a Rails, as policies empacotadas pelo Debian e pelo Ubuntu não bloqueiam.
  3. Aceita upload de usuários não confiáveis: cadastro aberto com avatar, anexos de clientes, formulários públicos.

Versões afetadas e corrigidas

  • activestorage 8.1.0 até 8.1.4: atualize pra 8.1.4.1.
  • activestorage abaixo de 8.0.5.2: atualize pra 8.0.5.2 (ou direto pra 8.1.4.1).
  • Rails 7.x e anteriores: não recebem correção. As séries antigas não têm mais suporte. Use a mitigação abaixo e planeje o upgrade pra 8.0 ou mais nova.

Atenção: o suporte de segurança da série 8.0 termina em 7 de novembro de 2026. Se for sair de uma versão antiga, mire na 8.1.

Os comandos pra conferir

Rode no mesmo lugar onde o app roda (no servidor ou dentro do container, por exemplo com docker compose exec app bash):

# 1. Processador efetivo (:mini_magick = risco; :vips = fora desta falha)
bin/rails runner 'p ActiveStorage.variant_processor'
grep -rnE 'variant_processor|load_defaults' config/

# 2. Versões das gems
bundle info activestorage
bundle list | grep -E 'activestorage|mini_magick'

# 3. Policy do ImageMagick
magick -list policy     # ImageMagick 7
convert -list policy    # ImageMagick 6

Na saída de -list policy, procure regras com rights: None pra MSL, pro delegate gs e pros coders do Ghostscript (PS, EPS, PDF etc.). Se elas não aparecem, a condição 2 vale pro seu servidor.

Passo a passo: como atualizar o Rails

1. Atualize as gems

bundle update rails mini_magick
bundle info activestorage   # precisa mostrar 8.1.4.1 ou 8.0.5.2
bundle info mini_magick     # precisa ser 5.1 ou maior

Se o Gemfile fixa a versão exata do Rails, troque antes, por exemplo gem "rails", "8.1.4.1" (ou "8.0.5.2"). Se o app usa :mini_magick, a correção exige mini_magick 5.1 ou mais nova. Com uma versão antiga, o app levanta uma exceção no boot. Se o seu Gemfile trava o mini_magick na série 4, libere com gem "mini_magick", ">= 5.1" e rode os testes, porque a série 5 mudou algumas APIs.

Prefere não atualizar o Rails inteiro agora? A Rails publicou os patches avulsos: 468aa9a pra 8.1 e ea8c401 pra 8.0. Mas os mesmos releases corrigem outras 20 falhas, então o caminho recomendado é a versão nova.

2. Docker e Kamal: rebuild e redeploy

Atualizar o Gemfile.lock não muda nada no container que já está rodando. Gere a imagem de novo e suba:

docker compose build --pull app
docker compose up -d

# com Kamal
kamal deploy

O --pull baixa a imagem base mais recente, o que também traz atualizações do ImageMagick do sistema. Se você administra vários containers por um painel (veja nosso comparativo de painéis Docker), confira que todos os serviços do app foram recriados com a imagem nova.

3. Reinicie o app e os workers

Reinicie o servidor web (Puma) e os workers (Sidekiq, Solid Queue, GoodJob…). A análise de um anexo pode rodar em background, no ActiveStorage::AnalyzeJob, então um worker com a versão velha continua vulnerável.

4. Confirme que a policy nova está valendo

A versão corrigida traz um policy.xml próprio e o aplica a todo processo do ImageMagick que o MiniMagick abre, pela variável MAGICK_CONFIGURE_PATH. Como ela é passada pelo MiniMagick, e não pelo shell, o guia do Active Storage manda conferir assim:

bin/rails runner 'puts MiniMagick.identify { |i| i.list "policy" }'

Casos em que a policy da Rails não chega ao app e você precisa colocar as regras na policy do sistema (próxima seção):

  • o app troca o MiniMagick.cli_env depois do boot, limpa o ambiente com MiniMagick.cli_prefix ou instala o próprio MiniMagick::Shell;
  • o app usa GraphicsMagick, que não lê as policies do ImageMagick.

Dois efeitos colaterais: se o app gera ou converte PDF ou PostScript pelo ImageMagick, isso para de funcionar até você liberar de novo o delegate gs e os coders que usa no policy.xml do sistema. E uma regra do sistema que libera um coder, inclusive um curinga como pattern="*", vence o bloqueio da Rails. Libere só o que usa:

<policy domain="delegate" rights="execute" pattern="gs"/>
<policy domain="coder" rights="read|write" pattern="PDF"/>

Não dá pra atualizar agora? Mitigação temporária no policy.xml

O workaround oficial é copiar as regras da policy que a Rails publicou, activestorage/lib/active_storage/image_magick/policy.xml, pra policy do ImageMagick do sistema. Vale também pra quem está no Rails 7.x ou anterior, que não vai receber correção.

1. Ache o arquivo

magick -list policy | grep Path    # ImageMagick 7
convert -list policy | grep Path   # ImageMagick 6

Exemplos: /etc/ImageMagick-7/policy.xml (ImageMagick 7) e /etc/ImageMagick-6/policy.xml (pacote do ImageMagick 6 no Debian e no Ubuntu).

2. Cole as regras antes de </policymap>

O mínimo pedido no aviso é negar o coder MSL, o delegate gs e os coders do Ghostscript:

<policy domain="coder" rights="none" pattern="MSL"/>
<policy domain="delegate" rights="none" pattern="gs"/>
<policy domain="coder" rights="none" pattern="{PS,PS2,PS3,EPS,EPS2,EPS3,EPI,EPSF,EPSI,EPT,EPT2,EPT3,PDF,AI,EPDF,PDFA,POCKETMOD,XPS,PCL}"/>

Melhor ainda é copiar todas as regras do arquivo da Rails. Além das acima, ele nega EPHEMERAL, TEXT, MPC, SHOW, WIN, PLT, URL, HTTP, HTTPS, FTP, FILE e a indireção @arquivo (<policy domain="path" rights="none" pattern="@*"/>). O próprio arquivo avisa: não use crase (`) em nenhum lugar do policy.xml, porque o ImageMagick descarta regras em silêncio a partir dela.

3. Confira

convert -list policy | grep -iE -B1 'msl|gs|pdf'   # ou magick -list policy

O ImageMagick lê a policy a cada processo novo. Mesmo assim, reinicie o app e os workers pra não sobrar nenhum processo antigo. No Docker, a mudança tem que ir pro Dockerfile (por exemplo, com COPY de um policy.xml revisado por cima do arquivo do sistema), seguida de rebuild e redeploy. Se você só editar dentro do container, a mudança some no próximo deploy.

O que checar depois de corrigir

1. Usa o Disk service? Troque todos os segredos

Veja em config/storage.yml se o serviço configurado em config.active_storage.service (em config/environments/production.rb) tem service: Disk. Se tem, o aviso manda trocar o secret_key_base e todo segredo que o processo do app consegue ler:

  • o secret_key_base e a master key (config/master.key ou RAILS_MASTER_KEY);
  • tudo o que está no config/credentials.yml.enc (e nos arquivos por ambiente, como config/credentials/production.yml.enc);
  • senhas e chaves de banco de dados e de storage;
  • tokens de terceiros (pagamento, e-mail, APIs).

E não mantenha o segredo antigo como fallback. Um jeito de trocar a master key e as credenciais:

# gera um secret_key_base novo
bin/rails secret

# anota os valores atuais, recria o arquivo com uma master key nova
bin/rails credentials:show > /tmp/credenciais-antigas.yml
mv config/credentials.yml.enc config/credentials.yml.enc.antigo
mv config/master.key config/master.key.antigo
EDITOR=nano bin/rails credentials:edit   # cria master.key nova; cole os valores NOVOS
shred -u /tmp/credenciais-antigas.yml

Depois, atualize a RAILS_MASTER_KEY onde ela estiver configurada (segredos do Kamal, variáveis do servidor ou do CI) e troque, nos próprios provedores, cada senha e token que estava no arquivo. Trocar o secret_key_base derruba as sessões (os usuários vão precisar entrar de novo) e invalida cookies assinados e links assinados antigos. Se o app usa Active Record Encryption, as chaves dele também estão nas credenciais: siga a seção de rotação de chaves do guia de Active Record Encryption antes de descartar a chave antiga, ou os dados já cifrados ficam ilegíveis. Já passamos por rotação de segredos em outros incidentes: veja o passo a passo do vazamento de variáveis de ambiente do Trigger.dev.

2. Procure SVGs e arquivos estranhos

O aviso não traz indicadores de ataque. As sugestões abaixo são nossas, a partir da cadeia descrita no commit (SVG chegando ao coder MSL):

# uploads de SVG nos logs
grep -iE '\.svg|image/svg' log/production.log*

# blobs SVG no banco
bin/rails runner 'puts ActiveStorage::Blob
    .where(content_type: "image/svg+xml")
    .or(ActiveStorage::Blob.where("LOWER(filename) LIKE ?", "%.svg"))
    .pluck(:id, :filename, :created_at)'

# arquivos alterados nos últimos 30 dias fora de storage/, tmp/, log/ e .git/
find . -xdev -type f -mtime -30 \
    -not -path './storage/*' -not -path './tmp/*' \
    -not -path './log/*' -not -path './.git/*'

O ImageMagick escolhe o coder pelo conteúdo, então um arquivo malicioso pode ter outra extensão e outro content type. Por isso, além dos SVGs, olhe arquivos novos em pastas que o usuário do app consegue gravar (o diretório do app, public/, config/, bin/, o ~/.ssh do usuário). Achou algo que não reconhece? Trate como incidente: tire o app do ar se preciso, preserve os logs, troque todos os segredos e reconstrua o servidor ou a imagem a partir de uma fonte limpa.

Perguntas frequentes

Meu app usa :vips. Estou seguro?

Desta falha, sim: ela exige o ImageMagick (:mini_magick). Mas atualize mesmo assim. Os mesmos releases corrigem outras falhas no Active Storage, e em julho a Rails já tinha corrigido uma falha crítica que afetava justamente apps com libvips.

A falha tem CVE?

Ainda não. Ela é identificada como GHSA-f3w6-w445-fwh9, com CVSS 9.8 (crítica) segundo a Rails.

Estou no Rails 7.1. Vai sair correção?

Não. O aviso só lista correções pra 8.0 e 8.1, e as séries antigas não têm mais suporte. Aplique a mitigação no policy.xml agora e planeje o upgrade pra 8.1.

Uso S3 em vez do Disk service. Preciso trocar os segredos?

O aviso só manda trocar os segredos quando os anexos ficam no Disk service, porque é nesse caso que dá pra ler arquivos do servidor. A gravação de arquivos arbitrários vale pra qualquer app afetado, então faça a checagem de arquivos estranhos do mesmo jeito.

Resumo

  • Falha crítica (CVSS 9.8) no Active Storage com ImageMagick: atacante sem login grava arquivos no servidor e, com o Disk service, lê os segredos do app.
  • Afeta quem usa :mini_magick, tem a policy padrão do ImageMagick (como a do Debian/Ubuntu) e aceita uploads de qualquer um.
  • Corrigida no Rails 8.1.4.1 e 8.0.5.2, lançados em 04/11/2026; exige mini_magick 5.1 ou mais nova.
  • Docker e Kamal: rebuild, redeploy e reinício do app e dos workers.
  • Sem upgrade (ou no Rails 7.x)? Copie as regras do policy.xml da Rails pra policy do sistema.
  • Usa Disk service? Troque secret_key_base, master key, credenciais e tokens, sem fallback.

Fontes: aviso GHSA-f3w6-w445-fwh9, anúncio do Rails 8.0.5.2 e 8.1.4.1, CHANGELOG do Active Storage, guia do Active Storage (seção ImageMagick Security Policy), versões no RubyGems, política de manutenção do Rails e The Hacker News.

Avalie este artigo