SecurityError: een frame met oorsprong geblokkeerd voor toegang tot een cross-origin frame

Ik laad een <iframe>in mijn HTML-pagina en probeer toegang te krijgen tot de elementen erin met Javascript, maar wanneer ik mijn code probeer uit te voeren, krijg ik de volgende foutmelding:

p>

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

Kun je me alsjeblieft helpen een oplossing te vinden zodat ik toegang heb tot de elementen in het frame?

Ik gebruik deze code om te testen, maar tevergeefs:

$(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!";
    });
});

Antwoord 1, autoriteit 100%

Beleid van dezelfde oorsprong

Je kunt geentoegang krijgen tot een <iframe>met een andere oorsprong met JavaScript, het zou een enorm beveiligingslek zijn als je dat zou kunnen. Voor het same-origin-beleidbrowserblokkering scripts die toegang proberen te krijgen tot een frame met een andere oorsprong.

De oorsprong wordt als verschillend beschouwd als ten minste een van de volgende delen van het adres niet wordt behouden:

protocol://hostnaam:poort/...

Protocol, hostnaam en poort moeten hetzelfde zijn van uw domein als u toegang wilt tot een frame.

OPMERKING: Het is bekend dat Internet Explorer deze regel niet strikt volgt, zie hiervoor details.

Voorbeelden

Dit is wat er zou gebeuren als je probeert toegang te krijgen tot de volgende URL’s van 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 

Tussenoplossing

Hoewel het beleid van dezelfde oorsprong scripts blokkeert van toegang tot de inhoud van sites met een andere oorsprong, als u eigenaar bent van beide pagina’s, kunt u dit probleem omzeilen met window.postMessageen de relatieve message-gebeurtenis om berichten tussen de twee pagina’s te verzenden, zoals dit:

  • Op je hoofdpagina:

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

    Het tweede argument voor postMessage()kan '*'zijn om aan te geven dat er geen voorkeur is voor de oorsprong van de bestemming. Waar mogelijk moet altijd een doelherkomst worden opgegeven, om te voorkomen dat de gegevens die u naar een andere site verzendt, openbaar worden gemaakt.

  • In uw <iframe>(op de hoofdpagina):

    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; 
        } 
    }); 
    

Deze methode kan in beide richtingenworden toegepast, door ook een luisteraar op de hoofdpagina te creëren en reacties van het frame te ontvangen. Dezelfde logica kan ook worden geïmplementeerd in pop-ups en in principe elk nieuw venster dat door de hoofdpagina wordt gegenereerd (bijvoorbeeld met behulp van window.open()) ook, zonder enig verschil.

Beleid voor dezelfde oorsprong uitschakelen in uwbrowser

Er zijn al een aantal goede antwoorden over dit onderwerp (ik vond ze net googlen), dus voor de browsers waar dit mogelijk is, zal ik het relatieve antwoord linken. Houd er echter rekening mee dat het uitschakelen van het same-origin-beleid alleen van invloed is op uwbrowser. Bovendien geeft het draaien van een browser met dezelfde-oorsprong beveiligingsinstellingen uitgeschakeld elkewebsite toegang tot bronnen van verschillende oorsprong, dus het is erg onveilig en zou NOOIT moeten worden gedaan als je niet precies weet wat je bent doen (bijv. ontwikkelingsdoeleinden).


Antwoord 2, autoriteit 6%

Als aanvulling op het antwoord van Marco Bonelli: de beste huidige manier van interactie tussen frames/iframes is het gebruik van window.postMessage, ondersteund door alle browsers


Antwoord 3, autoriteit 2%

Controleer de webserver van het domein voor http://www.<domain>.comconfiguratie voor X-Frame-Options
Het is een beveiligingsfunctie die is ontworpen om clickjacking-aanvallen te voorkomen,

Hoe werkt clickjacking?

  1. De kwaadaardige pagina lijkt precies op de slachtofferpagina.
  2. Vervolgens misleidde het gebruikers om hun gebruikersnaam en wachtwoord in te voeren.

Technisch gezien heeft het kwaad een iframemet de bron naar de slachtofferpagina.

<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>

Hoe de beveiligingsfunctie werkt

Als u wilt voorkomen dat webserververzoeken worden weergegeven binnen een iframe, voegt u de x-frame-options

X-Frame-Options DENY

De opties zijn:

  1. SAMEORIGIN //alleen toestaan dat mijn eigen domein mijn HTML in een iframe weergeeft.
  2. DENY //sta niet toe dat mijn HTML in een iframe wordt weergegeven
  3. “ALLOW-FROM https://example.com/”//laat specifiek domein renderen mijn HTML in een iframe

Dit is een IIS-configuratievoorbeeld:

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

De oplossing voor de vraag

Als de webserver de beveiligingsfunctie heeft geactiveerd, kan dit een client-side SecurityError veroorzaken zoals het hoort.


Antwoord 4, autoriteit 2%

Voor mij wilde ik een handdruk in twee richtingen implementeren, wat betekent:
– het bovenliggende venster wordt sneller geladen dan het iframe
– het iframe zou met het bovenliggende venster moeten praten zodra het klaar is
– de ouder is klaar om het iframe-bericht te ontvangen en opnieuw af te spelen

deze code wordt gebruikt om white label in het iframe in te stellen met behulp van [ Aangepaste CSS-eigenschap]
code:
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","*");
    }
});

ouder

$(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);
});

Natuurlijk kun je de oorsprong en de tekst beperken, dit is gemakkelijk te gebruiken code
ik vond dit voorbeeld nuttig:
[Cross-Domain Messaging With postMessage]


Antwoord 5

Ik wil graag een Java Spring-specifieke configuratie toevoegen die hierop van invloed kan zijn.

In de website of Gateway-toepassing is er een contentSecurityPolicy-instelling

in het voorjaar vindt u de implementatie van de WebSecurityConfigurerAdapter-subklasse

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

.referrerPolicy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN)

Browser wordt geblokkeerd als u hier geen veilige externe inhoud heeft gedefinieerd.


Antwoord 6

Als je controle hebt over de inhoud van het iframe – dat wil zeggen, als het alleen wordt geladen in een cross-origin setup zoals op Amazon Mechanical Turk – kun je dit probleem omzeilen met de <body onload='my_func(my_arg)'>attribuut voor de innerlijke html.

Voor de inner html gebruikt u bijvoorbeeld de thishtml parameter (ja – thisis gedefinieerd en verwijst naar het bovenliggende venster van het inner body-element):

<body onload='changeForm(this)'>

In de binnenste 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>

Antwoord 7

Ik heb deze fout meegemaakt bij het insluiten van een IFrame en vervolgens de site openen met dapper. De fout ging weg toen ik veranderde in “Shields Down” voor de betreffende site. Het is duidelijk dat dit geen volledige oplossing is, omdat iemand anders die de site met dappere bezoeken hetzelfde probleem zal tegenkomen. Om het daadwerkelijk op te lossen zou ik een van de andere dingen op deze pagina moeten doen. Maar ik weet tenminste waar het probleem ligt.


Antwoord 8

  • Open het startmenu
  • Type Windows + R of Open “Uitvoeren
  • voer de volgende opdracht uit.

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

Other episodes