{"id":1665,"date":"2017-02-15T22:28:11","date_gmt":"2017-02-15T21:28:11","guid":{"rendered":"http:\/\/blog.benny-baumann.de\/?p=1665"},"modified":"2017-02-15T22:35:31","modified_gmt":"2017-02-15T21:35:31","slug":"responsible-disclosure-in-der-praxis","status":"publish","type":"post","link":"https:\/\/blog.benny-baumann.de\/?p=1665","title":{"rendered":"Responsible Disclosure in der Praxis"},"content":{"rendered":"<p>Software-Sicherheit ist ein schwieriges Thema: Nicht nur, weil es trotz zahlreicher Ma\u00dfnahmen zur Fehlervermeidung nahezu unm\u00f6glich ist, komplett fehlerfreie Software zu schreiben, sondern auch, weil das Beheben eines Fehlers dessen Gefahrenpotential extrem steigern kann. Im Umfeld von OpenSource-Software haben sich daher verschiedene Vorgehensweisen zum Umgang mit gemeldeten Fehlern etabliert, die von Full Disclosure, \u00fcber Responsible Disclosure bis hin zu Irresponsible Disclosure reichen. Einen Vertreter der letzteren Kategorie m\u00f6chte ich heute einmal vorstellen, da in diesem Fall einige Dinge zwar richtig angegangen wurden, in ihrer Umsetzung aber eine unn\u00f6tige Gef\u00e4hrdung der Nutzer resultierte.<!--more--><\/p>\n<p>Angefangen hat die hier beispielhaft dargestellte Episode vor etwa einem Monat, mit einem <a href=\"https:\/\/twitter.com\/nomoketo\/status\/824335449598623744\">Tweet von nomoketo<\/a> mit der Frage f\u00fcr einen Kontakt zum Reporten eines Sicherheitsproblems, der korrekt nicht-\u00f6ffentlich bearbeitet wurde. Soweit recht normal und wenig spannend. Was mich auf die Sache aufmerksam machte, war ein <a href=\"https:\/\/twitter.com\/nomoketo\/status\/824353274228854794\">weiterer Kommentar<\/a> mit <a href=\"https:\/\/twitter.com\/nomoketo\/status\/824353582979907586\">Quellenangabe<\/a>, der kurz darauf folgte: Erst 2013 wurde die Speicherung von Passw\u00f6rtern von Klartext auf (ungesalzene) Hashes umgestellt. Dass die Hashes ungesalzen waren, ergab sich durch einen Blick in den Quelltext; und wie es nunmal so ist, war dieser Blick einer zu viel und neben der (Quasi-)Klartext-Speicherung vielen gleich 3 weitere Probleme auf:<\/p>\n<ul>\n<li>Akzeptieren des Hashes als Klartext-Passwort (Logic Bug)<\/li>\n<li>Nicht-Konstantzeit-String-Vergleich bei der Passwort-Pr\u00fcfung (Timing Oracle)<\/li>\n<li>Unzureichende Hash-St\u00e4rke<\/li>\n<\/ul>\n<p>Wirkt harmlos? Schauen wir einmal: Auf Grund des Timing Oracles konnte man anhand der Antwort-Zeit des Servers (bei ausreichend genauer Messung) den Inhalt des Datenbank-Feldes rekonstruieren. Dieser beinhaltete entweder das Passwort selbst oder dessen Hash. Mit dem Legacy-Passwort ist man drin (Authentiction Bypass). Bei einem ausreichend starken Hash w\u00e4re hier eigentlich Schluss, aber dank eines Logik-Fehlers bei der Passwort-Pr\u00fcfung f\u00fchrte ein Fehlschlag des Hash-Vergleichs zum direkten String-Vergleich zwischen Hash und dem gesendeten Passwort. Da wir den Hash durch das Timing Oracle kennen, sind wir also auch hier drin (Authentication Bypass). Ein st\u00e4rkerer Hash h\u00e4tte mit diesem Logik-Fehler zwar nur wenig ausrichten k\u00f6nnen, h\u00e4tte aber zumindest den f\u00fcr das Timing Oracle notwendigen Code-Pfad extrem verlangsamt, womit der Angriff erheblich auff\u00e4lliger geworden w\u00e4re. Au\u00dferdem h\u00e4tte der Angreifer mit einem starken Passwort-Hash nicht die Wahl gehabt, sich nach dem Erbeuten des Hashes ganz normal mit dem Klartext-Passwort anzumelden. Entsprechende <a href=\"https:\/\/hashtoolkit.com\/decrypt-md5-hash\/5f4dcc3b5aa765d61d8327deb882cf99\">Datenbanken<\/a> gibt es zu Hauf &#8230;<\/p>\n<p>Die Reaktion war <a href=\"https:\/\/twitter.com\/BenBE1987\/status\/824354839039770624\">entsprechend eindeutig<\/a>. Details gab es an dieser Stelle aber <a href=\"https:\/\/twitter.com\/BenBE1987\/status\/824355889012494341\">vorerst ausschlie\u00dflich privat<\/a>. Kurz darauf kontaktierte mich Thorsten Eckel via DM mit Details f\u00fcr den Security-Kontakt. Da sein Account nur den \u00fcblichen Ei-Avatar hatte, und ich wusste, dass nomoketo bereits kontakt hatte, lie\u00df ich mir die Details kurz Gegenpr\u00fcfen &#8211; eine \u00f6ffentliche Liste der Maintainer, sowie eine M\u00f6glichkeit zur Ende-zu-Ende-verschl\u00fcsselten Kommunikation fehlten leider. Diese sollten auf der Webseite, oder auf Anfrage griffbereit verf\u00fcgbar sein. Infos zur verschl\u00fcsselten Kommunikation mit mir, gibt&#8217;s bei <a href=\"https:\/\/keybase.io\/benbe\">keybase.io<\/a>.<\/p>\n<p>Die initiale Meldung der oben aufgef\u00fchrten Probleme lief via Email an die von Thorsten genannte Adresse &#8211; inklusive einer ausf\u00fchrlichen Beschreibung der verschiedenen L\u00fccken, Voraussetzungen f\u00fcr deren Ausnutzung und die damit assoziierten Gefahren (AKA Risiko-Einsch\u00e4tzung). Zwei der 4 genannten Probleme trugen dabei die Stufe hoch. Die Antwort erfolgte zeitnah und verwies auf eine erste Version eines m\u00f6glichen Patches f\u00fcr die genannten Probleme. Dies ist in sich nicht weiter tragisch, w\u00e4re der Patch nicht gerade <a href=\"https:\/\/github.com\/zammad\/zammad\/commit\/0862bf7e6a6a9a67016083e528c51299824652e9\">direkt \u00f6ffentlich auf Github<\/a> gelandet.<\/p>\n<p>Bei sicherheitskritischen Bugs ist es essentiell, dass Details zu einer L\u00fccke erst \u00f6ffentlich werden, wenn auch ein Patch zur Verf\u00fcgung steht, um diese zu schlie\u00dfen. Andernfalls k\u00f6nnen Angriffe auf verwundbare Systeme gestartet werden, ohne dass eine effektive Gegenwehr m\u00f6glich ist. Je nach Verbreitung einer Software finden solche Angriffe dabei meist bereits nach wenigen Stunden automatisiert und im gro\u00dfen Stil statt. Wenn also zur Mitte des \u00fcblichen 4-Wochen-Release-Zyklus ein Zero-Day \u00f6ffentlich wird, haben Angreifer mehr als genug Zeit, diese Schwachstelle auszunutzen. Versch\u00e4rfend kam in diesem Fall auch noch hinzu, dass der Patch zwar funktional war, aber in Hinblick auf die Best Practices unvollst\u00e4ndig war.<\/p>\n<p>Analog wurde auch die von nomoketo gemeldete L\u00fccke auf diese Art vorzeitig \u00f6ffentlich: Ein <a href=\"https:\/\/github.com\/zammad\/zammad\/commit\/8800a4a86191f604a138eb80ac97befdf6d1e4de\">trivial ausnutzbarer Clientside-XSS-Bug<\/a>, der beliebige Inhalte direkt auf die Webseite einbinden lie\u00df. Im Gegensatz zu den Problemen betreffs meiner Meldung war der hierf\u00fcr anf\u00e4nglich vorgeschlagene Patch aber l\u00f6chrig bis unwirksam, so dass jedem, der die Github-Logs etwas beobachtet, auf dem Pr\u00e4sentierteller eine erstklassige Vorlage f\u00fcr eine L\u00fccke samt Exploit geliefert wurde &#8211; mit Anleitung, wie dieser auch auf notd\u00fcrftig gepatchten Systemen weiterhin ausnutzbar w\u00e4re.<\/p>\n<p>Davon abgesehen sind beide Patches insgesamt vergleichsweise umfangreich, so dass ein Review recht anstrengend ist. Die dennoch an den Commit, der eine Blacklist f\u00fcr b\u00f6sartigen Code implementierte, angeh\u00e4ngten Kommentare verwiesen daher auch schnell auf die zwei relevanten Quellen f\u00fcr diesen Fall:<\/p>\n<ol>\n<li>Das <a href=\"https:\/\/www.owasp.org\/index.php\/XSS_Filter_Evasion_Cheat_Sheet\">OWASP Cross Side Scripting Cheat Sheet<\/a> &#8211; mit XSS-Angriffsvektoren<\/li>\n<li>Den <a href=\"https:\/\/www.owasp.org\/index.php\/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet\">OWASP Cross Side Scripting Mitigation guide<\/a> &#8211; mit Best Practices zur Vermeidung von XSS<\/li>\n<\/ol>\n<p>Auch andere Kommentare empfahlen recht z\u00fcgig, den Blacklist-Ansatz zu Gunsten einer <a href=\"https:\/\/github.com\/zammad\/zammad\/commit\/3fa12b73ae678458d06bac64fbf4778e6e225c14\">Whitelist-L\u00f6sung ersetzt<\/a> wurde. Weitere Vorschl\u00e4ge f\u00fcr die Absicherung wurden genannt, sind aber im Zuge eines Security-Updates zu umfangreich umzusetzen, da diese prim\u00e4r auf Defense-in-Depth abzielen. Zu den weiteren Vorschl\u00e4gen geh\u00f6rten u.a.<\/p>\n<ul>\n<li>Content Security Policy<\/li>\n<li>Sub-Resource Integrity<\/li>\n<li>Nonces f\u00fcr Script-Ausf\u00fchrung<\/li>\n<\/ul>\n<p>Es bleibt aber zu hoffen, dass diese zu einem sp\u00e4teren Zeitpunkt noch nachgereicht werden und die Anstrengungen beim Absichern gegen Sicherheitsl\u00fccken nicht nachl\u00e4sst, wie es bei der Kommunikation der Zwischenst\u00e4nde der Fall war. Abseits der unregelm\u00e4\u00dfig im Git \u00f6ffentlich einsehbaren neuen Patches, war lange Zeit die Information, dass aktuell CVE-Nummern angefordert werden, die letzte Information von offizieller Seite in direkter Kommunikation.<\/p>\n<p>Und so war auch das Testen der Bugfixes eher unkoordiniert: Tage vor dem wahrscheinlichen Release-Termin des Bugfix-Releases probierte nomoketo nochmals, ob die gemeldeten Fehler nun behoben sind &#8211; und stellte gleich den n\u00e4chsten Fehler fest, der in Kombination mit der weiter oben erw\u00e4hnten Authentifizierungsproblematik deren Ausnutzung stark beg\u00fcnstigte. Das Problem dieses Mal war, dass die API zum Abfragen von Daten zu einem Nutzer, neben den \u00fcblichen Details unter gewissen Umst\u00e4nden auch den Hash des Nutzerpasswortes (oh oops, ich meinte: das Passwort) lieferte. Erschwerend hinzu kam, dass f\u00fcr diese API <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Access_control_CORS\">CORS-Header<\/a> gesendet wurden, wodurch &#8211; verhindert nur durch ein Security-Feature im Browser &#8211; man \u00fcber Domain-Grenzen hinweg die Gesamte Nutzerliste samt verwendeter Passworte auslesen konnte. Wer Zammad im Einsatz hatte, sollte also einmal alle Passw\u00f6rter zur\u00fccksetzen und diese auch \u00fcberall, wo sie sonst noch Verwendung fanden, einmal \u00e4ndern. Den Patch dazu gibt es <a href=\"https:\/\/github.com\/zammad\/zammad\/commit\/cd28e904ac122b410f7c28e8284bb0c22411e342\">wie gehabt auf Github<\/a> (diesmal aber erst nach dem Release zug\u00e4nglich).<\/p>\n<p>Abschlie\u00dfend bleibt also zu sagen, dass jedes OpenSource-Projekt neben einem regul\u00e4ren Bugtracker auch einen Prozess zum Melden kritischer Sicherheitsprobleme vorweisen sollte. Dieser sollte leicht zu finden sein und die vertrauliche, verschl\u00fcsselte Kommunikation erm\u00f6glichen. Zudem sollte dieser Prozess sicherstellen, dass sicherheitskritische Patches solange wie m\u00f6glich unter Verschluss gehalten werden und nur f\u00fcr die Behebung ben\u00f6tigten Personen zug\u00e4nglich sind. Diese Einschr\u00e4nkung der Sichtbarkeit mag zuerst im Widerspruch zur Transparenz in OpenSource-Projekten erscheinen, sch\u00fctzt korrekt umgesetzt aber vorhandene, verwundbare Installationen der Software vor gro\u00dffl\u00e4chigen Angriffen mit dieser Verwundbarkeit. Sollte ein Exploit &#8211; oder Details zu einem Sicherheitsproblem &#8211; in the wild existieren, so ist ein Sicherheitsrelease &#8211; auch Abseits des \u00fcblichen Rhythmus &#8211; oberste Priorit\u00e4t.<\/p>\n<p>Etabliert haben sich im Bereich der Responsible Disclosure von L\u00fccken etwa die Regelungen des <a href=\"https:\/\/en.wikipedia.org\/wiki\/Project_Zero_(Google)\">Project Zero<\/a> unter Leitung von Google. Werden Details zu einer vertraulich gemeldeten L\u00fccke fahrl\u00e4ssig vorab bekannt, ist dies nicht nur f\u00fcr die Nutzer riskant, sondern auch f\u00fcr die Meldenden frustrierend. Durch einfache Gestaltung des Prozesses zum Melden von Fehlern und Vermeidung der gr\u00f6\u00dften Fettn\u00e4pfchen bei deren Beseitigung, werden sich regelm\u00e4\u00dfig Leute finden, die unvoreingenommen und abseits der eingefahrenen Muster im Projekt einmal einen Blick werfen, und ihren Fund melden. Wie die 5 Bugs in diesem Release eindrucksvoll zeigen.<\/p>\n<p>Ansonsten kann ich mich hier nur <a href=\"https:\/\/twitter.com\/nomoketo\/status\/831962049508937728\">nomoketo anschlie\u00dfen<\/a>, und jedem Nutzer von <a href=\"https:\/\/zammad.org\">Zammad<\/a> DRINGEND zum Update und zum Wechsel seines Passwortes raten. Die letzten 4 Wochen waren eine sehr interessante Erfahrung und es besteht die Hoffnung, dass das Entwickler-Team das neu gewonnene Wissen gewinnbringend f\u00fcr die weitere Verbesserung der Software einsetzen kann.<\/p>\n<p class=\"wp-flattr-button\"><a href=\"https:\/\/blog.benny-baumann.de\/?flattrss_redirect&amp;id=1665&amp;md5=f103a2cd69b1e006bcf6abde4043962e\" title=\"Flattr\" target=\"_blank\"><img src=\"http:\/\/blog.benny-baumann.de\/wp-content\/plugins\/flattr\/img\/flattr-badge-large.png\" srcset=\"http:\/\/blog.benny-baumann.de\/wp-content\/plugins\/flattr\/img\/flattr-badge-large.png\" alt=\"Flattr this!\"\/><\/a><\/p>","protected":false},"excerpt":{"rendered":"<p>Software-Sicherheit ist ein schwieriges Thema: Nicht nur, weil es trotz zahlreicher Ma\u00dfnahmen zur Fehlervermeidung nahezu unm\u00f6glich ist, komplett fehlerfreie Software zu schreiben, sondern auch, weil das Beheben eines Fehlers dessen Gefahrenpotential extrem steigern kann. Im Umfeld von OpenSource-Software haben sich daher verschiedene Vorgehensweisen zum Umgang mit gemeldeten Fehlern etabliert, die von Full Disclosure, \u00fcber Responsible [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[29],"tags":[14,350,52,351],"class_list":["post-1665","post","type-post","status-publish","format-standard","hentry","category-software","tag-bugs","tag-cve","tag-security","tag-zammad"],"_links":{"self":[{"href":"https:\/\/blog.benny-baumann.de\/index.php?rest_route=\/wp\/v2\/posts\/1665","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.benny-baumann.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.benny-baumann.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.benny-baumann.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.benny-baumann.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1665"}],"version-history":[{"count":4,"href":"https:\/\/blog.benny-baumann.de\/index.php?rest_route=\/wp\/v2\/posts\/1665\/revisions"}],"predecessor-version":[{"id":1671,"href":"https:\/\/blog.benny-baumann.de\/index.php?rest_route=\/wp\/v2\/posts\/1665\/revisions\/1671"}],"wp:attachment":[{"href":"https:\/\/blog.benny-baumann.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1665"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.benny-baumann.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1665"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.benny-baumann.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1665"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}