O sandbox do Python é difícil . Python é inerentemente introspectável, em vários níveis.
Isso também significa que você pode encontrar os métodos de fábrica para tipos específicos desses tipos e construir novos objetos de baixo nível, que serão executados diretamente pelo intérprete, sem limitação.
Aqui estão alguns exemplos de como encontrar maneiras criativas de sair das caixas de proteção do Python:
A idéia básica é sempre encontrar uma maneira de criar tipos básicos de Python; funções e classes e quebre o shell fazendo com que o interpretador Python execute bytecode arbitrário (não verificado!).
O mesmo e mais se aplicam à exec
instrução ( exec()
função no Python 3).
Então, você quer:
Controle estritamente a compilação de bytes do código Python ou, pelo menos, pós-processe o bytecode para remover qualquer acesso aos nomes que começam com sublinhados.
Isso requer conhecimento profundo de como o interpretador Python funciona e como o bytecode do Python está estruturado. Objetos de código estão aninhados; o bytecode de um módulo cobre apenas o nível superior de instruções, cada função e classe consiste em sua própria sequência de bytecode mais metadados, contendo outros objetos de bytecode para funções e classes aninhadas, por exemplo.
Você precisa colocar os módulos na lista de permissões que podem ser usados. Cuidadosamente.
Um módulo python contém referências a outros módulos. Se você importar os
, existe um nome local os
no namespace do módulo que se refere ao os
módulo. Isso pode levar um invasor determinado a módulos que podem ajudá-lo a sair da área restrita. O pickle
módulo, por exemplo, permite carregar objetos de código arbitrários, por exemplo, portanto, se algum caminho através dos módulos na lista de permissões levar ao pickle
módulo, você ainda terá um problema.
Você precisa limitar estritamente as cotas de tempo. Mesmo o código mais neutralizado ainda pode tentar executar para sempre, amarrando seus recursos.
Dê uma olhada no RestrictedPython , que tenta fornecer o controle estrito do bytecode. RestrictedPython
transforma o código Python em algo que permite controlar quais nomes, módulos e objetos são permitidos no Python 2.3 até 2.7.
Se RestrictedPython
for suficientemente seguro para seus propósitos, depende das políticas que você implementa. Não permitir o acesso a nomes começando com um sublinhado e estritamente na lista de permissões dos módulos seria um começo.
Na minha opinião, a única opção verdadeiramente robusta é usar uma máquina virtual separada, uma que não tenha acesso à rede para o mundo externo que você destrói após cada execução. Cada novo script recebe uma nova VM. Dessa forma, mesmo que o código consiga sair da sua caixa de proteção do Python (o que não é improvável), tudo o que o invasor obtém acesso é de curta duração e sem valor.