Magazine Gadgets

Contournement du CSP avec des iframes suspendus

Publié le 14 juin 2022 par Mycamer
Gareth Heyes

Affichage des captures d'écran iframe suspendues à des chaînes

Introduction

Notre Web Security Academy a un sujet sur injection de balisage pendant – une technique d’exploitation de sites protégés par CSP. Mais quelque chose d’intéressant s’est produit lorsque nous avons mis à jour Chrome 97 – car l’un de nos laboratoires interactifs a mystérieusement cessé de fonctionner. Lorsque nous avons créé cet atelier à l’origine, Chrome empêchait les attaques basées sur le balisage en suspens en recherchant des espaces blancs bruts suivis de caractères “<" - mais oubliait d'empêcher les attributs d'arrière-plan (comme découvert par Masato Kinugawa).

Malheureusement, à partir de Chrome 97, cette technique ne fonctionnait plus, j’ai donc été chargé d’essayer de trouver une alternative. J’ai essayé de nombreux attributs différents et des animations basées sur CSS pour retarder les affectations afin d’essayer de contourner cette protection. Ils ont tous échoué – il semble que la force soit forte avec Mike Westqui est à l’origine de cette modification.

J’ai pris du recul et j’ai analysé le CSP :

default-src 'self';object-src 'none'; style-src 'self'; script-src 'self'; img-src *;

Cela semble étanche, non (à part le img-src) ? Et si je vous disais que vous pouviez supprimer la directive ‘img-src’ et continuer à mener une attaque de balisage suspendu sans un clic ? Voyons comment…

Problèmes iframe inter-domaines

J’ai d’abord allumé le Inspecteur de piratage qui est un énumérateur axé sur la sécurité que j’ai codé il y a quelque temps et j’ai commencé à disséquer le fonctionnement interne des iframes. L’inspecteur est pratique pour tester plusieurs domaines à la recherche de fuites interdomaines. j’ai ajouté le premier iframe et à l’intérieur de cette instance, j’ai ajouté un autre iframe :

<iframe name=test>

Ensuite, depuis le parent, j’ai inspecté la fenêtre inter-domaines avec l’entrée suivante :

x.contentWindow

À ma grande surprise, l’inspecteur a montré le nom de l’iframe comme “test” – que se passait-il ici ? Eh bien, l’inspecteur a quelques propriétés connues qu’il essaie – “test” étant l’une d’entre elles. Mais cela signifie alors qu’un iframe interdomaine peut découvrir l’attribut de nom d’iframe. J’ai fait quelques tests et il semble que vous ne puissiez pas énumérer l’iframe pour le nom du cadre, mais vous pouvez utiliser typeof pour déterminer si le nom existe ou non. Par exemple, vous pouvez poser des questions oui/non sur l’attribut name de n’importe quel iframe interdomaine :

if(typeof x.contentWindow.myWinName === 'object') {
  //window name exists
} else {
  //window name doesn't exist
}

C’est bien, mais cela ne m’aide pas vraiment à contourner le CSP; ça ne sert à rien d’essayer de forcer brutalement un Jeton CSRF poser des questions oui/non. En inspectant diverses propriétés de l’iframe inter-domaines, j’ai essayé de changer les valeurs – en changeant l’emplacement de l’iframe en about:blank. À ma grande surprise, même s’il s’agissait de plusieurs domaines, Chrome l’autorisait :

x.contentWindow[0].location='about:blank'

Non seulement cela, mais la fenêtre complète a pu être énumérée, et j’ai pu accéder location.ancesterOrigins – qui a divulgué un domaine externe. Mais ce qui m’intéressait vraiment, c’était le window.name et s’il pouvait être lu. Effectivement, le nom de la fenêtre était lisible et inscriptible – et vous pouviez même exécuter JavaScript quel que soit le CSP de la page parent. Ce qui semble se produire, c’est que lorsque vous l’attribuez à about:blank, la propriété de l’iframe passe au domaine qui l’a définie.

Enfin, voici l’exploit qui a résolu le laboratoire :

<script>
function cspBypass(win) {
  win[0].location = 'about:blank';
  setTimeout(()=>alert(win[0].name), 500);
}
</script>
<iframe src="https://subdomain1.portswigger-labs.net/bypassing-csp-with-dangling-iframes/target.php?email=%22><iframe name=%27" onload="cspBypass(this.contentWindow)"></iframe>

Preuve de concept

Conclusion

CSP traite les URL about:blank comme la même origine – cependant, lorsqu’un attaquant définit un iframe interdomaine sur about:blank, il devient lisible par un attaquant et n’a certainement pas la même origine. Les atténuations de Chrome pour les attaques de balisage pendantes empêchent certaines attaques, mais en abusant des bizarreries du navigateur, il est possible de contourner ces atténuations et d’accéder aux informations inter-domaines via une injection – même avec JavaScript désactivé dans votre CSP.

Chronologie

2022-02-10 08:55 GMT – Bug signalé à Google
2022-02-10 09:38 GMT – Signalé à Mozilla
2022-06-14 15:00 GMT – Publié ce message

Retour à tous les articles



— to portswigger.net


Retour à La Une de Logo Paperblog

A propos de l’auteur


Mycamer Voir son profil
Voir son blog

l'auteur n'a pas encore renseigné son compte l'auteur n'a pas encore renseigné son compte

Magazines