Por que os recursos do tipo eval são considerados maus, em contraste com outros recursos possivelmente prejudiciais?

51

A maioria das línguas modernas (que são de alguma forma interpretadas) têm algum tipo de eval função. Essa função executa código de idioma arbitrário, na maioria das vezes passado como argumento principal como uma string (idiomas diferentes podem adicionar mais recursos à função eval).

Entendo que os usuários não devem ter permissão para executar essa função ( editar, ou seja, receber diretamente ou indiretamente informações arbitrárias de um usuário arbitrário para serem repassados eval), especialmente com o software do servidor, pois podem forçar o processo a executar código malicioso. Dessa forma, tutoriais e comunidades nos dizem para não usar o eval. No entanto, há muitas vezes em que eval é útil e usado:

  • Regras de acesso personalizadas para elementos de software (IIRC OpenERP possui um objeto ir.ruleque pode usar código python dinâmico).
  • Cálculos e / ou critérios personalizados (o OpenERP possui campos como esse para permitir cálculos de código personalizados).
  • Analisadores de relatórios do OpenERP (sim, eu sei que estou assustando você com coisas do OpenERP ... mas é o principal exemplo que tenho).
  • Codificando efeitos de feitiço em alguns jogos de RPG.

Portanto, eles têm um bom uso, desde que sejam usados ​​corretamente. A principal vantagem é que o recurso permite que os administradores escrevam códigos personalizados sem precisar criar mais arquivos e incluí-los (embora a maioria das estruturas que usam os recursos eval também tenham uma maneira de especificar um arquivo, módulo, pacote, ... para ler).

No entanto, eval é mau na cultura popular. Coisas como invadir seu sistema vêm à mente.

No entanto, existem outras funções que podem ser prejudiciais se, de alguma forma, forem acessadas pelos usuários: desvincular, ler, escrever (semântica de arquivos), alocação de memória e aritmética de ponteiros, acesso ao modelo de banco de dados (mesmo que não considerando casos injetáveis ​​por SQL).

Portanto, basicamente, na maioria das vezes, quando qualquer código não é gravado corretamente ou não é monitorado adequadamente (recursos, usuários, ambientes, ...), o código é ruim e pode levar até a um impacto econômico.

Mas há algo especial com evalfunções (independentemente do idioma).

Pergunta : Existe algum fato histórico para esse medo se tornar parte da cultura popular, em vez de dar a mesma atenção aos outros aspectos possivelmente perigosos?

Luis Masuelli
fonte
11
Discordo que isso seja muito amplo e, como evidência, apresento as quatro respostas que são de duração razoável.
12
Eles votaram para fechar como muito amplo ? (Ainda não consigo ver votos próximos nesta comunidade) Esse motivo próximo está se tornando um motivo curinga sem nenhum significado ultimamente. Especialmente quando o ponto que pergunto é bastante claro com exemplos e um ponto específico a perguntar. Vou pedir este tema em Meta ...
Luis Masuelli
13
Por que se tornar parte da cultura popular, com mais atenção do que outras características perigosas? Porque a aliteração eval - o mal é fácil de lembrar
Bergi
5
A alocação de memória e a aritmética dos ponteiros são vistas como más por muitos.
user253751
5
Deve-se notar que o OpenERP (agora Odoo) não apenas chama eval, ele possui uma função interna chamada safe_evalque prepara o ambiente para impedir que o código faça coisas perigosas. Porém, foram encontrados erros, já que o Python é uma linguagem bastante flexível e, portanto, difícil de controlar.
André Paramés

Respostas:

76

Uma evalfunção por si só não é má, e há um ponto sutil que eu não acredito que você esteja fazendo:

Permitir que um programa execute entradas arbitrárias do usuário é ruim

Eu escrevi um código que usava um evaltipo de função e era seguro: o programa e os parâmetros eram codificados. Às vezes, não há recurso de linguagem ou biblioteca para fazer o que o programa precisa e executar um comando shell é o caminho curto. "Eu tenho que terminar de codificar isso em algumas horas, mas escrever Java / .NET / PHP / qualquer código levará dois dias. Ou posso evalem cinco minutos."

Depois de permitir que os usuários executem o que quiserem, mesmo se bloqueados por privilégios de usuário ou atrás de uma tela "segura", você cria vetores de ataque. Toda semana, algum CMS aleatório, software de blog etc. tem uma falha de segurança corrigida, na qual um invasor pode explorar uma falha como essa. Você está confiando na pilha de software inteira para proteger o acesso a uma função que pode ser usada rm -rf /ou algo catastrófico (nota: é improvável que esse comando seja bem-sucedido, mas falhará após causar alguns danos).

Existe algum fato histórico para esse medo se tornar parte da cultura popular, em vez de dar a mesma atenção aos outros aspectos possivelmente perigosos?

Sim, existe um precedente histórico. Devido aos inúmeros bugs que foram corrigidos ao longo dos anos em vários softwares que permitem que atacantes remotos executem códigos arbitrários, a idéia de evalcair fora de moda. As linguagens e bibliotecas modernas têm um rico conjunto de funcionalidades que se tornam evalmenos importantes, e isso não é por acaso. Isso facilita o uso das funções e reduz o risco de uma exploração.

Tem sido dada muita atenção a muitos recursos potencialmente inseguros em idiomas populares. Se alguém recebe mais atenção é principalmente uma questão de opinião, mas os evalrecursos certamente têm um problema de segurança comprovável que é fácil de entender. Por um lado, eles permitem executar comandos do sistema operacional, incluindo shell embutidos e programas externos que são padrão (por exemplo, rmou del). Dois, combinados com outras explorações, um invasor pode ser capaz de carregar seu próprio script executável ou shell e executá-lo através do seu software, abrindo a porta para que quase tudo aconteça (nada disso é bom).

Este é um problema difícil. O software é complexo e uma pilha de softwares (por exemplo, LAMP ) é composta por vários softwares que interagem entre si de maneiras complexas. Cuidado ao usar recursos de linguagem como esse e nunca permita que os usuários executem comandos arbitrários.


fonte
2
Você é o único :). Embora se houver um bom exemplo conhecido que contribuiu para essa cultura, eu gostaria de vê-lo na resposta.
Luis Masuelli
5
Não tenho conhecimento de qualquer único exemplo, eu acredito que este é mais "morte por mil cortes", com muitos exemplos menores de exploits sendo usado e remendado. Não estou exagerando quando digo que alguma exploração remota é corrigida semanalmente em algum software.
11
Meu IDE é um programa que me permite - é usuário - executar entradas arbitrárias. Acho mais útil do que ruim.
Den
3
@ Den isso seria uma exceção. Sendo um IDE, tenho certeza de que você poderia causar problemas sem essa capacidade. Basta escrever no seu código fonte. Além disso, você já tem acesso total ao computador em que é executado. A implicação aqui é que um evalpode elevar privilégios. o que não é um problema se eles já estiverem elevados.
3
@ Den: É o que Raymond Chen resumiu como "o outro lado da câmara". Você já pode executar rm -rf /, não há necessidade de fazer isso de maneira complicada por meio de um IDE. O problema evalé que ele abre essa capacidade para muitos atores que não deveriam ter essa capacidade.
precisa saber é o seguinte
38

Parte disso é simplesmente que as nuances são difíceis. É fácil dizer algo como nunca usar goto, campos públicos, interpolação de strings para consultas sql ou eval. Essas declarações não devem realmente ser entendidas como dizendo que nunca há, sob nenhuma circunstância, uma razão para usá-las. Mas evitá-los como regra geral é uma boa idéia.

O Eval está fortemente desencorajado porque combina vários problemas comuns.

Em primeiro lugar, é suscetível a ataques de injeção. Aqui é como a injeção de SQL, pois quando dados controlados pelo usuário são inseridos no código, é fácil permitir acidentalmente que código arbitrário seja inserido.

Em segundo lugar, os iniciantes tendem a usar eval para contornar códigos mal estruturados. Um codificador iniciante pode escrever um código parecido com:

x0 = "hello"
x1 = "world"
x2 = "how"
x3 = "are"
x4 = "you?"
for index in range(5):
   print eval("x" + index)

Isso funciona, mas é realmente a maneira errada de resolver esse problema. Obviamente, usar uma lista seria muito melhor.

Em terceiro lugar, a avaliação é tipicamente ineficiente. Muito esforço é gasto para acelerar nossas implementações de linguagem de programação. Mas é difícil acelerar o eval e usá-lo normalmente terá efeitos prejudiciais no seu desempenho.

Então, eval não é mau. Podemos dizer que avaliar é mau, porque bem, é uma maneira cativante de colocá-lo. Qualquer programador iniciante deve ficar estritamente longe de eval, porque o que quer que eles desejem fazer, eval é quase certamente a solução errada. Para certos casos de uso avançados, eval faz sentido, e você deve usá-lo, mas obviamente tenha cuidado com as armadilhas.

Winston Ewert
fonte
13
Seu segundo caso é muito importante. Em idiomas que têm eval , mas também são compilados, avaliando uma corda para produzir uma referência variável é não-trivial. Por exemplo, se var x = 3; print(x)for compilado , não será necessário saber em tempo de execução que a fonte usou o nome "x". Para var x = 3; print(eval("x"))funcionar, esse mapeamento precisa ser registrado. Esta é uma questão real: no Common Lisp (let ((x 3)) (print (eval 'x)))lançará uma exceção de variável não acoplada porque a variável lexical x não tem nenhuma conexão com o nome após a compilação do código.
21730 Joshua Taylor #
@JohnuaTaylor Você quer dizer terceira razão, não segunda?
user253751
11
@immibis, acho que ele está se referindo ao código no segundo motivo. Mas você está correto, está realmente relacionado à terceira razão: desempenho.
Winston Ewert
Viu esta pergunta , não viu? ;)
jpmc26
@ jpmc26, não. Mas já vi muitas coisas assim.
Winston Ewert 03/03
20

O que se resume é que a "execução arbitrária de código" é uma conversa técnica para "capaz de fazer qualquer coisa". Se alguém é capaz de explorar a execução arbitrária de código no seu código, esta é literalmente a pior vulnerabilidade de segurança possível, porque significa que eles podem fazer o que for possível para o seu sistema.

"Outros bugs possivelmente prejudiciais" podem ter limites, o que significa que eles são, por definição, capazes de causar menos danos do que uma execução arbitrária de código sendo explorada.

Mason Wheeler
fonte
2
Por razões de argumento, o uso indevido de ponteiros também leva à execução arbitrária de código , mas os ponteiros são menosprezados do que o evalsão.
Dmitry Grigoryev
12
@DmitryGrigoryev São realmente? Fora do C ++, os ponteiros geralmente são considerados extremamente perigosos e evitados. O C # suporta ponteiros, por exemplo, mas costuma ser a última coisa que você tenta depois de esgotar todas as outras opções (geralmente, por razões de desempenho na manipulação de dados). A maioria das linguagens modernas não tem suporte para ponteiros. Até o próprio C ++ está se movendo em direção a ponteiros "mais seguros" que tentam aliviar os problemas com ponteiros arbitrários (por exemplo, usando listas / matrizes verdadeiras em vez de apenas ponteiros, usando safe_ptr, passagem de referência ...).
Luaan 02/02
2
@DmitryGrigoryev: Você pode fornecer uma referência para alguém dizendo que os ponteiros são menos perigosos que o eval?
precisa saber é o seguinte
2
@JacquesB, aqui está você :) #
Dmitry Grigoryev #
11
@ JacquesB, sim; era uma piada (eu esperava que o sorriso deixasse claro o suficiente). O OP fez essa afirmação, não eu, então você deve pedir uma prova.
Dmitry Grigoryev
15

Há uma razão prática e teórica.

A razão prática é que observamos que freqüentemente causa problemas. É raro que a avaliação resulte em uma boa solução, e muitas vezes resulta em uma solução ruim, onde você teria uma solução melhor no final se você fingisse que a avaliação não existia e abordasse o problema de maneira diferente. Portanto, o conselho simplificado é ignorá-lo e, se você encontrar um caso em que deseja ignorar o conselho simplificado, esperamos que você tenha pensado nisso o suficiente para entender por que o conselho simplificado não é aplicável e o comum armadilhas não afetarão você.

A razão mais teórica é que, se é difícil escrever um bom código, é ainda mais difícil escrever um código que escreva um bom código. Esteja você usando eval ou gerando instruções SQL juntando cadeias ou escrevendo um compilador JIT, o que você está tentando é geralmente mais difícil do que o esperado. O potencial de injeção de código mal-intencionado é uma grande parte do problema, mas, além disso, é geralmente mais difícil saber se o seu código está correto se ele nem existir até o tempo de execução. Portanto, o conselho simplificado é manter as coisas mais fáceis para você: "use consultas SQL parametrizadas", "não use eval".

Tomando seu exemplo de efeitos ortográficos: uma coisa é criar um compilador ou intérprete Lua (ou qualquer outro) em seu jogo, a fim de permitir aos designers de jogos uma linguagem mais fácil que C ++ (ou qualquer outro) para descrever os efeitos ortográficos. A maioria dos "problemas de avaliação" não se aplica se tudo o que você está fazendo é avaliar o código que foi escrito e testado e incluído no jogo ou no DLC ou o que você tem. Isso é apenas misturar idiomas. Os grandes problemas atingem você quando você tenta gerar Lua (ou C ++, ou SQL, ou comandos de shell, ou qualquer outra coisa) em tempo real e estraga tudo.

Steve Jessop
fonte
11
Obviamente, a geração do código de tempo de execução pode ser feita corretamente e a avaliação pode ser útil. Por exemplo, eu freqüentemente uso o eval para coisas de metaprogramação / macro, especialmente quando eu quero mais desempenho do que uma OOP "mais limpa" ou uma solução funcional poderia fornecer. O código resultante geralmente é melhor e mais simples porque possui menos clichê. No entanto, estar ciente de vários problemas relacionados ao sandboxing, mecanismos de escape, injeção de código, regras de escopo, relatórios de erros, otimização etc. requer um nível não trivial de proficiência no idioma, e a avaliação é positivamente perigosa sem esse conhecimento.
amon
11

Não, não há fato histórico óbvio.

Os males de eval são fáceis de ver desde o início. Outros recursos são levemente perigosos. As pessoas podem excluir dados. As pessoas podem ver dados que não deveriam. As pessoas podem escrever dados que não deveriam. E eles só podem fazer a maioria dessas coisas se você errar de alguma forma e não validar a entrada do usuário.

Com o eval, eles podem invadir o pentágono e fazer parecer que você fez isso. Eles podem inspecionar suas teclas para obter suas senhas. Assumindo uma linguagem completa de Turing, eles podem literalmente fazer qualquer coisa que seu computador seja capaz de fazer.

E você não pode validar a entrada. É uma string arbitrária de forma livre. A única maneira de validar isso seria criar um analisador e um mecanismo de análise de código para o idioma em questão. Boa sorte com isso.

Telastyn
fonte
11
... ou a entrada é proveniente de uma fonte confiável, como os arquivos de definição ortográfica de um jogo.
user253751
3
@immibis mas se a entrada é predefinida e testada com segurança, por que usar eval quando poderia ser incluída na fonte do sistema?
Jules
3
@immibis - porque ninguém nunca hacks arquivos do jogo ...
Telastyn
2
... não é isso que "Turing complete" significa (a integridade de Turing está a um passo da computação irrelevante para a do mundo real).
precisa saber é o seguinte
11
@Telastyn: O que um programa Javascript não pode fazer. Ou mesmo um programa C ++. O Javascript é executado dentro de uma caixa de proteção (navegador) que está em outra caixa de proteção (anel 3 em x86 speak). O vetor de interrupção está fora dessa caixa de proteção, sob controle do SO. E essa sandbox externa, anel 3, é aplicada à CPU.
precisa saber é o seguinte
6

Eu acho que tudo se resume aos seguintes aspectos:

  • Necessidade
  • Uso (Guardado)
  • Acesso
  • Verificabilidade
  • Ataques em vários estágios

Necessidade

Olá, escrevi esta ferramenta de edição de imagens extremamente interessante (disponível por US $ 0,02). Depois de abrir a imagem, você pode passar vários filtros sobre a imagem. Você pode até criar scripts usando Python (o programa em que escrevi o aplicativo). Vou usar evalsuas informações, confiando em você para ser um usuário respeitável.

(mais tarde)

Obrigado por comprá-lo. Como você pode ver, funciona exatamente como prometi. Oh, você quer abrir uma imagem? Não, você não pode. Não usarei o readmétodo, pois é um tanto inseguro. Salvando? Não, eu não vou usar write.

O que estou tentando dizer é: Você precisa ler / escrever para quase as ferramentas básicas. O mesmo para armazenar as pontuações mais altas do seu jogo tão incrível.

Sem leitura / gravação, seu editor de imagens é inútil. Sem eval? Vou escrever um plugin personalizado para isso!

Uso (Guardado)

Muitos métodos podem ser potencialmente perigosos. Como, por exemplo, o reade write. Um exemplo comum é um serviço da Web que permite ler imagens de um diretório específico, especificando o nome. No entanto, o 'nome' pode ser de fato qualquer caminho (relativo) válido no sistema, permitindo que você leia todos os arquivos aos quais o serviço da Web tem acesso, e não apenas as imagens. Abusar deste exemplo simples é chamado de 'caminho atravessado'. Se o seu aplicativo permite o percurso, é ruim. Um readsem se defender contra o caminho pode ser chamado de mal.

No entanto, em outros casos, a cadeia de caracteres readestá totalmente sob o controle dos programadores (talvez codificado permanentemente?). Nesse caso, dificilmente é mau usar read.

Acesso

Agora, outro exemplo simples, usando eval.

Em algum lugar do seu aplicativo da web, você deseja algum conteúdo dinâmico. Você permitirá que os administradores insiram algum código que seja executável. Como os administradores são usuários confiáveis, teoricamente isso pode ser aceitável. Certifique-se de não executar o código enviado por não administradores, e você está bem.

(Isto é, até que você despediu o bom administrador, mas esqueceu de revogar o acesso dele. Agora, seu aplicativo da Web está no lixo).

Verificabilidade.

Outro aspecto importante, eu acho, é como é fácil verificar a entrada do usuário.

Usando a entrada do usuário em uma chamada de leitura? Apenas certifique-se (muito) de que a entrada para a chamada de leitura não contenha nada de malicioso. Normalize o caminho e verifique se o arquivo aberto está no seu diretório de mídia. Agora isso é seguro.

Entrada do usuário em uma chamada de gravação? Mesmo!

Injeção SQL? Apenas escape ou use consultas parametrizadas e você estará seguro.

Eval? Como você vai verificar a entrada usada para a evalchamada? Você pode trabalhar muito, mas é realmente muito difícil (se não impossível) fazê-lo funcionar com segurança.

Ataques em vários estágios

Agora, toda vez que você usa a entrada do usuário, você precisa pesar os benefícios de usá-la, contra os perigos. Proteja seu uso o máximo que puder.

Considere novamente o evalmaterial capaz no exemplo de administrador. Eu te disse que estava tudo bem.

Agora, considere que, na verdade, existe um lugar no seu aplicativo da Web em que você esqueceu de escapar do conteúdo do usuário (HTML, XSS). Essa é uma ofensa menor que a avaliação acessível pelo usuário. Mas, usando o conteúdo do usuário sem escape, um usuário pode assumir o navegador da Web de um administrador e adicionar um evalblob capaz na sessão de administradores, permitindo novamente o acesso total ao sistema.

(O mesmo ataque de vários estágios pode ser feito com injeção de SQL em vez de XSS ou algumas gravações arbitrárias de arquivos substituindo o código executável em vez de usar eval)

Sjoerd Job Postmus
fonte
2
"Você pode trabalhar muito, mas é realmente muito difícil (se não impossível) fazê-lo funcionar com segurança". Isso é impossível. Prova simples: em vez de tentar descobrir se o código fornecido pelo usuário é ou não "seguro", tente descobrir algo muito, muito mais simples, e veja o quanto isso já é difícil : o código fornecido pelo usuário para?
Jörg W Mittag 01/03
2
@ JörgWMittag: me dê um programa escrito em Coq e eu vou provar.
André Paramés
11
@ JörgWMittag: De acordo. Dependendo do idioma e do escopo da entrada do usuário. Poderia muito bem ser eval("hard coded string" + user_input_which_should_be_alphanumeric + "remainder"). É possível verificar se a entrada é alfanumérica. Além disso, 'interrompe' é ortogonal a 'modifica / acessa o estado em que não deve tocar' e 'faz métodos calóricos que não deve chamar'.
Sjoerd Job Postmus
3
@ JörgWMittag É impossível provar que um determinado programa não fará algo, mas não é impossível definir de maneira conservadora um conjunto restrito de programas para os quais você pode prová-lo e impor que os programas de entrada sejam membros desse conjunto.
user253751
3

Para que esse recurso funcione, significa que preciso manter uma camada de reflexão que permita o acesso total ao estado interno de todo o programa.

Para linguagens interpretadas, posso simplesmente usar o estado do interpretador, o que é fácil, mas, em combinação com os compiladores JIT, ainda aumenta significativamente a complexidade.

Sem isso eval, o compilador JIT geralmente pode provar que os dados locais de um encadeamento não são acessados ​​a partir de qualquer outro código, portanto, é perfeitamente aceitável reordenar acessos, omitir bloqueios e armazenar em cache os dados frequentemente usados ​​por períodos mais longos. Quando outro encadeamento executa uma evalinstrução, pode ser necessário sincronizar o código compilado JIT em execução com isso, de repente o código gerado pelo JIT precisa de um mecanismo de fallback que retorne à execução não otimizada dentro de um prazo razoável.

Esse tipo de código tende a ter muitos bugs sutis e difíceis de reproduzir e, ao mesmo tempo, também limita a otimização no compilador JIT.

Para linguagens compiladas, a troca é ainda pior: a maioria das otimizações é proibida, e eu preciso manter informações extensas sobre símbolos e um intérprete, para que a flexibilidade adicional geralmente não valha a pena - geralmente é mais fácil definir uma interface para algumas funções internas. estruturas, por exemplo, fornecendo uma visão de script e acesso simultâneo ao controlador ao modelo do programa .

Simon Richter
fonte
"Para que esse recurso funcione, significa que preciso manter uma camada de reflexão que permita acesso total ao estado interno de todo o programa" - não, apenas às partes que você deseja afetar. No caso do OpenERP / Odoo, o código que está sendo avaliado apenas tem acesso a um número muito limitado de variáveis ​​e funções que ele pode chamar, e todos eles são locais de threads.
André Paramés
1

Rejeito a premissa que evalé considerada mais maligna que a aritmética do ponteiro ou mais perigosa do que o acesso direto à memória e ao sistema de arquivos. Não conheço nenhum desenvolvedor sensato que acredite nisso. Além disso, os idiomas que suportam o acesso direto à memória aritmética / direta do ponteiro normalmente não suportam evale vice-versa, portanto, tenho certeza de que frequência essa comparação seria relevante.

Mas evalpode ser uma vulnerabilidade mais conhecida , pelo simples motivo de ser suportada pelo JavaScript. O JavaScript é uma linguagem em área restrita sem acesso direto à memória ou ao sistema de arquivos, portanto, simplesmente não possui essas vulnerabilidades, exceto as deficiências na própria implementação da linguagem. Evalé, portanto, um dos recursos mais perigosos da linguagem, pois abre a possibilidade de execução arbitrária de códigos. Acredito que muito mais desenvolvedores desenvolvem em JavaScript do que em C / C ++, por isso evalé simplesmente mais importante conhecer do que estouros de buffer para a maioria dos desenvolvedores.

JacquesB
fonte
0

Nenhum programador sério consideraria Eval "mau". É simplesmente uma ferramenta de programação, como qualquer outra. O medo (se houver) dessa função não tem nada a ver com a cultura popular. É simplesmente um comando perigoso que geralmente é mal utilizado e pode apresentar sérias falhas de segurança e prejudicar o desempenho. Pela minha própria experiência, diria que é raro encontrar um problema de programação que não possa ser resolvido de maneira mais segura e eficiente por outros meios. Os programadores com maior probabilidade de usar o eval são aqueles com menos qualificação para fazê-lo com segurança.

Dito isto, existem idiomas em que o uso de eval é apropriado. Perl vem à mente. No entanto, eu pessoalmente acho que isso raramente é necessário em outras linguagens mais modernas, que oferecem suporte nativo ao tratamento estruturado de exceções.

user1751825
fonte
isso nem tenta abordar a pergunta: "Existe algum fato histórico para esse medo se tornar parte da cultura popular". Veja como responder
gnat
A pergunta, na minha opinião, é baseada em uma premissa falsa, então eu a respondi como tal.
user1751825
0

Acho que você o abordou muito bem na parte seguinte da sua pergunta (grifo meu):

eles têm um bom uso, desde que sejam usados ​​adequadamente

Para os 95% que podem usá-lo corretamente, tudo está bem; mas sempre haverá pessoas que não o usarão corretamente. Alguns deles se resumem a inexperiência e falta de habilidade; o restante será malicioso.

Sempre haverá pessoas que querem ultrapassar fronteiras e encontrar falhas de segurança - algumas para o bem, outras para o mal.

Quanto ao aspecto histórico, as evalfunções de tipo permitem essencialmente a execução de código arbitrário que já havia sido explorado no popular CMS da web, Joomla! . Com o Joomla! acionando mais de 2,5 milhões de sites em todo o mundo , há muitos danos potenciais não apenas aos visitantes desses sites, mas também à infraestrutura em que está hospedado e também à reputação dos sites / empresas que foram explorados.

O Joomla! exemplo pode ser simples, mas foi gravado.

gabe3886
fonte
0

Existem algumas boas razões para desencorajar o uso de eval(embora algumas sejam específicas para determinados idiomas).

  • O ambiente (lexicamente e dinamicamente) usado por evalé freqüentemente surpreendente (ou seja, você acha que eval(something here)deve fazer uma coisa, mas faz outra, possivelmente desencadeando exceções)
  • Frequentemente, existe uma maneira melhor de realizar a mesma coisa (concatenação de fechamentos lexicais construídos às vezes é uma solução melhor, mas que pode muito bem ser específica do Common Lisp)
  • É muito fácil acabar com dados não seguros sendo avaliados (embora isso possa ser protegido principalmente).

Pessoalmente, eu não chegaria ao ponto de dizer que isso é mau, mas sempre desafiarei o uso de evaluma revisão de código, com palavras na linha de "você considerou algum código aqui ?" (se eu tiver tempo para fazer pelo menos uma substituição provisória) ou "você tem certeza de que uma avaliação é realmente a melhor solução aqui?" (se não tiver).

Vatine
fonte
isso nem tenta abordar a pergunta: "Existe algum fato histórico para esse medo se tornar parte da cultura popular". Veja como responder
gnat
0

Na Sociedade da mente de Minsky , capítulo 6.4, ele diz

Existe uma maneira de a mente se observar e ainda acompanhar o que está acontecendo. Divida o cérebro em duas partes, A e B. Conecte as entradas e saídas do cérebro A ao mundo real - para que ele possa sentir o que acontece lá. Mas não conecte o cérebro B ao mundo exterior; em vez disso, conecte-o para que o cérebro A seja o mundo do cérebro B!

Quando um programa (B) escreve outro programa (A), ele está funcionando como um metaprograma. O assunto de B é o programa A.

Existe um programa C. Essa é a sua cabeça que escreve o programa B.

O perigo é que pode haver alguém (C ') com más intenções, que pode interferir nesse processo, para que você obtenha coisas como injeção de SQL.

O desafio é tornar o software mais inteligente sem também torná-lo mais perigoso.

Mike Dunlavey
fonte
Dois votos positivos e dois votos negativos. Parece que isso atinge um nervo.
Mike Dunlavey
0

Você tem muitas boas respostas aqui e o principal motivo é claramente que a execução arbitrária do código é ruim mmmkay, mas vou adicionar outro fator que outros apenas abordaram:

É realmente difícil solucionar problemas de código que está sendo avaliado em uma sequência de texto. Suas ferramentas de depuração normais são praticamente diretamente da janela e você é reduzido a traçados ou ecos da velha escola. Obviamente, isso não importa tanto se você tem um fragmento em uma linha que deseja, evalmas como programador experiente, provavelmente encontrará uma solução melhor para isso, enquanto a geração de código em larga escala pode estar em algum lugar em que uma função de avaliação torna-se um aliado potencialmente útil.

glenatron
fonte