Suponha que eu esteja revendo o código que os candidatos a emprego enviam para provar suas habilidades. Claramente, não quero executar executáveis que eles enviam. Não é tão claro que eu prefiro não executar o resultado da compilação do código (apenas, por exemplo, Java permite ocultar o código executável nos comentários ).
Que tal compilar seu código? Quero avisos do compilador, se houver, e se o código contiver algumas seqüências de caracteres inteligentes que exploram meu compilador e meu compilador comprometa minha máquina?
Quando pesquiso por "vulnerabilidades do compilador", as ocorrências são otimizações e emissão de código e se o código emitido é tão seguro quanto o código-fonte original.
Os compiladores normalmente são validados para garantir que não comprometam a máquina do usuário ao compilar algum trecho de código inteligente? Quão seguro é compilar um pedaço de código de um estranho?
fonte
Respostas:
Depende.
Esta parte do makefile pode excluir seu diretório inicial:
Portanto, se você precisar usar uma ferramenta (como o sistema cmake ou makefile), ela não será segura. Depende apenas de quão malicioso o codificador é.
Por outro lado, os compiladores são programados por pessoas, portanto, eles têm bugs. Portanto, talvez seja possível que alguém tenha encontrado uma maneira de executar código malicioso durante a compilação.
Conforme sugerido nos comentários, se você quiser ter certeza de que nada de engraçado está sendo feito em sua máquina, use uma máquina virtual.
fonte
Tenho certeza de que em algum lugar do ramo existem pessoas inteligentes que já criaram um hack para uma linguagem específica e uma versão do compilador. Meu lugar favorito para procurar algo assim provavelmente seria o concurso International Obfuscated C - (não sei se há algo comparável para Java). No entanto, na realidade, quão alto você considera o risco, assumiu que
o candidato causa uma impressão plausível em você, ele realmente quer o emprego na sua empresa (e não um processo)
o cara não sabe quanta revisão é feita na sua
ele / ela não sabe qual versão exata do compilador você está usando
ele / ela não sabe se você usa um ambiente virtual ou um compilador online, apenas por segurança
você não aceita programas grandes demais para serem efetivamente revisados
você não compila nada que lhe pareça suspeito
não há muitas pessoas no mundo que realmente sabem como realizar essa tarefa tecnicamente (e pesquisar no Google sozinho não fornecerá uma "referência rápida" ou um tutorial sobre isso, como você já descobriu por si mesmo).
Portanto, embora a compilação não seja "totalmente segura" em teoria, IMHO, na realidade, o risco é extremamente baixo de o seu "compilador ser pwned".
fonte
Temos que distinguir vários casos:
Makefile
, abuild.xml
, umconfigure
script de shell etc. Tecnicamente, isso não se deve à compilação do código do invasor, mas à configuração do ambiente de compilação.# 4 e # 5. resultará em uma negação de serviço. Na prática, os compiladores C ++ e Scala limitam a quantidade de recursão que você pode fazer, para que não seja realmente possível escrever um loop infinito. Em Scala, isso é apenas uma restrição de implementação, mas em C ++, é explicitamente permitido pelas especificações, acredito.
# 2 está tecnicamente fora do escopo da questão porque se tratava de compilar código que não está sendo executado (OTOH, existe uma pergunta filosófica profunda: se a verificação de tipo de um programa Haskell pode executar computação de Turing arbitrária, isso é compilação ou execução de um programa?)
# 1 é improvável. Por um lado, os compiladores de produção são muito complexos, portanto a probabilidade de erros é alta. Por outro lado, eles são rigorosamente testados, afinal, lidar com entrada mal formada normalmente faz parte da descrição do trabalho de um compilador. Mesmo se eles não forem testados, eles serão bombardeados com código mal formado de qualquer maneira… basta olhar para algumas perguntas do StackOverflow para exemplos de que lixo as pessoas lançam em seus compiladores!
Isso nos deixa com 3. Alguns compiladores podem limitar o tipo de acesso que o código de tempo de compilação tem ao sistema, mas para alguns casos de uso, o acesso total é inevitável. O objetivo dos provedores de tipos do F #, por exemplo, é "falsificar" tipos sintéticos para dados cujo sistema de tipos não corresponde aos F #, para que você possa interagir com, digamos, um serviço da web que possua um esquema WSDL em um tipo fortemente tipado. moda. No entanto, para fazer isso, o provedor de tipos precisa ter acesso ao recurso de esquema WSDL no sistema de arquivos ou na web, portanto, precisa ter acesso ao sistema de arquivos e à rede.
Então, é seguro? Tecnicamente, não. É arriscado? Na verdade não.
fonte
Não deve haver nenhum risco apenas compilando o código. Em teoria , poderia haver um bug no compilador que um hacker inteligente poderia tirar proveito, mas parece extremamente improvável.
Esteja ciente de que a construção pode não ser segura. Por exemplo, no C #, 'build event' permite que você especifique linhas de comando arbitrárias para executar antes e depois da compilação, o que é obviamente perigoso e muito mais fácil de explorar do que dizer estouros de buffer no código do compilador.
fonte
Em vez de especular, na verdade me preocupei em fazer alguma pesquisa sobre esse tópico antes de responder, indo para o recurso mais autorizado que eu conseguia pensar ( detalhes do CVE ). Essa lista abrangente de explorações de segurança divulgadas publicamente é provavelmente o melhor que se poderia fazer para avaliar os níveis de ameaça de vários tipos de software.
Não tive tempo de ler todo o material disponível, é claro, mas selecionei alguns compiladores "principais", IDEs e editores de texto para criar uma amostra de avaliação de ameaças. Se você é sério sobre a execução de qualquer software, deve ver pelo menos quais ameaças existem. Observe também que o software mais antigo geralmente é mais problemático do que o software mais recente; portanto, é ideal executar o mais recente do que você estiver executando.
Primeiro, podemos dar uma olhada em vários editores de texto. Parece que os melhores editores são os mais simples. Vi se você estiver usando um shell Linux ou o Bloco de Notas se estiver no Windows. Algo sem capacidade de formatação, sem análise, apenas visualização direta dos dados e finalização automática da análise, se um único caractere estiver fora do esquema de codificação atual. Mesmo o Notepad ++ teve um punhado de vulnerabilidades. Evite qualquer coisa complexa ao exibir arquivos não confiáveis.
Segundo, podemos olhar para os IDEs. Se você optar por abrir o arquivo em um IDE, esteja ciente de que alguns IDEs tiveram bugs relatados. Aparentemente, o Visual Studio teve explorações disponíveis por meio do mecanismo de extensões, portanto, abrir uma solução pode ser problemático. Evitar IDEs evita uma classe inteira de problemas entre você e o código não confiável. Ficar com o VI parece muito mais seguro.
Terceiro, podemos ver os compiladores reais. Pesquisei alguns, incluindo Adobe, Microsoft, Java e C / C ++ da GNU, e descobri que, de um modo geral, o código de compilação (e até a construção , assumindo que não haja arquivo de criação personalizado) é relativamente seguro, mas cada um desses compiladores faz ou fez possui explorações de segurança que podem surgir da execução dos binários compilados. Em outras palavras, eles não poderiam controlar seu sistema simplesmente compilando, mas poderiam executando o código.
Portanto, concluindo, assumindo que o método de entrega ainda não sequestrou seu sistema (por exemplo, seu cliente de email foi hackeado ou a unidade USB foi infectada ...), ler o código fonte e compilar o código fonte provavelmente é seguro . Ao pesquisar seu software específico, você pode torná-lo ainda mais seguro, digamos, validando o arquivo na página de códigos correta etc. A execução do código deve ser feita apenas em hardware com o qual você simplesmente não se importa. Não é uma VM, mas um computador fisicamente diferente, sem acesso à rede e sem arquivos sensíveis ou dispositivos externos. Mesmo que você ache que entende o código, uma pesquisa simples mostra que até os compiladores têm bugs que podem permitir que uma exploração de buffer overflow oculta por trás e execute código arbitrário, mas somente se você optar porexecutar ou depurar o programa. A compilação real deve ser segura.
fonte
Bem, eu começaria com "revisar o código deles". Por que é necessário executar o código?
Além disso, existem muitos compiladores on-line onde você pode simplesmente inserir o código, compilar e / ou executá-lo. Você pode fazer disso um requisito: ele compila neste e naquele compilador online.
Aqui está um exemplo de página com compiladores online: Compiladores online
O código para revisão de uma entrevista de emprego não deve ser tão grande assim, para você não entender o que está acontecendo.
fonte
Em geral, são muito complexos e geralmente são escritos usando linguagens nas quais não é prático provar essa propriedade.
Possivelmente não com essa intenção específica, mas a noção de compilador de teste de fuzz é pelo menos conhecida (o LLVM agora pode testar o próprio fuzz ). Testes destinados a capturar entradas que causam falhas no compilador devido a erros do compilador tendem a também apresentar falhas exploráveis.
Naturalmente, você teria que verificar se o compilador específico no qual você está interessado é testado ou fuzz para encontrar possíveis falhas e se os bugs encontrados são realmente corrigidos. A regra geral é que, se houver falhas piores do que as exceções não detectadas na memória, sem investigar mais os detalhes, você deverá considerar uma possibilidade séria de que elas poderiam ser aproveitadas em explorações.
Infelizmente, quanto tempo é um pedaço de corda. Em princípio, o email pode explorar seu cliente de email ou o código-fonte pode explorar seu editor de texto ou cppcheck, antes mesmo de chegar ao seu compilador. A sugestão de Sebastian nos comentários de usar um compilador on-line é muito boa, mas é claro que o código deve estar no formato que o compilador aceitará.
Qualquer linguagem ou compilador com recursos para execução de código geral em tempo de compilação é, obviamente, altamente suspeito. Os modelos C ++ são funcionalmente completos, mas não têm acesso (pretendido) ao sistema, portanto, são relativamente de baixo risco. BЈовић menciona
make
um risco extremamente alto (já que ele está executando o código do estranho, é só que o código está escrito namake
linguagem, não em C ++). Se o compilador funcionarsystem
, você estará no mesmo barco. Eu costumava trabalhar com um assembler que, se bem me lembro, poderia executar arbitrariamente a execução de código em tempo de compilação. Ele era destinado à computação de tabelas de consulta, mas acho que nada o impediu de fazer chamadas do sistema.Na prática , se o código parecer bom para mim e acho que o compreendo, consideraria um risco extremamente baixo compilá-lo, risco muito menor do que dizer "navegar na Internet com um navegador bloqueado". Eu faço coisas arriscadas rotineiramente na minha máquina de uso geral, mas muitas delas eu não faria, por exemplo, dentro de um laboratório de vírus ou em um servidor crítico. Se o código é engraçado ou evidentemente ofuscado, não posso arriscar compilá-lo porque, além do risco de conter uma exploração oculta no lixo ilegível, é um código de lixo. Código secreto é difícil, mas possível. O código secreto que envia a máquina por meio de uma exploração do compilador precisa conter uma carga executável não trivial, portanto, é extremamente difícil.
Se você quiser aprofundar isso, tente perguntar às pessoas que hospedam compiladores online. Se não tiver sido feito com eles (com a exceção de você chamar a atenção da NSA ou equivalente), você pode razoavelmente supor que não será feito com você. Eles se esforçam para executar o compilador em uma sandbox adequada, o que pode ser mais trabalhoso do que você deseja, mas eles podem pelo menos ser capazes de lhe dizer com que frequência essa sandbox evita problemas.
fonte
Embora isso geralmente seja uma preocupação, acho que o problema não existe devido à configuração.
O requerente enviou um código-fonte. Como ou por que isso aconteceu?
Bem, obviamente, existem apenas três possibilidades:
Cerca de 2) e 3)
O principal risco é distinguir entre 2) e 3). Há grandes chances de que, se o que ele escreveu vale a pena examinar , é algo que você pode obter o código-fonte on-line (de uma fonte "neutra") e com o qual você já deve estar familiarizado, ou é algo que você realmente não usa. não quero olhar porque você infringiria a propriedade intelectual de um concorrente (ex-empregador). O último significaria que você não iria querer contratar essa pessoa de qualquer maneira.
Se você puder obter a fonte online, faça-o. Se você puder verificar a contribuição do candidato a um software conhecido (incluindo software proprietário) pelo nome dele em algum lugar nos créditos, faça-o.
Em qualquer outro caso, simplesmente ignore o que ele lhe enviou. Ou não vale a pena olhar, é ilegal ou é de alto risco.
Cerca de 1)
O candidato enviou alguma coisa porque você lhe deu uma tarefa. Se você tem alguma competência (o que eu suponho que você tenha!), Então, para uma tarefa de programação típica (... que você até se escolheu!), Será capaz de dizer se é uma solução plausível que parece que pode funcionar. olhando o código-fonte por menos de 30 segundos (provavelmente 10 segundos).
Se você não pode dizer que o programa provavelmente funcionará (ou o que está fazendo) em 30 segundos, quem o escreveu não é o tipo de pessoa que você deseja contratar. Você quer pessoas que escrevam códigos que outros humanos possam entender e manter. Você não quer alguém que esteja tentando ficar esperto com você, nem alguém que vence regularmente o concurso ofuscado de C. Nem importa se o programa funciona. Assim que outra pessoa não consegue entender o código, ele nunca "funciona".
Se o programa parece que provavelmente funcionará, mas você encontrar algo que pareça "estranho" (por exemplo, sequências de escape unicode Java, literais de string bruta em C ++, coisas que se parecem com trigraphs, o que seja), trate a atribuição como "falha", mova para o próximo candidato. Não é necessário incluir nada parecido em 99% de todos os programas (e, com certeza, não em sua tarefa - espero). Portanto, se você encontrar algo "estranho" assim, o candidato não é alguém que você desejará contratar.
Se o código passar na primeira triagem, convém passar mais de 2 a 3 minutos para analisá-lo mais detalhadamente. Se você ainda estiver satisfeito com o que vê depois, poderá executá-lo através de um analisador estático e compilá-lo em uma máquina virtual com um alto nível de aviso.
Isso deve trazer à tona problemas que você pode ter perdido ao ler a fonte (como chamar comportamento indefinido ou restringir a conversão).
A compilação informará, em primeiro lugar, se o candidato possui a diligência e a atenção necessárias aos detalhes, e não se possui habilidades de programação. Assim como escrever o nome do empregador corretamente em seu aplicativo e verificar o seu currículo com ortografia antes de entregá-lo, é uma boa prática garantir que qualquer código-fonte entregue seja compilado sem erros (e de preferência sem avisos). Se alguém não conseguir fazer isso, você não deseja contratá-lo.
O risco de coisas ruins acontecerem neste momento (explorar o compilador e sair da VM) é negligenciável, pois você já executou uma verificação de plausibilidade sobre o código. Não vai acontecer.
fonte
Se a possibilidade o preocupa, pegue uma máquina mais antiga (a maioria de nós não tem alguns por aí?), Instale a versão atual do Linux e do compiler & c, copie o código-fonte, desconecte o cabo de rede (ou desligue o WiFi ) e faça as compilações. Se algo desagradável acontecer, ele não afetará mais nada.
E, para malware no Makefile, execute-o com o sinalizador -n (IIRC, RTMF) para ver o que ele fará sem realmente fazê-lo.
* A menos que o programador codifique o malware para que ele aguarde uma reconexão, mas nesse caso você a) limpa a máquina; eb) encaminhar o currículo do cara para a NSA, porque ele está desperdiçado no mundo comercial :-)
fonte
A linha inferior é que não é risco. O risco é bastante pequeno, como as outras respostas observam, mas existe um risco. Isso significa que você precisa fazer duas perguntas:
O segundo é o que você colocou aqui nesta pergunta, mas é o foco errado para este caso em particular. A resposta para mitigar o risco é clara e prontamente disponível: não compile o código em sua máquina . Você tem duas maneiras óbvias de compilá-lo sem usar sua máquina:
Essas maneiras de mitigar seu risco são tão óbvias, baratas e facilmente acessíveis que não vale a pena gastar muito tempo tentando analisar o tamanho do risco. Basta fazer um deles e acabar com ele.
fonte
O Visual Studio na verdade avisa se você abrir um projeto a partir de um local não confiável (por exemplo, baixado ou compartilhamento de rede).
Um exemplo de como isso poderia ser explorado seria com um projeto WPF: você pode fazer referência a classes .NET de XAML e fornecer ao IntelliSense, VS carrega e executa as classes referenciadas em tempo de design.
Isso significa que um invasor pode soltar uma DLL maliciosa no diretório bin, substituir o código-fonte por não malicioso e, em tempo de design, a DLL é executada. Após a sua primeira compilação, todos os vestígios do binário malicioso desaparecem.
Portanto, mesmo que todo o código fornecido esteja "limpo", o compilador está livre de erros e você, é claro, nunca executa manualmente nenhum .EXE fornecido, mas o código malicioso ainda pode ser executado em segundo plano. (Para se proteger contra esse ataque específico, você pode apenas garantir que NÃO há binários na árvore de diretórios antes de abrir a solução. O VS solicitará que você crie a solução antes de fornecer o IntelliSense em tempo de design.)
Vetores similares provavelmente existem com outros idiomas / sistemas operacionais.
fonte
Lendo o código fonte: totalmente seguro. Compilando código fonte: totalmente seguro. Executando binários compilados: bem ... isso depende.
Compilar é apenas o computador lendo o código fonte e escrevendo seu equivalente em formato binário. Após a compilação, você tem apenas dois documentos: um legível por humanos e outro legível por computador. A menos que você faça o computador ler (ou seja, executar) o segundo documento, nada vai acontecer.
fonte
mvn package
" descuidado pode extrair coisas e executar tarefas com plugins adicionais que você talvez não conheça facilmente. Tenho certeza que o mesmo pode se aplicar a outros sistemas de compilação.Acho que você está preocupado com um dos dois sabores:
Algumas pessoas sugeriram máquinas virtuais ou sistemas antigos, mas eu ofereço uma solução muito mais fácil: Compile como um usuário diferente com permissões reduzidas / diferentes . Muito mais fácil do que configurar uma máquina virtual ou um computador dedicado.
Se for improvável que seu sistema seja invadido por explorações em tempo de compilação, restaure a partir de backups (você tem esses, certo?).
fonte