Passar uma senha na linha de comando (para um processo filho iniciado no meu programa) é conhecido por não ser seguro (porque pode ser visto até por outros usuários com o comando ps). É possível passar isso como uma variável de ambiente?
O que mais posso usar para passar isso? (Exceto a variável de ambiente), a solução mais fácil parece usar um canal, mas essa solução mais fácil não é fácil.
Eu programa em Perl.
environment-variables
fork
ipc
Porton
fonte
fonte
Respostas:
Os argumentos do processo são visíveis para todos os usuários, mas o ambiente é visível apenas para o mesmo usuário ( pelo menos no Linux , e acho que em todas as variantes modernas do unix). Portanto, passar uma senha por uma variável de ambiente é seguro. Se alguém puder ler suas variáveis de ambiente, ele poderá executar processos como você, então já acabou o jogo.
O conteúdo do ambiente corre algum risco de vazar indiretamente, por exemplo, se você correr
ps
para investigar algo e colar e copiar acidentalmente o resultado, incluindo variáveis de ambiente confidenciais em um local público. Outro risco é que você passa a variável de ambiente para um programa que não precisa dela (incluindo filhos do processo que precisa da senha) e esse programa expõe suas variáveis de ambiente porque não espera que sejam confidenciais. A gravidade desses riscos de vazamento secundário depende de qual é o processo com a senha (por quanto tempo é executado? Executa subprocessos?).É mais fácil garantir que a senha não vaze acidentalmente, passando-a por um canal que não foi projetado para ser espionado, como um cano. Isso é muito fácil de fazer no lado de envio. Por exemplo, se você tiver a senha em uma variável do shell, poderá fazer
se
theprogram
espera a senha em sua entrada padrão. Observe que isso é seguro porqueecho
é um builtin; não seria seguro com um comando externo, pois o argumento seria exposto naps
saída. Outra maneira de obter o mesmo efeito é com um documento aqui:Alguns programas que exigem uma senha podem ser instruídos para lê-la em um descritor de arquivo específico. Você pode usar um descritor de arquivo diferente da entrada padrão se precisar de entrada padrão para outra coisa. Por exemplo, com
gpg
:Se o programa não pode ser instruído a ler a partir de um descritor de arquivo, mas pode ser instruído a ler a partir de um arquivo, você pode instruí-lo a ler a partir de um descritor de arquivo usando um nome de arquivo como `/ dev / fd / 3.
No ksh, bash ou zsh, você pode fazer isso de forma mais concisa através da substituição do processo.
fonte
/usr/ucb/ps
setuid root era capaz de ler e exibir variáveis de ambiente de outros processos - isso foi removido no Solaris 10; portanto, a resposta "todas as outras variantes modernas do Unix" acima se aplica às versões Solaris a partir de 2005 e posteriores.Em vez de passar a senha diretamente através de um argumento ou variável de ambiente
use o mesmo argumento ou variável de ambiente para passar um nome de arquivo :
Então você pode passar tanto um arquivo regular protegido por permissão (embora isso não vai protegê-lo de outros processos em execução sob o mesmo usuário), ou
/dev/stdin
e tubulação -lo em (que AFAIK irá protegê-lo de outros processos em execução sob o mesmo usuário):Se você usa
/dev/stdin
aqui, é imperativo que seja um cano . Se for um terminal, será legível por outros processos em execução no mesmo usuário.Se você já precisar usar o seu
/dev/stdin
para outra coisa, poderá usar a substituição de processo se estiver em um shell que o suporte, o que é essencialmente equivalente ao uso de pipes:Os pipes nomeados (FIFOs) podem parecer iguais, mas são interceptáveis.
Essas soluções também não são perfeitamente seguras , mas podem estar próximas o suficiente, desde que você não esteja em um sistema com restrição de memória que troque muito.
Idealmente, você deve ler esses arquivos (pipe também é um arquivo) na memória marcada com mlock (2) como não trocável, que é o que geralmente fazem os programas de manipulação de senhas, como o gnupg.
Notas:
Passar números de filedescriptor é, teoricamente, tão bom quanto arquivo como passar nomes de arquivos, mas os nomes de arquivos são mais práticos, porque
<()
fornece um nome de arquivo, não um número de filedescriptor (coproc
es fornecem os descritores de arquivo marcados como FD_CLOEXEC , o que torna esses descritores de arquivo inutilizáveis nesse contexto).Se você estiver em um sistema Linux
/proc/sys/kernel/yama/ptrace_scope
definido como0
AFAIK, não há maneira de se proteger de outros processos em execução no mesmo usuário (eles podem usar o ptrace para se conectar ao seu processo e ler sua memória)Se você apenas precisar manter sua senha longe de processos em execução sob usuários diferentes (não raiz), argumentos, variáveis de ambiente, canais e arquivos protegidos por permissão serão suficientes.
fonte
Não, as variáveis de ambiente também são facilmente lidas e vazam para os processos filhos. passe-o usando um cano.
fonte
ps
e/proc
pode vê-lo.ptrace()
atingir o alvo e ler sua memória de qualquer maneira.Se nada mais servir, considere o serviço de Retenção de Chave do Linux (chaveiros do kernel).
Comece em: security / keys.txt . Um dos chaveiros padrão pode ser clonado entre os processos pai e filho.
Não é a solução mais simples, mas está lá e parece ser mantida e usada (também foi implicada em um bug do Android no ano passado).
Eu não sei sobre seu status "político", mas tinha uma necessidade semelhante e comecei a trabalhar em uma ligação do Guile. Não encontrei suporte Perl pré-existente.
fonte