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


120

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

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

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

Rails 문서 에 따르면 :

escape_javascript (자바 스크립트)

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

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


23
참고로 여기에서 허용되는 답변은 정답이 아닙니다. Kikito의이다
스티브

답변:


-3

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


4
하지만 언제 자바 스크립트 코드를 전달하고 렌더링하고 싶습니까?
berto77 2012

예, 실제로는 형식 지정 방법에 가깝습니다. 사용자가 자신의 자바 스크립트를 실행하는 것을 막지는 않습니다. 그것을 막을 수있는 것은 없습니다.
LasagnaAndroid

3
이것은 도움이되지 않습니다. 대신 kikito의 답변을 참조하십시오 .
nitsas

363

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

첫 번째 부분 $("#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>")

문안 인사!


4
참으로 아주 좋은 설명 감사합니다. 그런 다음 'escape_javascript'를 사용하는 것은 실제 자바 스크립트를 벗어나기 위해 실제로 사용하지 않기 때문에 일종의 오해의 소지가 있다고 생각합니다. 부분에 스크립트 태그를 넣고 원하는 자바 스크립트를 실행할 수 있습니다.
Steve

13
@Steve는 동의 escape_for_javascript했습니다. 자바 스크립트를 깨지 않도록 다른 코드 (예 : html)를 이스케이프하는 경우가 많기 때문에 더 나은 이름은 입니다.
kikito

14
escape_javascript()이제 더 짧은 방법이 있습니다 : simpley j()(최소한 Rails 4에서는).
mjnissim 2013-08-16

@kikito,이 효과를 사용하여 원격 양식으로 구성된 html 부분을 렌더링하려고합니까? 자바 스크립트를 통해 제출할 다른 양식을 포함하는 자바 스크립트로 부분을 렌더링하면 두 번째 요청이 js 대신 html이되는 이유를 찾으려고합니다. 시간이 있으시다면 제가 이미 게시 한 질문을 보시겠습니까? 감사! 내 질문
제이크 스미스

1
@JakeSmith는 귀하의 질문에 대답
kikito

8

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

이 시도:

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

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


8

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

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

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

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

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

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

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

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

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

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