
codejail v4.1.1
Execução segura de código
CodeJail
========
O CodeJail gerencia a execução de código não confiável em sandboxes seguros. Ele é projetado principalmente para execução de Python, mas também pode ser usado para outras linguagens.
A segurança é aplicada com AppArmor. Se o seu sistema operacional não suportar AppArmor, ou se o perfil do AppArmor não estiver definido e configurado corretamente, o CodeJail não protegerá a execução.
O CodeJail é projetado para ser configurável e se auto-configura para execução de Python se você o instalar corretamente.
Um sandbox do CodeJail consiste em várias partes:
#) Ambiente do sandbox. Para uma configuração Python, isso seria o Python e os pacotes principais associados como um virtualenv. Isso é indicado ao longo deste documento como . Ele é somente leitura e compartilhado entre as instâncias do sandbox.
O código em sandbox também tem acesso às bibliotecas do sistema operacional na medida em que o perfil do AppArmor permitir.
#) Diretório de execução do sandbox. Este é um diretório efêmero somente
leitura nomeado como /tmp/codejail-XXXXXXXX contendo o código enviado
(./jailed_code), arquivos adicionais opcionais e um diretório temporário
gravável (./tmp) que o código enviado pode usar como espaço de trabalho
temporário.
O código enviado é tipicamente o código submetido pelo estudante para ser
testado no servidor, e os arquivos adicionais são tipicamente um
python_lib.zip contendo bibliotecas de avaliação ou utilitárias.
Para executar, o CodeJail requer duas contas de usuário. Uma conta é a conta
principal sob a qual o código é executado, que tem acesso para criar sandboxes.
Ela será referida como <SANDBOX_CALLER>. A segunda conta é a conta sob a
qual o sandbox é executado. Esta é tipicamente a conta sandbox.
Versões Suportadas
Esta biblioteca atualmente é testada para funcionar com as seguintes versões
Python:
- 3.12
Ubuntu:
- 22.04
- 24.04
(Observe que a versão do Python usada dentro do sandbox pode ser diferente da versão usada para a própria biblioteca.)
Instalação
Estas instruções detalham como configurar seu sistema operacional para que o
CodeJail possa executar código Python com segurança. No entanto, também é
possível definir codejail.safe_exec.ALWAYS_BE_UNSAFE = True e executar o
Python enviado diretamente na máquina, sem nenhuma segurança. Isso pode ser
aceitável para máquinas de desenvolvedores que não se preocupam com segurança e
permite testar uma integração com a API do CodeJail. No entanto, não deve ser
usado se qualquer entrada vier de fontes não confiáveis. Não use esta opção
em sistemas de produção.
Para garantir a execução segura do Python, você criará um novo virtualenv. Isso significa que você terá dois: o virtualenv principal do seu projeto e o novo para o código Python em sandbox.
Escolha um local para o novo virtualenv e chame-o de . Ele será
detectado e usado automaticamente se você o colocar bem ao lado do seu
virtualenv existente, mas com -sandbox acrescentado. Então, se o seu
virtualenv existente estiver em /home/chris/ve/myproj, faça
ser /home/chris/ve/myproj-sandbox.
O usuário que executa o LMS é <SANDBOX_CALLER>, por exemplo, você na sua
máquina de desenvolvimento, ou www-data em um servidor.
Outros detalhes aqui que dependem da sua configuração:
-
Crie o novo virtualenv, usando
--copiespara que haja um executável Python distinto para limitar::$ sudo python3.12 -m venv --copies
Por padrão, o virtualenv apenas criaria um symlink para o Python do sistema, e a configuração padrão do apparmor em alguns sistemas operacionais pode impedir que o confinamento seja aplicado a ele.
-
(Opcional) Se você tiver pacotes específicos que deseja disponibilizar para o seu código em sandbox, instale-os ativando o virtual env do sandbox e usando o pip para instalá-los::
$ /bin/pip install -r requirements/sandbox.txt
-
Adicione um usuário de sandbox::
$ sudo addgroup sandbox $ sudo adduser --disabled-login sandbox --ingroup sandbox
-
Permita que o servidor web execute o Python em sandbox como o usuário sandbox. Crie o arquivo
/etc/sudoers.d/01-sandbox::$ sudo visudo -f /etc/sudoers.d/01-sandbox
<SANDBOX_CALLER> ALL=(sandbox) SETENV:NOPASSWD:/bin/python <SANDBOX_CALLER> ALL=(sandbox) SETENV:NOPASSWD:/usr/bin/find <SANDBOX_CALLER> ALL=(ALL) NOPASSWD:/usr/bin/pkill
(Observe que o binário
findpode executar código arbitrário, portanto este não é um arquivo sudoers seguro para fins não relacionados ao codejail.) -
Edite um perfil do AppArmor. Este é um arquivo de texto que especifica os limites do executável Python em sandbox. O arquivo deve estar em
/etc/apparmor.de deve ser nomeado com base no executável, com as barras substituídas por pontos. Por exemplo, se o seu Python em sandbox estiver em/home/chris/ve/myproj-sandbox/bin/python, então o seu perfil do AppArmor deve ser/etc/apparmor.d/home.chris.ve.myproj-sandbox.bin.python.Veja o perfil de exemplo em
apparmor-profiles/. O perfil deve ser personalizado para corresponder ao local do seu sandbox. -
Analise os perfis::
$ sudo apparmor_parser --replace --warn=all --warn=no-debug-cache --Werror <APPARMOR_FILE>
-
Reative novamente o virtualenv principal do seu projeto.
-
Desative o uso do PAM para definir rlimits::
sed -i '/pam_limits.so/d' /etc/pam.d/sudo
Usando o CodeJail
Se o seu CodeJail estiver configurado corretamente para usar safe_exec, tente estes comandos no seu terminal Python::
import codejail.jail_code
codejail.jail_code.configure('python', '<SANDENV>/bin/python', user='sandbox')
import codejail.safe_exec
jailed_globals = {}
codejail.safe_exec.safe_exec("output=open('/etc/passwd').read()", jailed_globals)
print(jailed_globals) # should be unreachable if codejail is working properly
Isso deve falhar com uma exceção.
Se você precisar alterar os pacotes instalados no virtualenv do seu sandbox, será necessário desabilitar o AppArmor, porque o seu Python em sandbox não tem os direitos de modificar os arquivos no diretório site-packages.
-
Desabilite o AppArmor para o seu sandbox::
$ sudo apt-get install apparmor-utils # if you haven't already $ sudo aa-complain /etc/apparmor.d/home.chris.ve.myproj-sandbox.bin.python
-
Instale ou altere os pacotes instalados::
$ pip install -r requirements/sandbox.txt
-
Reabilite o AppArmor para o seu sandbox::
$ sudo aa-enforce /etc/apparmor.d/home.chris.ve.myproj-sandbox.bin.python
Testes
Para executar os testes, você deve realizar as etapas de instalação padrão. Em seguida, você deve definir as seguintes variáveis de ambiente::
$ export CODEJAIL_TEST_USER=<owner of sandbox (usually 'sandbox')>
$ export CODEJAIL_TEST_VENV=<SANDENV>
Execute os testes com o Makefile::
$ make tests
Vários testes de proxy são ignorados se o modo proxy não estiver configurado.
Design
O CodeJail é suficientemente versátil para ser usado em uma variedade de projetos para executar código não confiável. Ele fornece duas camadas:
-
jail_code.pyoferece execução segura de subprocessos. Ele faz isso executando o programa em um subprocesso gerenciado pelo AppArmor. -
safe_exec.pyoferece tratamento especializado para execução de Python, usando jail_code para fornecer a semântica da instrução exec do Python.