Restringir 'esperar' apenas à interação stdin / stdout

3

Eu preciso aceitar arquivos de trabalho dos usuários, que consistem essencialmente em interação do console com um processo que eu vou executar para eles. Naturalmente, a primeira ideia que me veio à mente é usar expect scripts como arquivos de trabalho:

spawn process
expect "ready"
send "process DATA"
set timeout 100
expect {
    "done" {send_user "success"}
    timeout {send_user "failure"}
}

No entanto, como gostaria de aceitar trabalhos automaticamente, quero impedir que os usuários façam algo estúpido ou perigoso, como gerar 10% dos processossysbench ou escrever arquivos aleatórios no disco ou tentar ler /etc/passwd . Eu quero restringi-los às interações STDIN / STDOUT com o processo que eu gero para eles.

Como eu faria isso? Até agora meus pensamentos são:

  • escreva meu próprio "espere lite". Parece viável, mas tolo e demorado.
  • limpar os arquivos de trabalho expect . Soa complexo e propenso a erros.
  • invente meu próprio idioma seguro e traduza-o para expect . É viável, mas vou ter que fornecer documentação e tutoriais para que os usuários possam aprender.
  • restringir o processo de trabalho com cota e permissões. Não é realmente uma opção, já que eu quero que meu process use uma quantidade razoável de tempo de CPU e crie arquivos tmp (o que estou certo de que irá limpar).
  • dê aos usuários acesso interativo a process . Não é uma opção, já que os trabalhos podem ter que ficar em uma fila por algum tempo.

Há algo óbvio que está faltando, como o parâmetro de configuração expect , que restringe os scripts ou uma ferramenta semelhante que eu poderia usar?

    
por Dmitry Grigoryev 12.01.2017 / 11:45

1 resposta

1

Os intérpretes seguros do TCL funcionam com expect . Para ilustrar, criei dois scripts: unsafe.exp representando o arquivo enviado pelo usuário e safe.exp , que usa um intérprete seguro para executar unsafe.exp . Aqui está o código de unsafe.exp :

#!/usr/bin/expect
spawn whoami
expect {
    "user" { send_user "safe success\n" }
    "root" { send_user "unsafe success\n" }
}

A execução de unsafe.exp como root resulta em

# expect unsafe.exp
spawn whoami
root
unsafe success

Agora, safe.exp impedirá que o usuário use comandos perigosos, como spawn , enquanto ainda fornece acesso a recursos essenciais, como send e expect . Aqui está o código:

#!/usr/bin/expect

# create a safe interpreter
interp create -safe untrusted

# provide it with essetial expect functions
interp alias untrusted send_user {} send_user
interp alias untrusted send {} send
interp alias untrusted expect {} expect
interp alias untrusted interact {} interact

# censor the "spawn" function
# not providing it would be just as safe, but scripts using it would fail
proc safe_spawn {args} {
    puts "censored spawn"
}
interp alias untrusted spawn {} safe_spawn

# create a safe process to interact with
spawn sudo -u user whoami

# run unsafe.exp
untrusted invokehidden source unsafe.exp

Executando safe.exp como resultado raiz em

# expect safe.exp
spawn sudo -u user whoami
censored spawn
user
safe success

Espero que isso ajude alguém. Comentários sobre possíveis problemas de segurança com esta abordagem são bem-vindos.

    
por 16.01.2017 / 10:26