Destructuring Tweets - 에피소드 7 - 훨씬 더 사악한 평가

그뤼스 딕! Twitter에서 JavaScript 퀴즈를 분해하는 방법에 대한 시리즈에 오신 것을 환영합니다. 이번 일요일에는 절대 사용해서는 안 되는 API인 eval에 대해 배우게 될 것입니다. 1

금주의 단편



이번 주 출처:

function challenge(input){
  eval(input.toUpperCase())
}

// provide an input that makes function challenge call alert(1)
challenge('alert(1)');


여기에서 우리는 진흙탕으로 이동합니다. 작성자는 challenge 라는 함수를 선언하고 이 함수는 eval 를 래핑합니다. 비결은 래퍼 함수의 인수가 먼저 .toUpperCase()를 통해 연결된다는 것입니다.
연습은 함수를 실행하는 것입니다alert(1).

출력



여기서 출력은 훌륭하지는 않지만 eval가 정확히 무엇을 하는지 모르는 경우 일종의 마술처럼 느껴집니다. 그러나 상당히 간단합니다. eval는 문자열로 전달되는 코드 조각을 실행합니다.
따라서 우리 스니펫의 경우 eval가 전역 범위에서 정의되지 않은 "ALERT"를 실행하려고 시도하기 때문에 인터프리터에서 오류가 발생합니다.

ReferenceError: ALERT is not defined 


분석



따라서 먼저 스니펫으로 돌아가서 정확히 어떤 일이 일어나는지 살펴보겠습니다. 인수alert(1)를 전달합니다. 래퍼 함수가 없는 경우 이 코드는 alert 잘 실행됩니다.

eval('alert(1)');


그러나 .toUpperCase() 를 통해 파이프되기 때문에 호출된 함수인 문자열은 실제로 ALERT 이고 JavaScript는 대소문자를 구분하는 언어입니다!
이제 우리는 이 문제를 극복해야 합니다. 나는 세 가지 가능한 해결책을 생각해 냈습니다. 하나씩 확인해보자.

문자열의 프로토타입 변경


toUpperCase 메서드는 String 프로토타입의 일부이므로 함수 본문을 쉽게 변경할 수 있습니다.

function challenge(input){
  eval(input.toUpperCase())
}

String.prototype.toUpperCase = () => alert(1);
challenge('alert(1)');


이 경우 toUpperCaseinput 에서 호출되면 문자열을 파이프 및 구문 분석하지 않고 대신 경고를 실행합니다. 호출된 함수는 대상 동작으로 덮어씁니다.

ALERT 기능 추가



다른 방향으로 가서 누락된 함수ALERT를 전역 객체에 추가할 수도 있습니다.

function challenge(input){
  eval(input.toUpperCase())
}

window.ALERT = input => alert(input);
challenge('alert(1)');


그 접근 방식은 간단합니다. 올바른 이름으로 다른 기능을 추가합니다. alert 를 호출하는 대신 ALERT 를 호출하면 인수가 alert 에 전달됩니다.

객체 전달



처음 두 가지 솔루션은 실제로 불법이었습니다. 저자는 입력을 전달하여 문제를 해결한다고 명시적으로 명시했습니다. 이것이 우리가 그 접근 방식에서 하는 일입니다. toUpperCase 함수로 객체를 전달합니다.

function challenge(input){
  eval(input.toUpperCase())
}

challenge({ toUpperCase: () => 'alert(1)' });


String의 프로토타입에서 구현을 사용하는 대신 자체 버전의 toUpperCase 개체를 전달합니다.

스니펫 요약



  • 속임수: 기존 함수 호출을 조작하는 방법

  • 주요 학습: JavaScript는 대소문자를 구분하며eval 문자열에서 코드를 실행합니다(사용해서는 안 됩니다!), 프로토타이핑 및 전역 범위
  • .

  • 추가 읽기:
  • Eval
  • String Prototype toUpperCase
  • JavaScript's case-sensitivity
  • The Window Object
  • Prototypes





  • 경고: 문자열에서 JavaScript를 실행하는 것은 엄청난 보안 위험입니다. eval()을 사용할 때 나쁜 행위자가 임의의 코드를 실행하는 것은 너무 쉽습니다. MDN   에서 자세히 읽어보세요.

    좋은 웹페이지 즐겨찾기