django-secure-js-login

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mein ursprünglicher "PyLucid JS-SHA-Login", geht in die nächste Runde :lol:

https://github.com/jedie/django-secure-js-login/

Ich arbeite nun daran, eine eigenständige "reusable django app" daraus zu machen.
Gleichzeitig ändre ich das Verfahren und nutzte nun PBKDF2 in JavaScript... (Dazu nutzte ich http://anandam.name/pbkdf2/ )

Dennoch bleibt es dabei, das es nicht einfach nur ein "...sende PBKDF2("password") zum Server..." ist.

Nach wie vor bleibt das bestreben:
  • Keine vollständigen Daten auf dem Server speichern, die zum Login notwendig sind
  • Keine vollständigen Daten zum Server schicken, die zum Login notwendig sind
Also, Sicherheit bieten, auch wenn der SQL-Dump in falsche Hände gerät oder die Verbindung mitgeschnitten wird...

Das verfahren, wie ich es gerade implementiere, ist hier aufgeführt:
https://github.com/jedie/django-secure- ... -procedure

EDIT:
Bild - https://coveralls.io/r/jedie/django-secure-js-login
Bild - https://travis-ci.org/jedie/django-secure-js-login/
:lol:

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ach, da fällt mir ein:

Falls jemand einen Raspberry Pi spontan nutzten kann: Kann jemand auf http://anandam.name/pbkdf2/ mit den iterations Wert spielen und testen wie hoch dieser sein kann, damit es noch in Endlicherzeit fertig wird?!?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Was ist das Threat Model bei dem ganzen? Dem Server muss man ohnehin vertrauen und wenn man kein HTTPS hat kann ein Angreifer in einer aktiven MITM Attacke den JS Code austauschen. Ist die Datenbank kompromitiert sehe ich nicht wieso eine Offline Attacke nicht möglich sein sollte.

Unabhängig von der Spezifikation sieht auch die aktuelle Implementation alles andere als gut aus, der ganze logging Code und ganz fatal die Nutzung von `==` hier ist alles andere als vertrauenserweckend.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Der code ist noch kraut und Rüben. Es ist ja auch noch nicht fertig ;) Deswegen auch die vielen logging ausgaben...

Wenn es fertig ist und alles getestet, gehts ans aufräumen...

Was soll ich denn statt == machen?!? Zur info, das ist die finale Prüfung. Wenn es bis dahin durch ist, wird die Prüfung mit sehr hoher Wahrscheinlichkeit richtig sein ;)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Das Problem mit == ist dass die Zeit in der der Vergleich ausgeführt wird abhängig ist von der Länge des gemeinsamen Präfixes. Wenn man so ein geheimes mit einem vom User beeinflussten Argument vergleicht, kann der User anhand der vergangenen Zeit Rückschlüsse auf das geheime Argument ziehen. Deswegen ist auch dein ganzes logging problematisch, je nachdem wo du damit Zeit "verschwendest" kann ein Angreifer möglicherweise Rückschlüsse darauf ziehen wie weit er gekommen ist.

Speziell um das Problem mit == zu lösen hat Django django.utils.crypto.constant_time_compare. Anders als == ist die Zeit die diese Funktion benötigt um zwei beliebige Strings einer bestimmten Länge zu vergleichen immer konstant. Einzig ob die Länge der beiden Strings übereinstimmt lässt sich hier durch messen der Zeit bestimmen.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ah, jetzt verstehe ich was du meinst ;)

crypto.constant_time_compare verwende ich bereits, nur nicht an dieser Stelle...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

So, mit https://github.com/jedie/django-secure- ... 8f22e5a87f funktioniert der Login endlich!

Fehler war, das der server-challenge jedes mal neu generiert wird :lol:

Rund ist die Sache allerdings noch lange nicht. Nun heißt es, unittests zu schreiben und Code Aufräumen...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

So v0.1.0 ist draußen:

https://pypi.python.org/pypi/django-secure-js-login

Unittests u.a. mit Selenium laufen:
https://travis-ci.org/jedie/django-secure-js-login

Für Python 2 muß ich noch ran, ist aber nichts wildes und Aufräumarbeiten sind auch nicht vollständig abgeschlossen...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hab nun mal django-secure-js-login auf einen Raspberry Pi 1 getestet und nachgesehen wie schnell/langsam es ist.
Relativ Akzeptabel sind IMHO 2000 PBKDF2-SHA1 Durchläufe...

Der RPi ist gar nicht mal so langsam dabei. Selbst auf einen schnellen Rechner dauert es ein/zwei Sekunden.

Hab mit https://github.com/jedie/django-secure- ... 8f0afd4771 die Iterationen auf 2x1000 erhöht...

Ist natürlich immer noch weit weg von den 24000 die bei Django's PBKDF2SHA1PasswordHasher() genutzt wird: https://github.com/django/django/blob/m ... hashers.py

Man kann nicht alles haben :lol:

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@jens:
Wir haben tatsächlich mal was Ähnliches für ein Uniprojekt gebraucht, für welches partout kein SSL und eigne VM zur Verfügung standen. Allerdings war das eher ein SSH-Nachbau: Handshake/Auth mit PKA + Inhaltsverschlüsselung via AES. RSA und AES waren ultralahm, da serverseitig alles in Pythonimplementationen (nix c-Modul) und browserseitig alles in JS gemacht werden musste. Das Ende von Lied - Aufwand für die Katz, da auf dem Server eh alles world readable war und das Rechenzentrum das nicht sauber konfigurieren wollte. Dolle Wurst.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Deswegen macht IMHO django-secure-js-login Sinn...

Klar, im idealfall hat man secure-http und ein Beglaubichtes Zertifikat und alles gut...

Aber wie sieht es in der Praxis aus? Meist doch kein HTTPS und normaler Klartext-Passwort-Login... z.B. hier im Forum :P Wobei IMHO fast in allen anderen Foren/Wikis, bei denen ich mich so rumtreibe...

Weil?
Eigenes Zertifikat -> Erstmal Browser Fehlermeldung
Kostenloses beglaubigtes Zertifikat -> zu kompliziert im beantragen / Server Setup
Zertifikat direkt vom Server-Betreiber -> zu teuer
SSL-Proxy -> günstig, aber auch nicht wirklich Sucher und doofer Domain-Name

Dazu kommt, das die ganze SSL/Zertifikat Geschichte eh nicht mehr so ganz das Wahre ist, siehe: http://www.heise.de/thema/SSL

Es gab doch mal so ein "Open Source" Projekt, die das ganze Zertifikat-Kram vereinfachen sollte... Finde es allerdings nicht mehr...


DasIch hat geschrieben:Das Problem mit == ist dass die Zeit in der der Vergleich ausgeführt wird abhängig ist von der Länge des gemeinsamen Präfixes. Wenn man so ein geheimes mit einem vom User beeinflussten Argument vergleicht, kann der User anhand der vergangenen Zeit Rückschlüsse auf das geheime Argument ziehen. Deswegen ist auch dein ganzes logging problematisch, je nachdem wo du damit Zeit "verschwendest" kann ein Angreifer möglicherweise Rückschlüsse darauf ziehen wie weit er gekommen ist.
Dazu hatte ich mir nochmal Gedanken gemacht:

Klar, man kann alles so gestalten, das eine Überprüfung theoretisch immer die selbe Zeit dauert...
Ich hatte jetzt aber mehr den Ansatz, möglichst wenig CPU Zeit zu verschwenden. Also so früh wie möglich die weitere Überprüfung abbrechen...

Wie wäre es mit der Lösung:

Wenn das Passwort falsch ist, dann: time.sleep(random.uniform(0, 0.5))

Vorteil:
* Kein Rückschluss auf "wie weit bin ich gekommen" möglich
* keine CPU Verschwendung in Multi-Threading-Umgebung

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich frage mich sowieso, wie man bei einem Zugriff aus der Ferne (darum geht es doch, oder?) erkennen will, ob eine Prüfung jetzt 3 Nanosekunden länger war als die vorherige. Das geht doch aufgrund der Schwankungen bei den Übertragungszeit über ein Netzwerk komplett unter, oder nicht?
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Das denke ich eigentlich auch...

Allerdings könnte man da vielleicht bei sehr vielen Versuchen über eine Statistik was machen...

Aber IMHO sollte es eh so sein, das nach X Versuchen eine Sperre eintritt... Gibt es aber noch nicht direkt in django-secure-js-login...

Weiß auch nicht, ob ich das direkt einbauen soll, oder auf was vorhandenes verweisen sollte, wie: https://github.com/kencochrane/django-defender

btw. in "django-secure-js-login" steckt auch noch die "Unter-App" honypot: https://github.com/jedie/django-secure- ... in/honypot
Da weiß ich auch noch nicht, ob ist das "behalten" soll oder als komplett separates Projekt machen oder einstampfen, weil es z.B. https://github.com/dmpayton/django-admin-honeypot gibt...


EDIT: Wie nennt man denn das "Rückschlüsse über bearbeitungs Zeit" ?!? Gibt es dazu ein "offiziellen" Begriff?!?
EDIT2: Ah, aus https://docs.python.org/3/library/hmac. ... are_digest : approach designed to prevent timing analysis by avoiding content-based short circuiting behaviour
Siehe da: https://en.wikipedia.org/wiki/Timing_attack :lol:

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@snafu:
Für wenige Einzelmessungen geht das im Latenzrauschen des Netzwerks unter. Mit genügend Messungen jedoch lassen sich die Unterschiede statistisch signifikant ermitteln.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Side-channel attacks über timing funktioniert durch aus auch über Netzwerke oder sogar das Internet. Das ist nicht ganz trivial aber durchaus praktikabel. Zufällig warten hilft da übrigens überhaupt nicht.

Ein Zertifikat kann man übrigens problemlos kostenlos von StartSSL bekommen. Bei allen Schwächen von HTTPS, HTTPS funktioniert. Dieser JS Login ist nette obfuscation mehr aber auch nicht, vorallem ist es nach keiner brauchbaren Definition "secure".
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Ich habe schon vor Jahren eine für beide Seiten 100% sichere Authentifizierung auf Basis von PAK geschrieben. Nebenbei fällt auch noch ein Session-Key ab, der für die weitere Verschlüsselte Kommunikation verwendet werden kann. Einzige Schwachstelle ist, dass der JavaScript Code natürlich manipuliert werden kann.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

DasIch hat geschrieben:Side-channel attacks über timing funktioniert durch aus auch über Netzwerke oder sogar das Internet. Das ist nicht ganz trivial aber durchaus praktikabel. Zufällig warten hilft da übrigens überhaupt nicht.
Warum?!?
DasIch hat geschrieben:Ein Zertifikat kann man übrigens problemlos kostenlos von StartSSL bekommen.
StartSSL hatte ich mal Probiert. War mir ehrlich gesagt viel zu kompliziert.

Man muß halt abwägen. Für was man es einsetzt...

Hatte ich schon erwähnt, das hier im Forum ebenfalls keine Verschlüsselung aktiv ist... Stimmt nicht: https://www.python-forum.de/ aber:
www.python-forum.de verwendet ein ungültiges Sicherheitszertifikat.

Das Zertifikat gilt nur für vst-opdm.de.
Warum wohl? Ich vermute mal, es ist zu Aufwendig...
DasIch hat geschrieben:Dieser JS Login ist nette obfuscation mehr aber auch nicht, vor allem ist es nach keiner brauchbaren Definition "secure".
Es ist kein "obfuscation" im Sinne von "Verschleierung"...

Also Angriffssektor sehe ich eigentlich nur eine Man-In-The-Middle Attacke... Die ist natürlich in der Praxis anzutreffen, aber sicherlich nicht mal eben so machbar. Außerdem, wer macht sich schon die Mühe dazu, für eine Private Homepage?!? Da sehe ich den Haupteinsatzzweck.
Sirius3 hat geschrieben:Ich habe schon vor Jahren eine für beide Seiten 100% sichere Authentifizierung auf Basis von PAK geschrieben.
Sourcen noch da?!?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Nu auch hier:
Bild - https://coveralls.io/r/jedie/django-secure-js-login

und nun auch alles ok:
Bild - https://travis-ci.org/jedie/django-secure-js-login/



TODO: Mehr Tests mit Ausnahmen/Falschen Daten...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ich habe das Thema "DOS potenzial in django.contrib.auth ?!?" abgetrennt: http://www.python-forum.de/viewtopic.php?f=7&t=36279

Sowie ein separates Thema "login timing attacks..." eröffnet: http://www.python-forum.de/viewtopic.php?f=7&t=36282


In django-secure-js-login gibt es auch einige Neuerungen:
* Den ganzen Validierungs-Prozess habe ich überarbeitet
* Über "Signals" halte ich den Grund eines Fehlgeschlagenen Login "fest"
* Bei settings.DEBUG sieht man den Fehlergrund beim Login selbst
* Bei settings.DEBUG=False: sieht man immer nur die selbe, allgemeine Fehlermeldung.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hab die README erweitert, damit man auch weiß, wie man die app bei sich einbinden kann:

https://github.com/jedie/django-secure-js-login#usage

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten