Injection d'iframe dans une page avec une politique de sécurité de contenu restrictive

je veux créer une extension de navigateur qui crée une barre latérale. Chrome n'a pas une barre latérale de première classe, et nous devons donc à la place mettre une iframe dans la page. Cependant, cela casse sur de nombreuses pages en raison de la Politique de sécurité du contenu. Par exemple: GitHub utilise un CSP, qui ne permet pas aux iframes d'autres sites d'y être intégrées. E. g. si vous essayez de mettre la capitalone.com site web dans une iframe sur GitHub, vous obtenez le résultat suivant:

a refusé d'encadrer 'https://www.capitalone.com/ 'parce qu'il viole la directive suivante de la Politique de sécurité du contenu:" frame-src 'self' render.githubusercontent.com www.youtube.com assets.braintreegateway.com".

Voici une extension de navigateur simple pour reproduire que:

chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
  if (changeInfo.status === 'complete') {
   chrome.tabs.executeScript(tabId, { code: 'document.body.innerHTML='<iframe style="width:600px; height:600px" src="https://www.capitalone.com/"></iframe>' + document.body.innerHTML;' }, function() {
     console.log('Iframe injection complete');
   })
  }
}.bind(this));

Pourtant, selon Wikipedia, une extension de navigateur devrait pouvoir injecter une iframe malgré toute politique de sécurité de contenu:

selon le traitement CSP Modèle, [20] CSP ne doit pas interférer avec le fonctionnement des add-ons ou des extensions de navigateur installé par l'utilisateur. Cette fonctionnalité de CSP permet effectivement à tout ajout ou extension d'injecter script dans des sites web, quelle que soit l'origine de ce script, et donc d'être exempté des politiques de CSP.

y a-t-il une autre façon d'injecter une iframe en plus de ce que je fais?

35
demandé sur Manikandan C 2014-07-09 01:04:44

3 réponses

L'impossibilité d'insérer un externe iframe dans Chrome est un bug (crbug.com/408932).

Si vous souhaitez intégrer un cadre extérieur à un site web externe, alors il doit être chargé dans un cadre qui est fourni avec votre extension.

manifest.json

{
    "name": "Embed external site",
    "version": "1",
    "manifest_version": 2,
    "content_scripts": [{
        "js": ["contentscript.js"],
        "matches": ["*://*/*"],
        "all_frames": true
    }],
    "web_accessible_resources": [
        "frame.html"
    ]
}

ne pas utiliser chrome.tabs.onUpdated+ chrome.tabs.executeScript si vous voulez qu'un script de contenu soit toujours inséré dans un document. Votre implémentation est défectueuse et peut faire tourner le script plusieurs fois. temps. Au lieu de cela, vous devez déclarez le script de contenu dans le fichier de manifeste.

(supprimer "all_frames": true si vous ne voulez pas insérer le cadre dans chaque sous-image.)

contentscript.js

// Avoid recursive frame insertion...
var extensionOrigin = 'chrome-extension://' + chrome.runtime.id;
if (!location.ancestorOrigins.contains(extensionOrigin)) {
    var iframe = document.createElement('iframe');
    // Must be declared at web_accessible_resources in manifest.json
    iframe.src = chrome.runtime.getURL('frame.html');

    // Some styles for a fancy sidebar
    iframe.style.cssText = 'position:fixed;top:0;left:0;display:block;' +
                           'width:300px;height:100%;z-index:1000;';
    document.body.appendChild(iframe);
}

frame.html

<style>
html, body, iframe, h2 {
    margin: 0;
    border: 0;
    padding: 0;
    display: block;
    width: 100vw;
    height: 100vh;
    background: white;
    color: black;
}
h2 {
    height: 50px;
    font-size: 20px;
}
iframe {
    height: calc(100vh - 50px);
}
</style>
<h2>Displaying https://robwu.nl in a frame</h2>
<iframe src="https://robwu.nl/"></iframe>

Il est important d'observer que j'ai chargé un https site dans le cadre. Si vous tentez de charger un site HTTP dans le cadre, alors la Politique de contenu mixte empêchera le cadre D'être chargé si l'un des parents frames est une page https.

Remplacer https://robwu.nl/http://example.com/ et le cadre restent vides sur les pages https https://github.com. Simultanément, le message suivant sera imprimé sur la console.

[blocked] The page at 'https://github.com/' was loaded over HTTPS, but ran insecure content from 'http://example.com/': this content should also be loaded over HTTPS

57
répondu Rob W 2018-06-18 14:54:46

Rob W ' S réponse is correct. Vous pouvez suivre ce https://transitory.technologie/navigateur-extensions-et-csp-en-têtes/. J'ai réussi à le faire fonctionner dans mon extension Chrome https://github.com/onmyway133/github-chat

notez que J'utilise Chrome 59, donc je peux utiliser la plupart des fonctionnalités ES6

Déclarer dans le manifeste

"web_accessible_resources": [
  "iframe.html",
  "scripts/iframe.js"
]

créer une iframe dans la fenêtre.événement de chargement

let url    = decodeURIComponent(window.location.search.replace('?url=', ''))
let iframe = document.createElement('iframe')
iframe.src = url

iframe.id = 'github-chat-box-iframe-inner'
iframe.style.width = '100%'
iframe.style.height = '350px'
iframe.style.border = '0px'

window.onload = () => {
  document.body.appendChild(iframe)
}
3
répondu onmyway133 2017-07-28 09:57:20

votre exemple devrait fonctionner dans Chrome, mais il ne fonctionne pas actuellement à cause d'un bug:https://code.google.com/p/chromium/issues/detail?id=408932