{"id":357,"date":"2018-06-06T00:14:20","date_gmt":"2018-06-06T00:14:20","guid":{"rendered":"https:\/\/www.wpvs.de\/iot-2018\/?p=357"},"modified":"2021-05-14T10:07:05","modified_gmt":"2021-05-14T08:07:05","slug":"raspberrybuy-4-cors-und-csrf-attacken","status":"publish","type":"post","link":"https:\/\/www.iot-embedded.de\/iot-2018\/projekt-raspberrybuy\/raspberrybuy-4-cors-und-csrf-attacken\/","title":{"rendered":"RaspberryBuy (4): CORS und CSRF Attacken"},"content":{"rendered":"<p>Bevor mit dem eigentlichen Thema dieses Blog-Eintrages begonnen wird, noch kurz eine Anmerkung zu der Buildroot-Vorlage &#8222;dhbw_html_defconfig&#8220;. Diese hat bei uns nicht direkt funktioniert. Beim Starten des Browsers erschien die Warnung, dass der Prozess keine Berechtigung hat, auf verschiedene Eingabeger\u00e4te wie Maus und Tastatur zuzugreifen. Aus diesem Grund wurden folgende Zeilen in die Inittab Datei eingef\u00fcgt:<\/p>\n<blockquote><p>#change input access permissions<br \/>\n::sysinit:\/bin\/chmod 0666 \/dev\/input\/event0<br \/>\n::sysinit:\/bin\/chmod 0666 \/dev\/input\/event1<br \/>\n::sysinit:\/bin\/chmod 0666 \/dev\/input\/event2<\/p><\/blockquote>\n<p>Diese bewirken, dass alle Prozesse schreibend und lesend auf die Ger\u00e4te zugreifen d\u00fcrfen.<\/p>\n<h2>Was ist CORS?<\/h2>\n<p>Cross-Origin Resource Sharing (CORS) bezeichnet einen Mechanismus, mithilfe dessen Webseiten, die \u00fcber einen Browser aufgerufen werden, auf Ressourcen (=HTTP Request) anderer Domains (=Origin) zugreifen k\u00f6nnen. Eine Origin wird dabei eindeutig durch die drei Attribute Domain, Protokoll und Port definiert. Aufgrund der damit einhergehenden Sicherheitsl\u00fccken blockieren Browser die meisten Cross-Origin Request. Mithilfe von speziellen HTTP Headern kann das CORS Verhalten einer Webseite gesteuert werden.<\/p>\n<p>HTTP-Anfragen werden im Kontext von CORS in zwei Gruppen eingeteilt:<\/p>\n<ol>\n<li>Simple Anfragen: Dies sind HTTP Requests, von denen nicht erwartet wird, dass sie gespeicherte Daten beeinflussen. Nur die HTTP Verben GET, HEAD und POST sind erlaubt. Des Weiteren sind nur bestimmte HTTP Header erlaubt. Eine weitere Einschr\u00e4nkung betrifft den Content-Type Header, dieser darf nur\u00a0<code>application\/x-www-form-urlencoded<\/code>,<code>multipart\/form-data<\/code> oder <code>text\/plain<\/code> sein.<br \/>\nDer Browser f\u00fchrt den Request ohne weitere vorherige Pr\u00fcfungen aus. Falls es ein CORS Request ist, wird der HTTP Header <code>Access-Control-Allow-Origin<\/code> der Antwort \u00fcberpr\u00fcft. Falls dieser die aktuelle Domain beinhaltet oder <code>*<\/code> entspricht, gibt der Browser die Antwort an die Webseite weiter, da dies bedeutet, dass der Server die CORS-Anfrage zul\u00e4sst.<\/li>\n<li>Bei allen anderen Requests f\u00fchrt der Browser vorher eine Pr\u00fcfung durch. W\u00fcrde die Anfrage direkt ausgef\u00fchrt werden, w\u00fcrde der Server eventuell Daten \u00e4ndern, noch bevor CORS-Header an den Browser zur\u00fcckgesendet werden.<br \/>\nDer Browser sendet dann einen sogenannten &#8222;Preflight&#8220;-Request. Dazu wird das OPTIONS Verb verwendet. Der Browser fragt damit beim Server nach, ob ein CORS-Request f\u00fcr diesen Origin, den angegebenen Pfad und das angegebene HTTP-Verb zul\u00e4ssig ist. Erst wenn der Server dies best\u00e4tigt, wird die eigentliche Anfrage ausgef\u00fchrt.<\/li>\n<\/ol>\n<p>Bez\u00fcglich der Authentifizierung bei HTTP-Requests ist anzumerken, dass bei (nicht-simplen) CORS-Requests der Browser standardm\u00e4\u00dfig keine Cookies und Authentifizierungs-Informationen sendet. Dies muss explizit erw\u00fcnscht werden. Des Weiteren muss der Server mithilfe des Headers <code>Access-Control-Allow-Credentials<\/code> explizit das Empfangen von Authentifizierungsdaten erlauben.<\/p>\n<p>Quelle:\u00a0<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/CORS\">https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/CORS<\/a><\/p>\n<h2><\/h2>\n<h2>Projekt Setup<\/h2>\n<p>In der Produktivumgebung unserer Anwendung ist kein CORS notwendig, da alle Anfragen an den gleichen Server gehen (Statische Dateien und API). In der Entwicklungsumgebung sieht das anders aus. Der Server ist \u00fcber eine registrierte Domain erreichbar, w\u00e4hrend die Entwickler des Frontends einen lokalen Webserver benutzen, um ihren Code zu testen. Der Browser w\u00fcrde diese CORS-Anfrage standardm\u00e4\u00dfig blockieren, da keine CORS-Header gesendet werden. Aufgrund der Verwendung verschiedener HTTP Verben und dem JSON Content Type werden Preflight Requests durchgef\u00fchrt. Folgende \u00c4nderungen waren notwendig, dass die Entwickler die Anwendung sinnvoll testen k\u00f6nnen:<\/p>\n<ul>\n<li>CORS-Requests serverseitig erlauben, jedoch nur im Test-Modus (Siehe Code unten). Als Origin wird der von der WebStorm IDE standardm\u00e4\u00dfig aufgesetzte Web Server verwendet, des Weiteren m\u00fcssen Cookies explizit erlaubt werden.<\/li>\n<li>Beim Versender der HTTP-Requests muss explizit angegeben werden, dass vorhandene Cookies gesendet werden sollen. (Bei der Verwendung der <a href=\"https:\/\/github.com\/axios\/axios\">AXIOS<\/a> Bibliothek: withCredentials Option)<\/li>\n<\/ul>\n<blockquote><p>if (testMode) {<br \/>\nconst corsOptions = {<br \/>\norigin: &#8218;http:\/\/localhost:63342&#8216;, \/\/ WebStorm default test web server<br \/>\ncredentials: true<br \/>\n};<\/p>\n<p>this.express.use(cors(corsOptions));<br \/>\n}<\/p><\/blockquote>\n<p>&nbsp;<\/p>\n<h2>CSRF Attacken<\/h2>\n<p>Cross-Site Request Forgery (CSRF) Angriffe nutzen Schwachstellen in der CORS-Konfiguration, um durch das Ausnutzen bestehender Sessions Daten zu erhalten beziehungsweise zu manipulieren. Ein m\u00f6glicher Ablauf sieht wie folgt aus:<\/p>\n<ol>\n<li>Ein Nutzer meldet sich bei einer Online-Banking Anwendung im Browser an<\/li>\n<li>Der Nutzer \u00f6ffnet in einem zweiten Browser-Tab eine Webseite, die Schadsoftware enth\u00e4lt. Diese l\u00f6st bspw. mit einer HTML-Form eine simple HTTP-Request an die Online-Banking Webseite aus (d.h. kein Preflight Request). Der Browser sendet dabei die Login-Cookies mit, sodass aus Serversicht die Anfrage zul\u00e4ssig ist.<\/li>\n<li>Die Anfrage l\u00f6st eine \u00dcberweisung aus. Da der Server kein CORS erlaubt, blockiert der Browser die Weitergabe der Antwort an die Webseite. Dies ist aber egal, da die \u00dcberweisung bereits get\u00e4tigt wurde.<\/li>\n<\/ol>\n<p>Eine M\u00f6glichkeit, eine Webseite dagegen zu sch\u00fctzen, besteht in der Nutzung von speziellen CSRF Tokens. Diese erh\u00e4lt der Sender der Anfrage bspw. \u00fcber ein HTTP-Response Header. Bei jeder nicht-simplen Anfrage muss das Token mitgegeben werden, damit die Anfrage ausgef\u00fchrt werden kann. Andere Webseiten haben bei richtiger CORS-Konfiguration keine M\u00f6glichkeit, dieses Token zu bekommen.<\/p>\n<h2>Auswirkungen auf unser Projekt<\/h2>\n<p>F\u00fcr unser Projekt haben wir evaluiert, inwiefern wir uns gegen CSRF Attacken sch\u00fctzen m\u00fcssen. Durch das Deaktivieren von CORS und simplen Requests (JSON Content Type &#8211;&gt; immer Preflight Request) ist die Anwendung bereits ausreichend gegen CSRF Attacken gesch\u00fctzt. Es sind, im Gegensatz zum urspr\u00fcnglichen Plan, keine CSRF Tokens notwendig.<\/p>\n<p>Quelle:\u00a0<a href=\"https:\/\/github.com\/pillarjs\/understanding-csrf\">https:\/\/github.com\/pillarjs\/understanding-csrf<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Bevor mit dem eigentlichen Thema dieses Blog-Eintrages begonnen wird, noch kurz eine Anmerkung zu der Buildroot-Vorlage &#8222;dhbw_html_defconfig&#8220;. Diese hat bei uns nicht direkt funktioniert. Beim Starten des Browsers erschien die Warnung, dass der Prozess keine Berechtigung hat, auf verschiedene Eingabeger\u00e4te<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[4],"tags":[],"_links":{"self":[{"href":"https:\/\/www.iot-embedded.de\/iot-2018\/wp-json\/wp\/v2\/posts\/357"}],"collection":[{"href":"https:\/\/www.iot-embedded.de\/iot-2018\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.iot-embedded.de\/iot-2018\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.iot-embedded.de\/iot-2018\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.iot-embedded.de\/iot-2018\/wp-json\/wp\/v2\/comments?post=357"}],"version-history":[{"count":1,"href":"https:\/\/www.iot-embedded.de\/iot-2018\/wp-json\/wp\/v2\/posts\/357\/revisions"}],"predecessor-version":[{"id":648,"href":"https:\/\/www.iot-embedded.de\/iot-2018\/wp-json\/wp\/v2\/posts\/357\/revisions\/648"}],"wp:attachment":[{"href":"https:\/\/www.iot-embedded.de\/iot-2018\/wp-json\/wp\/v2\/media?parent=357"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.iot-embedded.de\/iot-2018\/wp-json\/wp\/v2\/categories?post=357"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.iot-embedded.de\/iot-2018\/wp-json\/wp\/v2\/tags?post=357"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}