[javascript] 부분을 ​​렌더링하기 전에 왜 escape_javascript입니까?

이 Railscast 에피소드를 보고 왜 escape_javascript여기에 호출 이 필요한지 궁금 합니다.

$("#reviews").append("<%= escape_javascript(render(:partial => @review)) %>");

무엇을 escape_javascript위해 사용됩니까?

Rails 문서 에 따르면 :

escape_javascript (자바 스크립트)

이스케이프 캐리어 반환 및 자바 스크립트 세그먼트에 대한 작은 따옴표 및 큰 따옴표.

그러나 그것은 나에게 큰 의미가 없습니다.



답변

브라우저가 실제로 실행하는 JavaScript를 사용자가 게시하는 것을 원하지 않기 때문입니까?


답변

코드를 두 부분으로 나누면 이해하기 더 쉽습니다.

첫 번째 부분 $("#reviews").append("<%= ... %>");은 erb가있는 자바 스크립트입니다. 이것은 <%= ... %>내부의 루비 코드가 반환하는 모든 것으로 대체 된다는 것을 의미 합니다. 대체 결과는 유효한 자바 스크립트 여야합니다. 그렇지 않으면 클라이언트가 처리하려고 할 때 오류가 발생합니다. 그래서 그것이 첫 번째입니다 : 유효한 자바 스크립트 가 필요 합니다 .

고려해야 할 또 다른 사항은 루비가 생성하는 모든 것이 큰 따옴표로 된 자바 스크립트 문자열 안에 포함되어야한다는 것 <%= ... %>입니다.. 즉, 생성 된 자바 스크립트는 다음과 같습니다.

$("#reviews").append("...");

이제 .NET 내부의 루비 부분을 살펴 보겠습니다 <%= ... %>. 무엇을 render(:partial => @review)합니까? 부분 렌더링입니다. 즉, html, css 등 모든 종류의 코드를 렌더링 할 수 있습니다.

그렇다면 부분에 이와 같은 간단한 html이 있으면 어떻게 될까요?

<a href="/mycontroller/myaction">Action!</a> 

자바 스크립트가 큰 따옴표로 묶인 문자열을 매개 변수로 사용하고 있다는 것을 기억하십니까? 단순히 <%= ... %>를 해당 부분의 코드로 바꾸면 문제가 발생합니다. 바로 뒤에 href=큰 따옴표가 있습니다! 자바 스크립트가 유효하지 않습니다.

// Without escaping, you get a broken javascript string at href
$("#reviews").append("<a href="/mycontroller/myaction">Action!</a>");

이런 일이 발생하지 않게하려면 이 특수 문자 를 이스케이프 하여 문자열이 잘리지 않도록해야합니다. 대신 이것을 생성하는 것이 필요합니다.

<a href=\"/mycontroller/myaction\">Action!</a>

이것은 무엇을 escape_javascript합니다. 반환 된 문자열이 자바 스크립트를 “중단”하지 않는지 확인합니다. 이를 사용하면 원하는 출력을 얻을 수 있습니다.

$("#reviews").append("<a href=\"/mycontroller/myaction\">Action!</a>")

문안 인사!


답변

사용자는 이스케이프 처리되지 않은 상태로두면 잠재적으로 실행되어 사용자가 애플리케이션을 제어 할 수있는 악성 코드 (악의적 인 사용자)를 게시 할 수 있습니다.

이 시도:

<% variable = '"); alert("hi there' %>
$("#reviews").append("<%= variable %>");

레일 구문에별로 익숙하지 않지만 탈출하지 않으면 variable경고 상자가 표시되며 의도 된 동작이라고 생각 하지 않습니다 .


답변

여기 에서 소스를 보면 훨씬 더 명확해질 것입니다.

이 기능은 다음 두 가지를 수행합니다.

  1. 입력 문자열의 문자를 JS_ESCAPE_MAP에 정의 된 문자로 대체합니다.

    이것의 목적은 자바 스크립트 코드가 포함되는 외부 문자열을 방해하지 않고 올바르게 직렬화되도록하는 것입니다. 예를 들어 큰 따옴표로 묶인 자바 스크립트 문자열이있는 경우 문자열 리터럴에 포함 된 모든 따옴표는 코드가 깨지지 않도록 작은 따옴표로 묶어야합니다.

  2. 이 함수는 또한 결과 문자열이 html로 안전한지 확인합니다. 그렇지 않은 경우 문자열이 html 안전하고 결과를 반환하는지 확인하기 위해 필요한 이스케이프를 수행합니다.

escape_javascript를 사용하는 경우 일반적으로 다른 문자열이나 기존 html에 동적으로 포함됩니다. 이렇게하면 전체 페이지가 렌더링되지 않는지 확인해야합니다.

이 응답의 일부 측면은 다른 응답에서 지적되었지만 모든 항목을 함께 가져 와서 자바 스크립트 이스케이프와 HTML 이스케이프의 차이점을 포함하고 싶었습니다. 또한 일부 응답은이 기능이 스크립트 삽입을 방지하는 데 도움이된다고 암시합니다. 이것이이 기능의 목적이라고 생각하지 않습니다. 예를 들어 리뷰에 alert ( ‘hi there’)가있는 경우 노드에 추가하는 것만으로 팝업이 실행되지 않습니다. 페이지로드시 또는 다른 이벤트를 통해 트리거되는 함수 내에 삽입하지 않습니다. html의 일부로 alert ( ‘hi there’)가 있다고해서 자바 스크립트로 실행된다는 의미는 아닙니다.

그것은 스크립트 삽입이 불가능하다는 것을 부정하지 않는다고 말했습니다. 그러나이를 피하기 위해 사용자 데이터를 가져 와서 데이터베이스에 저장할 때 조치를 취해야합니다. 제공하는 기능과 예제는 이미 저장된 정보를 렌더링하는 것과 관련이 있습니다.

이 정보가 귀하의 질문에 도움이 되었기를 바랍니다.


답변