SecurityError: क्रॉस-ऑरिजिनल फ्रेम को एक्सेस करने से उत्पत्ति के साथ एक फ्रेम को ब्लॉक किया गया


555

मैं <iframe>अपने 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!";
    });
});

जवाबों:


818

समान-मूल नीति

यदि आप जावास्क्रिप्ट का उपयोग करते हुए विभिन्न मूल के साथ प्रवेश नहीं कर सकते हैं<iframe> , तो यह एक बड़ी सुरक्षा दोष होगा यदि आप इसे कर सकते हैं। के लिए एक ही मूल नीति ब्राउज़रों स्क्रिप्ट एक अलग मूल के साथ एक फ्रेम पर पहुँचने का प्रयास ब्लॉक

मूल को अलग माना जाता है यदि पते के निम्न भागों में से कम से कम एक को बनाए नहीं रखा जाता है:

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

यदि आप किसी फ़्रेम तक पहुँचना चाहते हैं, तो प्रोटोकॉल , होस्टनाम और पोर्ट आपके डोमेन के समान होने चाहिए।

नोट: इंटरनेट एक्सप्लोरर को इस नियम का कड़ाई से पालन नहीं करने के लिए जाना जाता है, विवरण के लिए यहां देखें।

उदाहरण

यहां बताया गया है कि निम्न 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()) के द्वारा उत्पन्न किसी भी नई विंडो को बिना किसी अंतर के लागू किया जा सकता है।

अपने ब्राउज़र में समान-मूल नीति अक्षम करना

इस विषय के बारे में पहले से ही कुछ अच्छे उत्तर हैं (मैंने अभी उन्हें खोजा है), इसलिए, उन ब्राउज़र के लिए जहां यह संभव है, मैं सापेक्ष उत्तर को लिंक करूंगा। हालाँकि, कृपया याद रखें कि समान-मूल नीति को अक्षम करना केवल आपके ब्राउज़र को प्रभावित करेगा । इसके अलावा, समान-मूल सुरक्षा सेटिंग्स के साथ एक ब्राउज़र चलाने से कोई भी वेबसाइट क्रॉस-ऑरिजनल संसाधनों तक पहुँच को अक्षम कर देती है , इसलिए यह बहुत असुरक्षित है और अगर आपको पता नहीं है कि आप वास्तव में क्या कर रहे हैं (जैसे विकास के उद्देश्य)


27
1 , 2 , मैंने जो भी उत्तर पाया है , वह बताता है कि CORS / Access-Control-Allow-Originकेवल IHR केcanvas.drawImage लिए लागू नहीं होता है, केवल XHRs, फ़ॉन्ट्स, WebGL और । मेरा मानना postMessageहै कि एकमात्र विकल्प है।
स्नैपी

369
पहली बार मैंने जावास्क्रिप्ट में "~" ऑपरेटर को देखा है। किसी और के लिए, जो यह नहीं जानता था कि यह क्या करता है: यह -1 को 0 में परिवर्तित करता है, जो आपको इंडेक्सऑफ के परिणाम पर "! = -1" होने से बचाता है। व्यक्तिगत रूप से, मुझे लगता है कि मैं "! = -1" का उपयोग करूंगा क्योंकि अन्य प्रोग्रामर को समझना और उन बग से बचना आसान है जो टिल्ड को डालने से भूल जाएंगे। (लेकिन कुछ नया सीखना हमेशा अच्छा होता है।)
Redzarf

4
@SabaAhang बस के लिए जाँच करें iframe.src, और यदि यह साइट आपके डोमेन के होस्टनाम से अलग है तो आप उस फ्रेम तक नहीं पहुँच सकते।
मार्को बोनेली

17
@ साइनसॉग्स पूरी तरह से गलत है, ~संख्या के 2 के पूरक को लौटाता है, इसलिए nबन जाता है -n-1, जिसका अर्थ है कि केवल -1बन जाएगा 0(जिसकी व्याख्या की गई है false), और कोई अन्य मान परीक्षण पास करेगा। IE 0 = -(-1)-1, नहीं -(-1+1)
मार्को बोनेली

2
@ user2568374 location.ancestorOrigins[0]मूल फ्रेम का स्थान है। यदि आपका फ्रेम किसी अन्य साइट के अंदर चल रहा है और आप जाँच कर उपयोग event.origin.indexOf(location.ancestorOrigins[0])कर रहे हैं कि क्या घटना के मूल में माता-पिता का फ़्रेम पता है, जो हमेशा रहने वाला हैtrue , इसलिए आप किसी भी मूल के साथ किसी भी माता-पिता को आपके फ़्रेम तक पहुँचने की अनुमति दे रहे हैं , और यह जाहिर है कुछ आप करना चाहते हैं नहीं है। इसके अलावा, document.referrerबुरा अभ्यास भी है, जैसा कि मैंने पहले ही ऊपर टिप्पणियों में समझाया था।
मार्को बोनेली

55

पारितोषिक मार्को Bonelli के जवाब: के बीच फ्रेम / iframes बातचीत उपयोग कर रहा है का सबसे अच्छा वर्तमान तरीका window.postMessage, सभी ब्राउज़र द्वारा समर्थित


21
हालांकि यह लिंक प्रश्न का उत्तर दे सकता है, लेकिन उत्तर के आवश्यक भागों को शामिल करना और संदर्भ के लिए लिंक प्रदान करना बेहतर है। लिंक-केवल उत्तर अमान्य हो सकते हैं यदि लिंक किए गए पृष्ठ बदल जाते हैं। - समीक्षा से
एलेसेंड्रो कटिन

9
मैं असहमत हूं, @AlessandroCuttin। यह बताते हुए कि कैसे window.postMessageकाम करता है केवल स्वीकृत उत्तर की नकल करेगा जो मैं पहले ही संदर्भित करता हूं। इसके अलावा, मेरे जवाब में जो आवश्यक मूल्य है वह बाहरी दस्तावेज को संदर्भित करने के लिए ठीक है।
गीर्ट

5
मुझे लगता है कि यह एक बेहतर है यदि आप स्वीकार किए गए उत्तर को संपादित कर सकते हैं और इसे वहां जोड़ सकते हैं
मार्टिन मासेरा

12
window.postMessage हम केवल तभी उपयोग कर सकते हैं जब हम माता-पिता (हमारे HTML पेज) और बच्चों के तत्व (अन्य डोमेन iframe) तक पहुँचने में सक्षम हो सकते हैं। अन्यथा "कोई भी समस्या नहीं है", यह हमेशा एक त्रुटि "अनियोजित DOMException:" को एक फ्रेम में अवरुद्ध करता है। मूल के साथ "< yourdomainname.com >" क्रॉस-ऑरिजनल फ्रेम तक पहुँचने से।
VIJAY P

18

http://www.<domain>.comकॉन्फ़िगरेशन के लिए डोमेन के वेब सर्वर की जाँच करें X-Frame-Options यह एक सुरक्षा सुविधा है जिसे क्लिकजैकिंग हमलों को रोकने के लिए डिज़ाइन किया गया है,

ClickJack कैसे काम करता है?

  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>

सुरक्षा सुविधा कैसे काम करती है

यदि आप वेब सर्वर अनुरोध को एक एक्स-फ्रेम-विकल्पiframe जोड़ने के भीतर प्रदान करने से रोकना चाहते हैं

एक्स-फ्रेम-विकल्प DENY

विकल्प हैं:

  1. SAMEORIGIN // केवल मेरे स्वयं के डोमेन को एक iframe के अंदर मेरे HTML को प्रस्तुत करने की अनुमति देता है।
  2. इनकार // मेरे HTML को किसी भी iframe के अंदर प्रदान करने की अनुमति न दें
  3. "ALLOW-FROM https://example.com/ " // विशिष्ट डोमेन को मेरे HTML को iframe के अंदर रेंडर करने की अनुमति देता है

यह IIS कॉन्फ़िग उदाहरण है:

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

सवाल का हल

यदि वेब सर्वर ने सुरक्षा सुविधा को सक्रिय किया है तो यह क्लाइंट-साइड SecurityError का कारण बन सकता है।


1
मुझे नहीं लगता कि एक्स-फ्रेम-ऑप्शंस यहां लागू होते हैं - एक्स-फ्रेम-ऑप्शंस गेस्ट (एंबेडेड) पेज द्वारा परिभाषित होते हैं, जिससे अभिभावक पेज लोड करने से मना कर सकते हैं, लेकिन जहां तक ​​मुझे पता है कि यह जावास्क्रिप्ट को प्रभावित नहीं करता है पहुंच - एक्स-फ्रेम-ऑप्शंस के साथ भी: *, मुझे नहीं लगता कि आप जावास्क्रिप्ट के साथ एक अलग मूल अतिथि पृष्ठ के डोम का उपयोग कर पाएंगे
नूह गिलमोर

13

मेरे लिए मैं एक 2-रास्ता हैंडशेक लागू करना चाहता था, जिसका अर्थ है:
- मूल विंडो तेजी से लोड होगी, तो iframe
- iframe को तैयार होते ही मूल विंडो से बात करनी चाहिए
- माता-पिता iframe संदेश प्राप्त करने के लिए तैयार है और फिर से खेलना

इस कोड का उपयोग iframe में सफेद लेबल सेट करने के लिए किया जाता है [CSS custom property]
कोड:
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);
});

स्वाभाविक रूप से आप मूल और पाठ को सीमित कर सकते हैं, यह आसान-से-काम वाला कोड है जिसमें
मैंने इस परीक्षा को मददगार पाया:
[क्रॉस-डोमेन मैसेजिंग विद पोस्टमेज़ेज]


मैं सफारी के साथ एक मुद्दे पर काम कर रहा हूं, जहां iframe में दस्तावेज़ मूल पृष्ठ की तुलना में बाद में अपने जेएस को निष्पादित कर रहा है, जो संदेश को iframe में दस्तावेज़ की तुलना में पहले भेजे जाने वाले संदेशों को सुन रहा है; जो क्रोम और फायरफॉक्स से बिल्कुल विपरीत है - क्या आपने आईओएस पर सफारी में अपने कोड का परीक्षण किया है? मान के दूसरे पैरामीटर के साथ btw पोस्टमैसेज "*" काफी सुरक्षित नहीं है, आपको हमेशा डोमेन निर्दिष्ट करना चाहिए
sKopheK

आपके कोड का पहला ब्लॉक, यह है कि अभिभावक में iframe पर है या यह पृष्ठ पर है जो iframe में लोड हो जाता है?
Demonic218

0

मैं जावा स्प्रिंग विशिष्ट कॉन्फ़िगरेशन जोड़ना चाहूंगा जो इस पर प्रभाव डाल सकता है।

वेब साइट या गेटवे एप्लिकेशन में एक सामग्री हैसुरक्षापॉलिश सेटिंग

वसंत में आप 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)

यदि आपने यहां सुरक्षित बाहरी कंटेस्टेंट को परिभाषित नहीं किया है तो ब्राउज़र को ब्लॉक कर दिया जाएगा।


0

यदि आपके पास iframe की सामग्री पर नियंत्रण है - अर्थात्, यदि यह केवल क्रॉस-ऑरिजिनल सेटअप में भरी हुई है जैसे कि Amazon मैकेनिकल तुर्क - तो आप इस समस्या <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>

-24
  • स्टार्ट मेन्यू खोलें
  • विंडोज़ + आर टाइप करें या खोलें "रन
  • निम्न आदेश निष्पादित करें।

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


3
त्वरित और गंदे परीक्षण के लिए अच्छा है!
user1068352

6
किसी भी चीज़ के लिए भयानक जो एक त्वरित और गंदा परीक्षण नहीं है ... और पहले से ही स्वीकृत उत्तर में पता है।
क्वेंटिन

2
कमांड के साथ भी, यह काम नहीं करता है क्योंकि क्रोम इस तरह से वेब सुरक्षा को अक्षम करने से बचता है
Metafaniel
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.