flawopen.com/Ruby YAML/Ruby YAML
YAML.load é seguro para entradas não confiáveis?
Confira a versão do Psych realmente carregada pela aplicação: Psych 4, incluído no Ruby 3.1, mudou YAML.load para usar desserialização segura por padrão. Versões anteriores do Psych construíam objetos sem essa restrição; o Psych também pode ser atualizado independentemente do Ruby. YAML.unsafe_load e Marshal.load desserializam objetos Ruby e nunca devem receber entrada não confiável.
# Psych < 4: YAML.load used unsafe # object construction by default. YAML.load(params[:config]) # Every Psych version: explicitly unsafe. YAML.unsafe_load(user_input) Psych.unsafe_load(user_input) # Marshal has no restricted safe-load API. Marshal.load(cookie_value)
# Explicit restricted types; keep this list minimal. require "yaml" require "date" data = YAML.safe_load( input, permitted_classes: [Date], permitted_symbols: [], aliases: false ) # For ordinary external data, prefer JSON and # validate its shape, values, and input size. data = JSON.parse(input)
Por que YAML pode ser perigoso
YAML tem tags que o Psych pode mapear para objetos Ruby. Com carregamento inseguro, um documento com tags pode solicitar a criação de uma classe e fornecer valores para seu estado serializado; o impacto depende das classes disponíveis e do comportamento delas. Esse é o princípio de cadeias gadget de desserialização. Use carregamento seguro para YAML não confiável e valide os dados resultantes separadamente. O risco amplo também existe em Python pickle, PHP unserialize e Marshal.load no Ruby.
Aplicações Rails e outras podem carregar muitas dependências, aumentando o conjunto de classes e comportamentos disponíveis para uma cadeia de desserialização insegura. Isso depende da implantação; não é uma propriedade de todo app Rails nem de qualquer documento YAML.
Por que a mudança de versão gerou confusão
Psych 4 mudou YAML.load para usar carregamento seguro por padrão e introduziu unsafe_load para o comportamento anterior, que construía objetos. O Ruby 3.1 incluiu Psych 4, mas aplicações podem selecionar outra versão da gem Psych; audite a dependência resolvida e o runtime, não apenas a versão do Ruby. Como o carregamento seguro pode rejeitar classes específicas da aplicação ou aliases, migre com uma lista de permissões explícita e mínima, em vez de trocar para unsafe_load.
Se uma atualização levar à introdução de unsafe_load, trate a chamada como um achado quando a entrada puder ser influenciada fora da fronteira de implantação confiável. Prefira safe_load com a menor lista necessária de permitted_classes; não a amplie apenas para ignorar erros de compatibilidade.
FAQ
YAML.safe_load é completamente seguro?
E se eu carregar meus próprios arquivos de configuração?
Marshal pode ser aceitável?
Outro risco no Ruby: Marshal.load
Separado do YAML, a documentação do Ruby informa que Marshal.load pode reconstruir quase qualquer classe carregada no processo e levar à execução remota de código quando os dados não são confiáveis. Mantenha os dados Marshal dentro de uma fronteira confiável; nunca desserialize bytes fornecidos pelo usuário ou influenciados por um atacante.
Referências
- Ruby documentation — Psych (YAML)
- Psych 4.0 — Ruby 3.1 API documentation
- Ruby documentation — Marshal security considerations
- CVE-2024-35221 — YAML alias denial of service in RubyGems metadata
- CWE-502 — Deserialization of Untrusted Data
- Is Python's pickle safe for untrusted data?
- Is PHP's unserialize() safe on user input?
- Documentação do Ruby — aviso de segurança sobre Marshal.load