다른 유해한 기능과 달리 평가 식 기능이 왜 악의적 인 것으로 간주됩니까?


51

대부분의 현대 언어 (어떻게 해석되는)는 일종의 평가 기능을 가지고 있습니다. 이러한 함수는 임의의 언어 코드를 실행하며 대부분의 경우 주요 인수로 문자열로 전달됩니다 (다른 언어는 eval 함수에 더 많은 기능을 추가 할 수 있음).

나는 사용자가 (이 기능을 실행하도록 허용해서는 안 이해 편집 예에 전달 될 임의의 사용자로부터 직접 또는 간접적으로 임의의 입력을 받아 eval들이 악성 코드를 실행하는 프로세스를 강제 할 수 있기 때문에, 특히 서버 측 소프트웨어). 그런 식으로, 튜토리얼과 커뮤니티는 eval을 사용 하지 말라고 말합니다 . 그러나 eval 이 유용하고 사용되는 경우가 많습니다 .

  • 소프트웨어 요소에 대한 사용자 지정 액세스 규칙 (IIRC OpenERP에는 ir.rule동적 파이썬 코드를 사용할 수 있는 개체 가 있습니다).
  • 사용자 정의 계산 및 / 또는 기준 (OpenERP에는 사용자 정의 코드 계산을위한 필드가 있습니다).
  • OpenERP 보고서 파서 (예, OpenERP 관련 자료를보고 놀란다는 것을 알고 있습니다. 그러나 이것이 제가 가진 주요 예입니다).
  • 일부 RPG 게임에서 주문 효과를 코딩합니다.

따라서 올바르게 사용되는 한 잘 사용됩니다. 주요 장점은 관리자가 더 많은 파일을 작성하지 않고 사용자 정의 코드를 작성하여 포함시킬 수 있다는 것입니다 (평가 기능을 사용하는 대부분의 프레임 워크에는 파일, 모듈, 패키지 등을 읽을 수있는 방법이 있지만).

그러나 대중 문화에서 평가는 악하다. 시스템 침입과 같은 것들이 떠 오릅니다.

그러나 언 링크, 읽기, 쓰기 (파일 시맨틱), 메모리 할당 및 포인터 산술, 데이터베이스 모델 액세스 (SQL 삽입 가능 사례를 고려하지 않더라도) 등 사용자가 액세스하는 경우 유해 할 수있는 다른 기능이 있습니다.

그래서, 기본적으로, 대부분의 시간에 임의의 코드가 기록되지 않습니다 제대로 여부를 지켜 제대로 (자원, 사용자, 환경, ...), 코드는 악하고도 경제적 효과로 이어질 수 있습니다.

그러나 eval언어에 관계없이 함수 에는 특별한 것이 있습니다.

질문 : 위험 가능성이있는 다른 특징들에 대해 동일한주의를 기울이지 않고 대중 문화의 일부가되는이 두려움에 대한 역사적 사실이 있습니까?


11
나는 이것이 너무 광범위하다는 것에 동의하지 않으며, 증거로서 합리적인 길이의 네 가지 답변을 제시합니다.

12
그들은 너무 광범위 하게 폐쇄 투표 ? (이 커뮤니티에서는 아직 가까운 투표를 볼 수 없습니다.) 그 가까운 이유는 요즘 전혀 의미없는 와일드 카드 이유가되고 있습니다. 특히 내가 묻는 요점은 예와 구체적인 요점으로 명확합니다. 나는 메타에서이 주제를 물을 것이다 ...
Luis Masuelli

13
왜 다른 위험한 기능보다 더 많은 관심을 가지고 대중 문화의 일부가됩니까? 두운의 때문에 평가 - 악은 기억하기 쉬운
BERGI

5
많은 사람들 메모리 할당과 포인터 산술 을 악의로 여깁니다.
user253751

5
OpenERP (현재 Odoo)는 단지 호출 하는 것이 아니라 코드가 위험한 일을하지 않도록 환경을 준비 eval하는 내부 함수를 safe_eval가지고 있습니다. 그러나 파이썬은 매우 유연한 언어이므로 제어하기 어렵 기 때문에 버그가 발견되었습니다.
André Paramés

답변:


76

eval자체 기능은 악하지 않고, 당신이하고 있습니다 믿지 않는 미묘한 지점이있다 :

프로그램이 임의의 사용자 입력을 실행하도록 허용하는 것은 좋지 않습니다

eval함수 유형 을 사용하는 코드를 작성 했으며 안전했습니다. 프로그램과 매개 변수가 하드 코딩되었습니다. 프로그램에 필요한 언어 나 라이브러리 기능이없는 경우도 있고 쉘 명령을 실행하는 것이 짧은 경로 일 수도 있습니다. "이 코드는 몇 시간 안에 완료해야하지만 Java / .NET / PHP / 어떤 코드를 작성하는 데 이틀이 소요됩니다. 또는 eval5 분 안에 코드를 작성할 수 있습니다 ."

사용자 권한에 의해 또는 "보안"화면 뒤에 숨어 있어도 사용자가 원하는 것을 실행하도록 허용하면 공격 경로를 생성합니다. 매주 임의의 CMS, 블로그 소프트웨어 등에는 공격자가 이와 같은 취약점을 악용 할 수있는 보안 취약점이 있습니다. 당신은에 사용할 수있는 기능에 대한 액세스를 보호하기 위해 전체 소프트웨어 스택에 의존하고 rm -rf /(이 명령에 성공 않을 수 있습니다,하지만 실패합니다 참고 다른 치명적인 또는 뭔가를 한 후 손상의 조금의 원인).

이 두려움이 대중 문화의 일부가되어 역사적으로 위험한 다른 특징들에도 관심을 기울이는 역사적 사실이 있습니까?

그렇습니다. 역사적 선례가 있습니다. 원격 공격자가 임의의 코드를 실행할 수 있도록 다양한 소프트웨어에서 수년 동안 수정 된 수많은 버그로 인해이 아이디어 eval는 대체로 유리하지 않았습니다. 현대 언어와 라이브러리에는 eval그다지 중요하지 않은 다양한 기능 세트가 있으며 이는 우연이 아닙니다. 둘 다 기능을보다 쉽게 ​​사용하고 악용의 위험을 줄입니다.

인기있는 언어로 된 잠재적으로 안전하지 않은 많은 기능에 많은 관심을 기울였습니다. 하나가 더 많은 관심을받는 여부는 주로 의견의 문제이지만, eval기능은 확실히이 증명 이해하기 쉬운 보안 문제를. 이를 위해 쉘 내장 및 표준 (예 : rm또는 del) 과 같은 외부 프로그램을 포함하여 운영 체제 명령을 실행할 수 있습니다. 둘째, 다른 익스플로잇과 함께 공격자는 자신의 실행 파일 또는 셸 스크립트를 업로드 한 다음 소프트웨어를 통해 실행하여 거의 모든 일이 발생할 수있는 문을 열 수 있습니다.

이것은 어려운 문제입니다. 소프트웨어는 복잡하고 소프트웨어 스택 (예 : LAMP )은 복잡한 방식으로 서로 상호 작용하는 여러 소프트웨어입니다. 이와 같은 언어 기능을 사용하는 방법에주의하고 사용자가 임의의 명령을 실행할 수 없도록하십시오.


2
당신은 하나입니다 :). 이 문화에 기여한 잘 알려진 예가 있다면, 그 답을보고 싶습니다.
Luis Masuelli

5
나는 하나의 예를 알지 못한다 . 나는 이것이 더 많은 악용 사례가 사용되고 패치되어 더 많은 "천사 컷에 의한 죽음"이라고 믿는다. 일부 원격 익스플로잇이 일부 소프트웨어 에서 매주 패치된다고해도 과언이 아닙니다 .

1
내 IDE는 사용자-임의의 입력을 실행할 수있는 프로그램입니다. 나는 그것이 나쁘기보다는 유용하다고 생각합니다.
Den

3
@Den은 예외입니다. IDE이기 때문에 그 능력이 없으면 신체 상해를 일으킬 수 있다고 확신합니다. 소스 코드로 작성하십시오. 또한 이미 실행중인 컴퓨터에 대한 모든 액세스 권한이 있습니다. 여기서 의미는 권한을 상승시킬eval 수 있다는 것 입니다. 이미 상승한 경우에는 문제가되지 않습니다.

3
@Den : Raymond Chen이 "에어 록의 반대쪽"이라고 요약 한 것입니다. 이미 실행할 수 있으므로 rm -rf /IDE를 통해 복잡한 방법으로 수행 할 필요가 없습니다. 문제 eval는 그 능력을 가져서는 안되는 많은 배우에게 그 능력을 열어 준다는 것입니다.
MSalters

38

그것의 일부는 단순히 뉘앙스가 어렵다는 것입니다. goto, public field, SQL 쿼리에 대한 문자열 보간 또는 eval을 사용하지 않는 것과 같은 것을 쉽게 말 할 수 있습니다. 이러한 진술은 어떤 상황에서도 그것을 사용해야 할 이유가 전혀 없다고 말하는 것으로 실제로 이해되어서는 안됩니다. 그러나 일반적인 규칙으로 피하는 것이 좋습니다.

Eval은 몇 가지 일반적인 문제를 결합하므로 크게 권장하지 않습니다.

첫째, 주입 공격에 취약합니다. 사용자 제어 데이터를 코드에 삽입 할 때 실수로 임의 코드를 삽입 할 수 있다는 점에서 SQL 삽입과 같습니다.

둘째, 초보자는 eval을 사용하여 잘못 구성된 코드를 피하는 경향이 있습니다. 초보자 코더는 다음과 같은 코드를 작성할 수 있습니다.

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

이것은 작동하지만 실제로이 문제를 해결하는 잘못된 방법입니다. 분명히 목록을 사용하는 것이 더 좋습니다.

셋째, 평가는 일반적으로 비효율적입니다. 프로그래밍 언어 구현 속도를 높이기 위해 많은 노력이 필요합니다. 그러나 평가는 속도를 높이기 어렵고 일반적으로 사용하면 성능에 해로운 영향을 미칩니다.

따라서 평가는 악이 아닙니다. 우리는 평가가 악의적이라고 말할 수 있습니다. 모든 초보자 코더는 eval이 거의 확실하게 잘못된 솔루션이기 때문에 eval에서 멀리 떨어져 있어야합니다. 특정 고급 사용 사례의 경우 eval이 의미가 있으므로이를 사용해야하지만 함정에주의해야합니다.


13
두 번째 경우는 매우 중요합니다. eval은 있지만 컴파일 된 언어의 경우 변수 참조를 생성하기 위해 문자열을 평가하는 것은 쉽지 않습니다. 경우 예는 var x = 3; print(x)되어 컴파일 후 것을 어떤 런타임 지식이있을 필요가없는 소스 이름 'x'를 사용했다. var x = 3; print(eval("x"))작동 하려면 해당 매핑을 기록해야합니다. 이것은 실제 문제입니다. Common Lisp (let ((x 3)) (print (eval 'x)))에서는 어휘 변수 x가 코드가 컴파일 된 후 이름 과 연결되어 있지 않기 때문에 언 바운드 변수 예외가 발생합니다 .
Joshua Taylor

@JohnuaTaylor 두 번째가 아닌 세 번째 이유를 의미 합니까?
user253751

1
@immibis, 나는 그가 두 번째 이유에서 코드를 언급하고 있다고 생각합니다. 그러나 세 번째 이유 인 성능과 관련이 있습니다.
Winston Ewert

이 질문을 봤 습니까? ;)
jpmc26

@ jpmc26, 아뇨. 그러나 나는 그것을 많이 보았다.
Winston Ewert

20

요약하자면, "임의 코드 실행"은 "무엇이든 할 수있는"기술적 인 이야기입니다. 누군가 코드에서 임의의 코드 실행을 악용 할 수있는 경우 이는 문자 그대로 시스템에서 가능한 모든 작업을 수행 할 수 있기 때문에 가능한 최악의 보안 취약점 입니다.

"다른 잠재적으로 유해한 버그"에는 한계가있을 수 있습니다. 즉, 정의에 따르면 임의의 코드 실행을 이용하는 것보다 덜 해칠 수 있습니다.


2
논쟁을 위해 포인터를 잘못 사용하면 임의의 코드가 실행 되지만 포인터는 그보다 훨씬 적습니다 eval.
Dmitry Grigoryev

12
@DmitryGrigoryev 정말입니까? C ++ 외부에서 포인터는 일반적으로 매우 위험하고 피해야합니다. 예를 들어 C #은 포인터를 지원하지만 다른 모든 옵션 (일반적으로 데이터 조작의 성능상의 이유로)을 모두 사용한 후에 마지막으로 시도하는 경향이 있습니다. 대부분의 현대 언어는 포인터를 지원하지 않습니다. C ++ 자체조차도 임의의 포인터 (예를 들어, safe_ptr, 참조 전달 ...을 사용하는 포인터 대신 실제 목록 / 배열 사용)를 사용하여 문제를 완화시키려는 "safer"포인터로 이동하고 있습니다.
Luaan

2
@ DmitryGrigoryev : 포인터가 eval보다 덜 위험하다고 말하는 사람에게 참조를 제공 할 수 있습니까?
JacquesB


1
@JacquesB, 예; 그것은 농담으로 의도되었습니다 (웃음이 충분히 명확해질 것이라고 기대했습니다). OP는 저가 아니라 그 진술을했기 때문에 증거를 요구해야합니다.
Dmitry Grigoryev

15

실용적이고 이론적 인 이유가 있습니다.

실제적인 이유는 자주 문제를 일으키는 것을 관찰하기 때문입니다. eval이 좋은 솔루션을 만드는 것은 드문 일이 아니며 eval이 존재하지 않고 다른 방식으로 문제에 접근했을 때 결국 더 나은 솔루션을 얻었을 때 나쁜 솔루션을 만드는 경우가 종종 있습니다. 그래서 단순화 된 조언은 그것을 무시하는 것이며, 단순화 된 조언을 무시하고 싶을 경우에, 단순화 된 조언이 적용되지 않는 이유와 일반적인 이유를 충분히 이해할 수 있기를 바랍니다. 함정은 당신에게 영향을 미치지 않습니다.

더 이론적 인 이유는 좋은 코드를 작성하기 어려운 경우 좋은 코드를 작성하는 코드 를 작성 하기가 더 어렵다는 것입니다. eval을 사용하거나 문자열을 고집하거나 JIT 컴파일러를 작성하여 SQL 문을 생성하든, 시도하는 것이 종종 예상보다 어렵습니다. 악의적 인 코드 삽입의 가능성은 문제의 큰 부분이지만, 코드가 런타임까지 존재하지 않는 경우 코드의 정확성을 아는 것은 일반적으로 어렵습니다. 따라서 단순화 된 조언은 "매개 변수화 된 SQL 쿼리 사용", "평가판 사용 안 함"등보다 쉽게 ​​작업을 수행하는 것입니다.

철자 효과 예제를 보자 : 게임 디자이너가 C ++ (또는 다른 것)보다 철자 효과를 설명하기에 더 쉬운 언어로 만들기 위해 Lua (또는 무엇이든) 컴파일러 또는 인터프리터를 게임에 빌드하는 것이 한 가지입니다. 당신이하고있는 모든 것이 게임이나 DLC 또는 무슨 행동에 작성되고 테스트되어 포함 된 코드를 평가하는 것이라면 대부분의 "평가 문제"는 적용되지 않습니다. 그것은 단지 언어를 혼합하는 것입니다. Lua (또는 C ++, SQL 또는 쉘 명령 등)를 즉시 생성하여 엉망으로 만들려고 할 때 큰 문제가 발생합니다.


1
물론 런타임 코드 생성 올바르게 수행 할 수 있으며 eval 이 유용 할 수 있습니다. 예를 들어 메타 프로그래밍 / 매크로와 같은 것들에 eval을 자주 사용합니다. 특히 "클리너"OOP 나 기능적 솔루션이 제공 할 수있는 것보다 더 많은 성능을 원할 때 특히 그렇습니다. 상용구가 적기 때문에 결과 코드가 더 좋고 단순 합니다. 그러나 샌드 박싱, 이스케이프 메커니즘, 코드 삽입, 범위 지정 규칙, 오류보고, 최적화 등과 같은 다양한 문제를 인식하려면 언어에있어 사소한 수준의 숙련도가 필요하며, 그 지식이 없으면 평가는 긍정적으로 위험합니다.
amon

11

아닙니다. 명백한 역사적 사실은 없습니다.

평가의 악은 처음부터 분명하다. 다른 기능은 약간 위험합니다. 사람들은 데이터를 삭제할 수 있습니다. 사람들은 원하지 않는 데이터를 볼 수 있습니다. 사람들은하지 말아야 할 데이터를 쓸 수 있습니다. 그리고 어떻게 든 사용자 입력을 망치지 않고 유효성을 검사하지 않으면 대부분의 작업을 수행 할 수 있습니다.

eval을 사용하면 국방부를 해킹하여 자신이 한 것처럼 보이게 할 수 있습니다. 키 입력을 검사하여 비밀번호를 얻을 수 있습니다. 튜링의 완전한 언어를 가정하면 컴퓨터에서 수행 할 수있는 모든 작업을 그대로 수행 할 수 있습니다.

그리고 입력을 확인할 수 없습니다. 임의의 자유 형식 문자열입니다. 그것을 검증하는 유일한 방법은 해당 언어에 대한 파서 및 코드 분석 엔진을 구축하는 것입니다. 행운을 빕니다.


1
... 또는 게임의 스펠 정의 파일과 같은 신뢰할 수있는 소스에서 입력을받습니다.
user253751

3
@immibis 그러나 입력이 사전 정의되고 안전하다고 테스트 된 경우 시스템 소스에 포함될 수있을 때 eval을 사용하는 이유는 무엇입니까?
Jules

3
@immibis- 아무도 게임 파일을 해킹 하지 않기 때문에 ...
Telastyn

2
"완전한 투어링"이 의미하는 것은 아닙니다 (완전한 투어링은 실제 컴퓨팅과 무관 한 단계입니다).
Leushenko

1
@Telastyn : Javascript 프로그램이 할 수없는 것. 또는 C ++ 프로그램도 있습니다. Javascript는 샌드 박스 (브라우저) 내에서 실행되며 다른 샌드 박스 (x86에서 링 3)에 있습니다. OS 벡터에서 인터럽트 벡터는 해당 샌드 박스 외부에 있습니다. 그리고 그 외부 샌드 박스 인 링 3은 CPU로 강화됩니다.
MSalters

6

나는 그것이 다음과 같은 측면으로 요약된다고 생각한다.

  • 필요성
  • (가드) 사용법
  • 접속하다
  • 검증 가능성
  • 다단계 공격

필요성

안녕하세요,이 매우 멋진 이미지 편집 도구를 작성했습니다 ($ 0.02에 사용 가능). 이미지를 연 후에는 이미지 위에 여러 필터를 전달할 수 있습니다. Python (응용 프로그램을 작성한 프로그램)을 사용하여 직접 스크립트를 작성할 수도 있습니다. 나는 단지 eval당신의 의견에 따라 당신을 존경하는 사용자라고 믿습니다.

(나중)

구입해 주셔서 감사합니다. 보시다시피 약속 한대로 정확하게 작동합니다. 오, 당신은 이미지를 열고 싶어? 아냐, 못해 read다소 안전하지 않으므로이 방법을 사용하지 않습니다 . 절약? 아니요, 사용하지 않습니다 write.

내가 말하려는 것은 거의 기본적인 도구에 대한 읽기 / 쓰기가 필요하다는 것입니다. 정말 멋진 게임의 높은 점수를 저장하는 경우에도 마찬가지입니다.

읽기 / 쓰기가 없으면 이미지 편집기가 쓸모가 없습니다. 없이 eval? 나는 당신을 위해 사용자 정의 플러그인을 작성합니다!

(가드) 사용법

많은 방법이 위험 할 수 있습니다. 예를 들어 readand write. 일반적인 예는 이름을 지정하여 특정 디렉토리에서 이미지를 읽을 수있는 웹 서비스입니다. 그러나 'name'은 실제로 시스템의 유효한 (상대) 경로 일 수 있으므로 이미지뿐만 아니라 웹 서비스가 액세스 할 수있는 모든 파일을 읽을 수 있습니다. 이 간단한 예제를 남용하는 것을 '경로 탐색'이라고합니다. 앱이 경로 순회를 허용하면 나쁘다. read경로 순회를 방어하지 않으면 A 는 악이라고 할 수 있습니다.

그러나 다른 경우에 대한 문자열 read은 프로그래머가 제어합니다 (하드 코딩 될 수 있습니까?). 이 경우에는 사용하기가 거의 불가능합니다 read.

접속하다

이제 또 다른 간단한 예제를 사용 eval합니다.

웹앱 어딘가에 동적 콘텐츠가 필요합니다. 관리자는 실행 가능한 코드를 입력 할 수 있습니다. 관리자가 신뢰할 수있는 사용자 인 경우 이론적으로는 괜찮을 수 있습니다. 관리자가 아닌 사람이 제출 한 코드를 실행하지 마십시오.

(즉, 멋진 관리자를 해고했지만 액세스를 취소하는 것을 잊었을 때까지는 웹 응용 프로그램이 휴지통에 있습니다.)

검증 가능성.

중요한 또 다른 측면은 사용자 입력을 확인하는 것이 얼마나 쉬운 지입니다.

읽기 호출에서 사용자 입력을 사용합니까? 읽기 호출 입력에 악의적 인 내용이 포함되어 있지 않은지 확인하십시오. 경로를 정규화하고 열린 파일이 미디어 디렉토리에 있는지 확인하십시오. 이제 안전합니다.

쓰기 호출에서 사용자 입력? 같은!

SQL 주입? 그냥 도망 치거나 매개 변수가있는 쿼리를 사용하면 안전합니다.

평가 요? eval통화에 사용 된 입력을 어떻게 확인 합니까? 당신은 매우 열심히 일할 수 있지만, 안전하게 작동하는 것은 정말로 어렵습니다 (불가능하지는 않지만).

다단계 공격

이제 사용자 입력을 사용할 때마다 위험에 대비하여 사용의 이점을 평가해야합니다. 사용을 최대한 보호하십시오.

eval관리자 예제에서 가능한 것들을 다시 고려하십시오 . 나는 그것이 괜찮다고 말했어.

이제 실제로 웹 응용 프로그램에 사용자 콘텐츠 (HTML, XSS)를 피하는 것을 잊어 버린 장소가 있다고 생각하십시오. 그것은 사용자가 액세스 할 수있는 평가보다 덜 공격적입니다. 그러나 이스케이프 처리되지 않은 사용자 콘텐츠를 사용하여 사용자는 관리자의 웹 브라우저를 인계 eval하고 관리자 세션을 통해 가능한 블롭을 추가하여 전체 시스템 액세스를 다시 허용 할 수 있습니다.

(XSS 대신 SQL 삽입을 사용하거나을 사용하는 대신 실행 코드를 대체하는 임의의 파일 쓰기로 동일한 다단계 공격을 수행 할 수 있음 eval)


2
"당신은 매우 열심히 일할 수 있지만, 안전하게 작동하는 것은 정말로 어렵습니다 (불가능하지는 않지만)." - 그것은 이다 불가능합니다. 간단한 증거 : 대신 제공되는 사용자가 "보안"입니다 코드 여부를 알아 내려고 노력의 단지 훨씬 간단 많은 무언가를 알아 내기 위해 시도하고 얼마나 열심히보고 이미 : 코드는 사용자의 중단에 의해 제공 하는가?
Jörg W Mittag

2
@ JörgWMittag : Coq로 작성된 프로그램을 제공해 주시면 증명하겠습니다.
André Paramés

1
@ JörgWMittag : 동의합니다. 언어 및 사용자 입력 범위에 따라 다릅니다. 그것도 될 수 있습니다 eval("hard coded string" + user_input_which_should_be_alphanumeric + "remainder"). 입력이 영숫자인지 확인할 수 있습니다. 또한 '정지합니까?'는 '만지지 말아야하는 수정 / 액세스 상태를 수행합니까?'및 '호출해서는 안되는 메소드를 수행합니다'와 직교합니다.
Sjoerd Job Postmus

3
@ JörgWMittag 주어진 프로그램 무언가 를하지 않는다는 것을 증명하는 것은 불가능 하지만, 그것을 증명할 수있는 제한된 프로그램 세트를 보수적으로 정의하고 입력 프로그램이 해당 세트의 멤버가되도록 강제하는 것은 불가능하지 않습니다.
user253751

3

이 기능이 전혀 작동하기 위해서는 전체 프로그램의 내부 상태에 완전히 액세스 할 수있는 반사 레이어를 유지해야합니다.

인터프리터 언어의 경우 인터프리터 상태를 간단하게 사용할 수 있지만 JIT 컴파일러와 함께 사용하면 여전히 복잡성이 크게 증가합니다.

이 없으면 evalJIT 컴파일러는 스레드의 로컬 데이터가 다른 코드에서 액세스되지 않았 음을 증명할 수 있으므로 액세스 순서를 바꾸고 잠금을 생략하며 자주 사용하는 데이터를 더 오랫동안 캐시하는 것이 완벽하게 허용됩니다. 다른 스레드가 eval명령문을 실행할 때 실행중인 JIT 컴파일 코드를 동기화해야 할 수 있으므로 갑자기 JIT 생성 코드에는 적절한 시간 내에 최적화되지 않은 실행으로 리턴하는 폴백 메커니즘이 필요합니다.

이러한 종류의 코드는 미묘하고 버그를 재현하기 어려운 경향이 있으며 동시에 JIT 컴파일러의 최적화에 제한을 둡니다.

컴파일 된 언어의 경우, 훨씬 더 나빠질 수 있습니다. 대부분의 최적화는 금지되어 있으며 광범위한 기호 정보와 해석기를 유지해야하므로 추가 유연성은 일반적으로 가치가 없습니다. 일부 내부에 대한 인터페이스를 정의하는 것이 더 쉽습니다 스크립팅 컨트롤러 에 프로그램 모델에 대한 동시 액세스를 제공하는 구조 .


"이 기능이 전혀 작동하기 위해서는 전체 프로그램의 내부 상태에 대한 완전한 액세스를 가능하게하는 리플렉션 레이어를 유지해야합니다."-아닙니다. OpenERP / Odoo의 경우 회피되는 코드는 호출 할 수있는 매우 제한된 수의 변수 및 함수에만 액세스 할 수 있으며 모두 스레드 로컬입니다.
André Paramés

1

포인터 산술보다 더 악eval 하다고 생각 되거나 직접 메모리 및 파일 시스템 액세스보다 더 위험한 전제를 거부합니다 . 나는 그것을 믿을만한 현명한 개발자를 모른다. 또한 포인터 산술 / 직접 메모리 액세스를 지원하는 언어는 일반적으로 지원하지 않으며 그 반대도 마찬가지입니다. 따라서 그러한 비교가 얼마나 자주 관련되는지 알 수 있습니다.eval

그러나 JavaScript로 지원되는 단순한 이유 때문에 eval잘 알려진 취약점 일 수 있습니다 . JavaScript는 직접적인 메모리 나 파일 시스템 액세스가없는 샌드 박스 언어이므로 언어 ​​구현 자체의 취약점을 약화시키는 이러한 취약점은 없습니다. Eval따라서 임의의 코드가 실행될 가능성이 있기 때문에 언어의 가장 위험한 기능 중 하나입니다. C / C ++보다 JavaScript에서 더 많은 개발자가 개발하고 있다고 생각하므로 eval대다수 개발자의 버퍼 오버플로보다 알고 있어야합니다.


0

어떤 심각한 프로그래머도 Eval을 "악"이라고 생각하지 않습니다. 다른 프로그래밍 도구와 마찬가지로 단순히 프로그래밍 도구입니다. 이 기능에 대한 두려움 (두려움이있는 경우)은 대중 문화와 관련이 없습니다. 그것은 종종 잘못 사용되는 위험한 명령이며 심각한 보안 허점을 초래하고 성능을 저하시킬 수 있습니다. 내 경험으로는 다른 방법으로는 더 안전하고 효율적으로 해결할 수없는 프로그래밍 문제가 거의 발생하지 않는다고 말합니다. 평가를 가장 많이 사용하는 프로그래머는 아마도 가장 안전하지 않은 프로그래머 일 것입니다.

말하지만 eval의 사용이 적절한 언어가 있습니다. 펄이 떠오른다. 그러나 개인적으로 구조적 예외 처리를 기본적으로 지원하는 다른 최신 언어에서는 거의 필요하지 않습니다.


이것은 "대중 문화의 일부가되는이 두려움에 대한 역사적 사실이 있는가?"라는 질문을 다루려고 시도조차하지 않습니다. 답변하는 방법
gnat

내 의견으로는, 그 질문은 잘못된 전제에 기초하고 있기 때문에 나는 그렇게 대답했다.
user1751825

0

나는 당신이 당신의 질문의 다음 부분에서 그것을 아주 잘 커버한다고 생각합니다 (강조 광산).

그들은 좋은 사용을 제대로 사용하는만큼

그것을 올바르게 사용할지도 모르는 95 %에게는 모든 것이 좋고 훌륭합니다. 그러나 그것을 올바르게 사용하지 않는 사람들이 항상있을 것입니다. 그 중 일부는 경험이 부족하고 능력이 부족할 것이고 나머지는 악의적 일 것입니다.

경계를 넓히고 보안 허점을 찾는 사람들이 항상있을 것입니다.

역사적 사실 측면에서, eval유형 함수는 본질적 으로 인기있는 웹 CMS 인 Joomla!에서 이전에 악용 된 임의 코드 실행 을 허용합니다 . . Joomla 와 함께 ! 전 세계 250 만 개 이상의 사이트에 전력을 공급하고 있습니다 . 이는 해당 사이트 방문자뿐만 아니라 호스팅 된 인프라 및 악용 된 사이트 / 회사의 평판에도 큰 피해를줍니다.

줌라! 예는 단순한 것일 수도 있지만 기록 된 것입니다.


0

사용을 권장하지 않는 몇 가지 이유가 있습니다 eval(일부 언어는 특정 언어에만 해당됨).

  • 에 의해 사용되는 환경 (어휘 적으로 그리고 동적으로) eval은 종종 놀랍습니다 (즉, eval(something here)한 가지를해야 한다고 생각 하지만 다른 것을 수행하여 예외를 유발할 수 있습니다)
  • 동일한 일을 달성하는 더 좋은 방법이 종종 있습니다 (구성된 어휘 클로저를 연결하는 것이 더 나은 솔루션이지만 공통 리스프에 따라 다를 수 있음)
  • 안전하지 않은 데이터를 평가하는 것은 너무 쉬운 일입니다 (주로이를 막을 수는 있지만).

나는 개인적으로 그것이 악하다고 말하기까지는하지 않겠지 만 항상 eval" 여기서 어떤 코드 를 고려 했습니까?" (적어도 잠정적 인 교체를 할 시간이 있다면) 또는 "여기서 실제로 eval이 최선의 해결책일까요?" (그렇지 않으면).


이것은 "대중 문화의 일부가되는이 두려움에 대한 역사적 사실이 있는가?"라는 질문을 다루려고 시도조차하지 않습니다. 참조 답변하는 방법
모기

0

6.4 장 Minsky 's Society of Mind 에서

하나의 마음이 자신을보고 아직도 무슨 일이 일어나고 있는지를 추적하기위한 방법. 뇌를 A와 B의 두 부분으로 나눕니다. A- 뇌의 입력과 출력을 현실 세계에 연결하여 뇌에서 일어나는 일을 감지 할 수 있습니다. 그러나 B-brain을 외부 세계와 전혀 연결하지 마십시오. 대신 A- 브레인이 B- 브레인의 세계가되도록 연결하십시오!

한 프로그램 (B)이 다른 프로그램 (A)을 쓰면 메타 프로그램으로 작동합니다. B의 주제는 프로그램 A입니다.

C 프로그램이 있습니다. 그것은 당신의 머리 속에 프로그램 B를 쓰는 것입니다.

위험은 악의적 인 의도를 가진 누군가 (C ')가있을 수 있으며,이 프로세스를 방해 할 수 있으므로 SQL 주입과 같은 것을 얻을 수 있습니다.

문제는 소프트웨어를 더 위험하게 만들지 않고 더 똑똑하게 만드는 것입니다.


두 개의 공감 및 두 개의 공감. 아마도 신경에 부딪힌 것 같습니다.
Mike Dunlavey가

0

여기에 좋은 대답이 많이 있으며 주된 이유는 임의 코드 실행이 나쁜 것입니다.

텍스트 문자열에서 평가되는 코드의 문제를 해결하는 것은 실제로 어렵습니다. 일반적인 디버깅 도구는 거의 똑바로 나오지 않으며 매우 오래된 추적 또는 에코로 줄어 듭니다. 원 라이너에 프래그먼트가 있고 eval숙련 된 프로그래머라면 더 나은 솔루션을 찾을 수 있지만 대규모 코드 생성은 평가 기능이있는 곳일 수 있습니다. 잠재적으로 유용한 동맹국이됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.