[javascript] SecurityError : 출처가있는 프레임이 교차 출처 프레임에 액세스하지 못하도록 차단

<iframe>HTML 페이지에서를 로드하고 Javascript를 사용하여 HTML 내의 요소에 액세스하려고하지만 코드를 실행하려고하면 다음 오류가 발생합니다.

SecurityError: Blocked a frame with origin "http://www.<domain>.com" from accessing a cross-origin frame.

프레임의 요소에 액세스 할 수 있도록 솔루션을 찾도록 도와 줄 수 있습니까?

테스트 에이 코드를 사용하고 있지만 헛된 것입니다.

$(document).ready(function() {
    var iframeWindow = document.getElementById("my-iframe-id").contentWindow;

    iframeWindow.addEventListener("load", function() {
        var doc = iframe.contentDocument || iframe.contentWindow.document;
        var target = doc.getElementById("my-target-id");

        target.innerHTML = "Found it!";
    });
});



답변

동일 출처 정책

JavaScript를 사용하여 다른 출처로 액세스 는 없습니다. 가능한 <iframe>경우 큰 보안 결함이 될 수 있습니다. 를 들어 동일 출처 정책 브라우저는 스크립트를 다른 원점 프레임에 액세스하려고 차단 .

주소의 다음 부분 중 하나 이상이 유지되지 않으면 출발지가 다른 것으로 간주됩니다.

<protocol>://<hostname>:<port>/...

프레임에 액세스하려면 프로토콜 , 호스트 이름포트 가 도메인과 같아야합니다.

참고 : Internet Explorer는이 규칙을 엄격하게 따르지 않는 것으로 알려져 있습니다 . 자세한 내용 은 여기 를 참조하십시오.

다음에서 다음 URL에 액세스하려고하면 어떻게됩니까? http://www.example.com/home/index.html

URL                                             RESULT
http://www.example.com/home/other.html       -> Success
http://www.example.com/dir/inner/another.php -> Success
http://www.example.com:80                    -> Success (default port for HTTP)
http://www.example.com:2251                  -> Failure: different port
http://data.example.com/dir/other.html       -> Failure: different hostname
https://www.example.com/home/index.html:80   -> Failure: different protocol
ftp://www.example.com:21                     -> Failure: different protocol & port
https://google.com/search?q=james+bond       -> Failure: different protocol, port & hostname 

해결 방법

동일한 출처 정책으로 인해 스크립트가 다른 출처를 가진 사이트의 컨텐츠에 액세스하는 것을 차단하더라도 두 페이지를 모두 소유 한 경우 다음window.postMessagemessage 과 같이 두 페이지간에 메시지를 보내기 위해 관련 이벤트사용하여이 문제를 해결할 수 있습니다 .

  • 메인 페이지에서 :

    let frame = document.getElementById('your-frame-id');
    frame.contentWindow.postMessage(/*any variable or object here*/, 'http://your-second-site.com');

    두 번째 인수는 할 postMessage()수 있습니다 '*'대상의 기원에 대한 더 선호를 나타 내기 위해. 다른 사이트로 보내는 데이터를 공개하지 않으려면 가능한 한 항상 목표 출처를 제공해야합니다.

  • 귀하의 <iframe>(메인 페이지에 포함) :

    window.addEventListener('message', event => {
        // IMPORTANT: check the origin of the data! 
        if (event.origin.startsWith('http://your-first-site.com')) {
            // The data was sent from your site.
            // Data sent with postMessage is stored in event.data:
            console.log(event.data);
        } else {
            // The data was NOT sent from your site! 
            // Be careful! Do not use it. This else branch is
            // here just for clarity, you usually shouldn't need it.
            return;
        }
    }); 

이 메소드는 양방향으로 적용되어 메인 페이지에도 리스너를 생성하고 프레임에서 응답을 수신 할 수 있습니다 . 동일한 논리를 팝업과 기본적으로 메인 페이지에 의해 생성 된 (예 :를 사용하여 window.open()) 새 창에서도 구현할 수 있습니다 .

에 동일 출처 정책을 비활성화 하여 브라우저

이미이 주제에 대한 좋은 답변이 있습니다 (방금 찾은 인터넷 검색).이 가능한 브라우저의 경우 상대 답변을 연결합니다. 그러나 기억하십시오 동일 출처 정책을 해제하는 경우에만 영향을 미칠 것이다 당신의 브라우저를 . 또한 동일한 출처 보안 설정을 사용하지 않는 브라우저를 실행하면 모든 웹 사이트에 출처 간 리소스에 대한 액세스 권한이 부여 되므로 매우 안전하지 않으므로 수행중인 작업을 정확히 모르는 경우 (예 : 개발 목적) 수행해서는 안됩니다 .


답변

마르코 보 넬리 (Marco Bonelli)의 답변 보완 : 프레임 / iframe 사이에서 상호 작용하는 가장 좋은 최신 방법은 모든 브라우저window.postMessage 에서 지원하는입니다.


답변

도메인 웹 서버의 http://www.<domain>.com구성을 확인하십시오. X-Frame-Options
클릭 재킹 공격을 방지하도록 설계된 보안 기능입니다.

clickJacking은 어떻게 작동합니까?

  1. 사악한 페이지는 희생자 페이지와 똑같습니다.
  2. 그런 다음 사용자가 자신의 사용자 이름과 비밀번호를 입력하도록 속였습니다.

기술적으로 악은 iframe희생자 페이지의 출처와 관련이 있습니다.

<html>
    <iframe src='victim_domain.com'/>
    <input id="username" type="text" style="display: none;/>
    <input id="password" type="text" style="display: none;/>
    <script>
        //some JS code that click jacking the user username and input from inside the iframe...
    <script/>
<html>

보안 기능 작동 방법

x-frame-options를iframe 추가하여 웹 서버 요청이 렌더링되는 것을 방지 하려면

X- 프레임 옵션 거부

옵션은 다음과 같습니다.

  1. SAMEORIGIN // 내 도메인에만 허용하여 HTML을 iframe 안에 렌더링합니다.
  2. 거부 // iframe 내에서 HTML을 렌더링 할 수 없음
  3. “ALLOW-FROM https://example.com/”// 특정 도메인이 iframe 내에서 HTML을 렌더링하도록 허용

이것은 IIS 구성 예입니다.

   <httpProtocol>
       <customHeaders>
           <add name="X-Frame-Options" value="SAMEORIGIN" />
       </customHeaders>
   </httpProtocol>

질문에 대한 해결책

웹 서버가 보안 기능을 활성화 한 경우 클라이언트 측 SecurityError가 발생할 수 있습니다.


답변

나를 위해 2-way 핸드 셰이크를 구현하고 싶었습니다
.- 부모 창이 iframe보다 빠르게로드됩니다
-iframe이 준비되는 즉시 부모 창과 대화해야합니다
-부모가 iframe 메시지를 수신하고 재생할 준비가되었습니다.

이 코드는 [CSS 사용자 정의 속성]
코드를 사용하여 iframe에서 화이트 라벨을 설정하는 데 사용됩니다 .
iframe

$(function() {
    window.onload = function() {
        // create listener
        function receiveMessage(e) {
            document.documentElement.style.setProperty('--header_bg', e.data.wl.header_bg);
            document.documentElement.style.setProperty('--header_text', e.data.wl.header_text);
            document.documentElement.style.setProperty('--button_bg', e.data.wl.button_bg);
            //alert(e.data.data.header_bg);
        }
        window.addEventListener('message', receiveMessage);
        // call parent
        parent.postMessage("GetWhiteLabel","*");
    }
});

부모의

$(function() {
    // create listener
    var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
    var eventer = window[eventMethod];
    var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
    eventer(messageEvent, function (e) {
        // replay to child (iframe) 
        document.getElementById('wrapper-iframe').contentWindow.postMessage(
            {
                event_id: 'white_label_message',
                wl: {
                    header_bg: $('#Header').css('background-color'),
                    header_text: $('#Header .HoverMenu a').css('color'),
                    button_bg: $('#Header .HoverMenu a').css('background-color')
                }
            },
            '*'
        );
    }, false);
});

당연히 당신은 원점과 텍스트를 제한 할 수 있습니다. 이것은 작업하기 쉬운 코드입니다.
이 examlpe가 도움이된다는 것을 알게되었습니다
.


답변

이에 영향을 줄 수있는 Java Spring 특정 구성을 추가하고 싶습니다.

웹 사이트 또는 게이트웨이 애플리케이션에는 contentSecurityPolicy 설정이 있습니다.

Spring에서는 WebSecurityConfigurerAdapter 하위 클래스의 구현을 찾을 수 있습니다

contentSecurityPolicy("
script-src 'self' [URLDomain]/scripts ;
style-src 'self' [URLDomain]/styles;
frame-src 'self' [URLDomain]/frameUrl...

.referrerPolicy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN)

안전한 외부 연결을 정의하지 않으면 브라우저가 차단됩니다.


답변

iframe의 컨텐츠를 제어 할 수있는 경우 (즉, Amazon Mechanical Turk와 같은 교차 출처 설정에만로드 된 <body onload='my_func(my_arg)'>경우) 내부 HTML 의 속성 으로이 문제를 피할 수 있습니다 .

예를 들어, 내부 HTML의 경우 thishtml 매개 변수를 사용하십시오 (예- this정의되고 내부 본문 요소의 상위 창을 나타냄).

<body onload='changeForm(this)'>

내부 HTML에서 :

    function changeForm(window) {
        console.log('inner window loaded: do whatever you want with the inner html');
        window.document.getElementById('mturk_form').style.display = 'none';
    </script>


답변

  • 시작 메뉴를 엽니 다
  • windows + R을 입력하거나 “실행
  • 다음 명령을 실행하십시오.

chrome.exe --user-data-dir="C://Chrome dev session" --disable-web-security