2011-12-08 2 views
17

업데이트 : 답변이 없으므로 질문을 약간 변경하고 있습니다. 아래에 링크 된 Dean의 블로그 게시물에 대한 의견은 Safari에서이 기술이 작동하지 않는다는 것을 나타냅니다."iframe 샌드 박스"기술은 안전한가요?

내 질문은 다음과 같습니다. 아래에 설명 된 기술이 최신 브라우저에서 작동합니까? 특히 Safari에서 작동하는지 확인 할 수 있습니까?

최근 blog post입니다. ...

샌드 박스 원주민 ...을 포함하여 브라우저의 다양한 지원하는 사파리 2.0 이상

...하지만 나중에 iframe이 기술 "이라고 말했다 : 그것은 하나 개의 지점에서 말한다 Safari를 제외한 모든 주요 브라우저에서 지원됩니다. "라고 말하면서 위조 된 생성자를 사용하여 이상한 물건을 만드는 것을 보여줍니다. __proto__ 약간 해킹 된 것처럼 보입니다.

두 개의 서로 다른 윈도우가 Object.prototype과 같은 것을 실제로 공유 할 수 있다고 생각하는 경우는 거의 없습니다. 교차 도메인 iframe은 어떻게됩니까? 한 프레임에서 프로토 타입을 수정하면 다른 프레임의 프로토 타입이 수정됩니까? 이것은 명백한 보안 우려처럼 보입니다. 누군가이 상황에 대해 밝혀주세요.

* "작품"은 My.Object != Object을 의미하므로 프로토 타입은 다른 창에 영향을주지 않고 하나의 창에서 수정할 수 있습니다.


원래의 게시물

나는이 이전에 요청하고있다,하지만 난 마음에 특정 솔루션을 가지고, 나는 이러한 유형의 솔루션이 논의되었는지를 알고 싶어하기 전에 어디 내가 아는 그것이 얼마나 신뢰할 수 있고 잘 받아 들여지는지 배울 수 있습니다.

질문은 실제로 유형 자체를 망칠 필요없이 네이티브 유형을 확장하는 방법이므로 Array.prototype을 변경하는 것은 좋지 않습니다 (다른 코드는 배열과 함께 for..in을 사용하고있을 수 있습니다). 일부 기능이 포함 된 원시 배열을 반환하는 가짜 생성자를 만드는 것은 좋은 해결책으로 보이지 않지만 실제로 네이티브 객체를 확장하는 것이 좋습니다. 하지만 네이티브 함수를 호출하려고하면 "push is generic"과 같은 오류가 발생하기 때문에 기본 javascript 더미 함수 prototype switcharoo 스타일 확장을 기본 형식으로 할 수 없습니다.

그래서, 내가 생각한 솔루션은 다른 창 만들기, 해당 창에서 기본 생성자의 프로토 타입에 기능을 추가하고 프로그램에서 해당 생성자를 사용하는 것입니다.

이 예 alert 기능 My.Stringeach로서 기능하고 My.ArrayStringArray로 연장된다.

var My = (function(){ 

     // create an iframe to get a separate global scope 
     var iframe = document.createElement('iframe'); 
     iframe.style.height = '0px'; 
     iframe.style.width = '0px'; 
     iframe.style.border = 'none'; 
     iframe.style.position = 'absolute'; 
     iframe.style.left = '-99999px'; 
     document.documentElement.appendChild(iframe); 
     var My = iframe.contentWindow; 

     My.String.prototype.alert = function(){ 
     alert(this); 
     } 

     My.Array.prototype.each = function(callback){ 
     for (var i=0, l=this.length; i<l; i++) { 
      callback(this[i], i); 
     } 
     } 

     return My; 

    }()); 

다시 말하지만, 내 질문은이 방법 내가 다른 글로벌 범위를 얻을 수있는 깨끗한 방법이 있는지 알고 싶습니다 등, 내가 더 많은 정보를 찾을 수있는 위치라는 것은, 이전에 논의되었는지 여부입니다 iframe을 사용하지 않거나 가능한 경우 특정 자바 스크립트 엔진에서 어떤 이유로 든 실패하거나 다른 사람이 특히 나쁜 생각이라고 생각하면 가능합니다.


업데이트 : 나는 사람들이 iframe이 샌드 박스에서, HTML5 iframe이 샌드 박스 속성과 혼동되지 않는 이런 종류의 호출하는 것 같아요. 다른 도메인에서로드 된 내용이 다른 프레임이있는 경우

http://dean.edwards.name/weblog/2006/11/hooray/

http://webreflection.blogspot.com/2008/03/javascript-arrayobject.html

+0

가 iframe을의 합법적 인 사용이다 ... – hugomg

+0

실종 22, 현재 사용 아무것도 알 수 있습니까 이 기술? 그것은 별난 파문의 무리가있다. 그리고 그것이 사용되면 어딘가에 관해 그것에 관해 약간의 메일 링리스트 토론이 있어야한다라고 상상한다 –

+3

나는 [프리젠 테이션] (http://www.slideshare.net/benvinegar/modern-iframe-programming)을 읽는 것을 기억한다. -8281214) Disqus에서 온 남자에게서. 그들은 기본적으로 어디서나 코드를 임베드 할 수 있어야하기 때문에 이런 종류의 트릭을 사용합니다. – hugomg

답변

6

이 페이지를 다양한 브라우저 (Safari, Opera, IE7-9, Chrome, Firefox)에서 실행하고 파이어 폭스 이외의 모든 것과 일관된 결과를 얻었습니다. 파이어 폭스에서 프로토 타입은 샌드 박스 처리되었으므로 두 번째 테스트는 실패합니다 파이어 폭스에서. iframe 프로토 타입은 즉시 추가되지 않습니다. 하지만 어쨌든 그것을 늘리려는 것이 아니라면 이것은 중요하지 않습니다. 더 많은 브라우저에서 테스트 해 볼 수 있습니다.

예를 들어 (My.Array().slice은 브라우저에 따라 window 주 배열을 반환 할 것입니다.) 더 많은 오류가있을 수 있습니다. 그래서 나는 그것이 꽤 안전하지 않다고 말할 것이다.

어쨌든 과잉이며 실제 이득을 얻지 못하는 것 같습니다. 이 기술은 가장 자주 * 다음 추가 할 그 여분의 방법을 제거 *를 가져 오는 데 사용하고 있지만 깨끗한 윈도우 객체를 얻기

<!DOCTYPE html> 
<html> 
<head> 
</head> 
<body> 
<script type="text/javascript"> 
(function(){ 
    var ifr = document.createElement("iframe"), 
     callbacks = [], 
     hasReadyState = "readyState" in ifr; 

    ifr.style.display = "none"; 


    document.body.appendChild(ifr); 
    ifrDoc = ifr.contentWindow.document; 
    ifrDoc.open(); 
    ifrDoc.write("<!DOCTYPE html><html><head></head><body>"+"<"+"script"+">var w = this;"+"</"+"script"+">"+"</body></html>"); 
    ifrDoc.close(); 

    if(hasReadyState) { 

     ifr.onreadystatechange = function(){ 
      if(this.readyState === "complete") { 
       fireCallbacks(); 
      } 
     }; 

    } 

    function fireCallbacks(){ 
     var i, l = callbacks.length; 
     window.My = ifr.contentWindow.w; 

     for(i = 0; i < l; ++i) { 
      callbacks[i](); 
     } 

     callbacks.length = 0; 


    } 

    function checkReady(){ 

     if(hasReadyState && ifr.readyState === "complete") { 
     fireCallbacks(); 
     } 
     else if(!hasReadyState) { 
     fireCallbacks(); 
     } 
    } 

    window.MyReady = function(fn){ 
     if(typeof fn == "function") { 
      callbacks.push(fn); 
     } 
    }; 


window.onload = checkReady; //Change this to DOMReady or whatever 
})() 


MyReady(function(){ 

    My.Object.prototype.test = "hi"; 

    var a = new My.Object(), 
     b = new Object(); 

    console.log(Math.random(), My.Object !== Object && b.test !== "hi", a.test === "hi"); 

}); 
</script> 

</body> 
</html> 
+1

올바르게 표시하고 있습니다. 결국 iframe sandboxing 작업을하지 않기로 결정한 이유는 여러 가지입니다. –

1

, 그럼 더 현대적인 브라우저가 확실한 보안을 위해 그들 사이의 자바 스크립트 수준에서의 상호 작용을 허용하지 않습니다 : 관련

원인. 최선의 방법은 테스트를 설정하고 자신을 위해 어떤 일이 발생 하는지를 확인하는 것이지만, 대부분의 브라우저에서 설명하는 내용이 안전해야한다고 확신합니다.

+0

그래,하지만 난 맥이 없어. 정말로 나는 그것을 시험해 볼 누군가가 필요합니다. 또한 iframe을 다른 하위 도메인에서 시작한 다음 나중에 document.domain을 변경하여 가짜로 만들 수 있는지 궁금합니다. –

+0

아하 그래, 나는 맥도 없다. IE, FireFox 및 Chrome에서 사용해 보겠습니다. 그것들이 세 가지 모두를 통과한다면, 나는 당신이 가기를 좋아한다고 말하고 싶습니다. 나중에 Safari에서 테스트 할 사람을 찾을 수는 있지만 우선 순위가 우선 순위가되어야한다고 생각하지는 않습니다. 그리고 물론, 정말로 원한다면 VirtualBox에서 MacOS 인스턴스를 항상 설정할 수 있습니다. –

관련 문제