einsiedler: Login-script -- Mit wie viel Euro muss ich rechnen wenn jemand von euch mir das programmiert?

0 62

Login-script -- Mit wie viel Euro muss ich rechnen wenn jemand von euch mir das programmiert?

  1. 0
    1. 0
  2. 0
    1. 3
    2. 0
      1. 0
  3. 1
    1. 0
      1. 0
    2. 0
    3. 7
      1. 0
        1. 0
      2. 0
        1. 0
          1. 0
            1. 0
            2. 2
              1. 0
                1. 6
                  1. 0

                    Login-script -- Mit wie viel Euro muss ich rechnen wenn jemand von euch mir das programmiert? - Moderiert -

                    1. 7

                      Login-script -- Mit wie viel Euro muss ich rechnen wenn jemand von euch mir das programmiert?

                2. 0

                  Mathematik zum Montag

                  1. 0
                    1. 0
                  2. 2
                    1. 0
                    2. 0
                      1. 0
                  3. 3
                    1. 2
                  4. 0
                    1. 0
                      1. 2
                        1. 0
                          1. 0
                          2. 2
                            1. 0
                              1. 0
                                1. 0
                              2. 0

                                Bevor gefragt wird, wieso denn alle unzutreffend seien

                                1. 0
                                  1. 0
                                    1. 2
                                      1. 0
                                        1. 0
                  5. 2
                    1. 0
              2. -2
                1. 0
                  1. 0
                    1. 1
                      1. 0
            3. 0
              1. 0
                1. 0
                  1. 0
                  2. 0
      3. 0
        1. 0
          1. 0

Hallo liebe Forumer,

es geht mir heute um ein Login-script -- Mit wie viel Euro muss ich rechnen wenn jemand von euch mir das programmiert?

Es geht mir um die üblichen Funktionen: Registrieren, einloggen, mehrere Unterseiten die eben geschützt sind, bei der Registrierung per E-Mail bestätigen, Admin soll Infos per Mail erhalten und letztlich der Registrierung per Link "zusagen" / bestätigen können. Das wäre es ganz grob.

Was denkt Ihr, was müsste ich bei euch anlegen?

Gerne Angebote per PN / muss nicht öffentlich hier gepostet werden.

Der Misanthrop

  1. Was würde Dir denn ein Loginscript nutzen? Hast Du da mal darüber nachgedacht? MFG

    1. Oh doch, ich habe nutzen dafür, glaube mir mal.

      Dahingehend möchte ich keine Diskussion.

      Ja gut, was würde es mich kosten wenn ihr es programmiert. In etwa (erfahrungsgemäß) Nennt nur mal eine Zahl.

      Gruß der misanthrop

  2. Lieber einsiedler,

    Es geht mir um die üblichen Funktionen: Registrieren, einloggen, mehrere Unterseiten die eben geschützt sind, bei der Registrierung per E-Mail bestätigen, Admin soll Infos per Mail erhalten und letztlich der Registrierung per Link "zusagen" / bestätigen können. Das wäre es ganz grob.

    das ist kein reines Login-Script mehr.

    Liebe Grüße

    Felix Riesterer

    1. Servus!

      Es geht mir um die üblichen Funktionen: Registrieren, einloggen, mehrere Unterseiten die eben geschützt sind, bei der Registrierung per E-Mail bestätigen, Admin soll Infos per Mail erhalten und letztlich der Registrierung per Link "zusagen" / bestätigen können. Das wäre es ganz grob.

      das ist kein reines Login-Script mehr.

      Ich persönlich verwende neuerdings (seit 2 Jahren) dann doch eine Fertiglösung:

      Das mit der 5-Minuten-Installation dauert bei mir immer ca. 10min, ansonsten kostenlos, immer aktuell und viele, viele Plugins (die ich nur vorsichtig installiere).

      Früher habe ich viel mit CSS ausprobiert, was ich dann nur auf einer Seite verwendet hatte - heute will ich Inhalte schnell online stellen - oder dies eben anderen Nutzern, die als Mitarbeiter und Redakteure angemeldet sind, ermöglichen.

      Im SELF-Wiki gibt's nen Kurs dazu:

      Herzliche Grüße

      Matthias Scharwies

      --
      "I don’t make typos. I make new words."
    2. Ja gut, was würde es mich kosten wenn ihr es programmiert. In etwa (erfahrungsgemäß) Nennt nur mal eine Zahl.

      Gruß der misanthrop

      1. Lieber einsiedler,

        ich werde es Dir nicht programmieren. Mein Geld verdiene ich auf andere Weise. Aber Du bist herzlich eingeladen, eine vorhandene Lösung (wie ein beliebiges CMS) für Deine Bedürfnisse einzurichten. @Matthias Scharwies hat Dir ja schon einen Tipp gegeben.

        Liebe Grüße

        Felix Riesterer

  3. Registrieren, einloggen, mehrere Unterseiten die eben geschützt sind,

    Liegt fertig rum. (Testseite existiert)

    bei der Registrierung per E-Mail bestätigen, Admin soll Infos per Mail erhalten und letztlich der Registrierung per Link "zusagen" / bestätigen können. Das wäre es ganz grob.

    Kleinkram, der allerdings doch so manche Änderung erfordert. Du hast nicht alles spezifiziert, ich würde deshalb mal sagen ab 600 Euro "schlüsselfertig".

    1. Servus!

      Kleinkram, der allerdings doch so manche Änderung erfordert. Du hast nicht alles spezifiziert, ich würde deshalb mal sagen ab 600 Euro "schlüsselfertig".

      Kommt hin; ich hab mal 1500,- für ne Webseite eines Fördervereins mit 5 Unterseiten gehört. Herzliche Grüße

      Matthias Scharwies

      --
      "I don’t make typos. I make new words."
      1. Kommt hin; ich hab mal 1500,- für ne Webseite eines Fördervereins mit 5 Unterseiten gehört.

        Au. Das erinnert mich daran, dass mal ein gelernter Lokführer mein Skript für genau den Preis auf der Webseite eines Fördervereins verbaut hat. Ich weiß nicht genau, ob der alles richtig gemacht hat. Andererseits habe ich auch (auch ich) einen ehrbaren Beruf.

    2. Also gut, verstehe,

      ich muss wohl mit 600 Euronen ++ (eher einiges mehr) rechnen. Das wollte ich wissen!

      Danke an alle!

      Der misanthrop

    3. Ich möchte nochmal vor selbst-gestrickten Lösungen warnen und für die Komplexität von sicherheits-kritischen Systemen sensibilisieren. Man sollte nicht zu leichtfertig an solche Systeme heran gehen. Das verlinkte Login-System ist ein Beispiel für einen mutigen, aber dennoch naiven Ansatz. Das habe ich früher schon kritisiert, und wurde im Gegenzug dafür kritisiert nicht konkret genug geworden sein. Die Kritik nehme ich mir zu Herzen und versuche diesmal alle meine Punkte mit Quellen und Zitaten zu belegen. Hauptsächlich beziehe ich mich dabei auf die Cheat Sheets von OWASP und die Paragon Initiative. Gegliedert habe ich die Kritik nach fachlichen Merkmalen, zu jeder Überschrift gibt es ein passendes Cheat Sheet von OWASP, das ich am Beginn jedes Abschnitts verlinke. Die OWASP Cheat Sheets sind ein guter Ausgangspunkt, allerdings keine erschöpfende Referenz für alle sicherheits-relevanten Software-Aspekte.

      Authentication

      Authentication Cheat Sheet

      Das Login-System benutzt die selben Konfigurations-Dateien, wie der Apache-Webserver für die Benutzer-Authentifizierung. Das habe ich zum ersten mal hier angesprochen, habe es aber nicht weiter unterfüttert. Das bringt allerlei Probleme mit sich, wenn man das nicht explizit durch die Apache-Konfiguration unterbindet. Zum Beispiel kann das dazu führen, dass ein Nutzer mehrfach nach seinem Passwort gefragt wird: Einmal durch den Webserver und einmal durch das darauf laufende PHP-Skript. Das ist unkomfortabel, allerdings auch ein Sicherheits-Risiko, weil durch das Basic-Auth-Verfahren nun bei jeder Folgeabfrage Benutzername und Passwort übertragen werden. Außerdem erfordert es erhöhten Konfigurations-Aufwand, wenn man Basic-Auth und PHP-Login von einander trennen möchte. Das Cheat Sheet schreibt dazu diesen Punkt:

      Do NOT allow login with sensitive accounts (i.e. accounts that can be used internally within the solution such as to a back-end / middle-ware / DB) to any front end user interface. - OWASP


      Ferner ist das Login-Skript mit einer minimalen Passwort-Länge von 8 Zeichen vorkonfiguriert. Diese Länge gilt inzwischen nicht mehr als hinreichend sicher und sollte auf 10 angehoben werden. Aus dem Cheat Sheet:

      Minimum length of the passwords should be enforced by the application. Passwords shorter than 10 characters are considered to be weak (NIST SP800-132). - OWASP


      Das Skript funktioniert sowohl mit HTTPS als auch mit unverschlüsseltem HTTP. Das ist prinzipiell in Ordnung, wenn im Falle von HTTP der Transport irgendwie anders abgesichert wird, zum Beispiel durch SSH-Forwarding oder einen VPN-Tunnel. Das muss beim Aufsetzen des Skriptes Berücksichtigung finden. Es gibt heute allerdings auch keine guten Gründe mehr dafür, überhaupt auf HTTPS zu verzichten. Aus dem Cheat Sheet:

      The login page and all subsequent authenticated pages must be exclusively accessed over TLS or other strong transport. - OWASP

      Und in dem Session Management Cheat Sheet wird dieser Punkt ebenfalls nochmal betont.

      In order to protect the session ID exchange from active eavesdropping and passive disclosure in the network traffic, it is mandatory to use an encrypted HTTPS (SSL/TLS) connection for the entire web session, not only for the authentication process where the user credentials are exchanged. - OWASP


      Wenn ein Login-Versuch fehlschlägt, antwortet das Skript mit einer präzisen Fehlerbeschreibung, die erklärt ob das Passwort falsch war oder der Benutzername nicht existiert. Das ist aus Benutzersicht erstmal bequem, kann aber auch von Angreifern genutzt werden, um zu herauszufinden ob ein Benutzer in deinem System registriert ist. Zum Beispiel, könnte ich einfach mal die Email-Adresse meines Partners oder meiner Kollegen ausprobieren. Stell dir bspw. vor, das mache ich in einem AIDS-Hilfe-Forum, einer Abtreibungs-Klinik oder einem Forum für trockene Alkoholiker. Aus dem Cheat Sheet:

      An application should respond with a generic error message regardless of whether the user ID or password was incorrect. It should also give no indication to the status of an existing account. - OWASP

      Session Management

      Session Management Cheat Sheet

      Der Name des Session-Cookies des Skripts lautet einfach PHPSESSID, dadurch weiß ein Angreifer, dass PHP eingesetzt wird und kann gezielt PHP-Sicherheitslücken ausprobieren. Besonders heikel ist das im Zusammenhang mit veralteten PHP-Versionen, die keine Sicherheitspatches mehr erhalten. Dazu später noch mehr. Aus dem Cheat Sheet:

      The session ID names used by the most common web application development frameworks can be easily fingerprinted, such as PHPSESSID (PHP), JSESSIONID (J2EE), CFID & CFTOKEN (ColdFusion), ASP.NET_SessionId (ASP .NET), etc. Therefore, the session ID name can disclose the technologies and programming languages used by the web application. - OWASP


      Um den Fall zu vermeiden, dass ein Session-Cookie über eine unverschlüsselte Verbindung übertragen wird, sollte die Session mit der Option 'cookie_secure' => true gestartet werden, das ist aktuell nicht der Fall. Aus dem Cheat Sheet.

      The Secure cookie attribute instructs web browsers to only send the cookie through an encrypted HTTPS (SSL/TLS) connection. This session protection mechanism is mandatory to prevent the disclosure of the session ID through MitM (Man-in-the-Middle) attacks. It ensures that an attacker cannot simply capture the session ID from web browser traffic. - OWASP

      Weiterhin sollte beim Session-Start die Option 'cookie_httponly' => true gesetzt werden, damit das Cookie nicht von JavaScript ausgelesen werden kann. Das ist bisher leider auch nicht der Fall. Aus dem Cheat Sheet:

      The HttpOnly cookie attribute instructs web browsers not to allow scripts (e.g. JavaScript or VBscript) an ability to access the cookies via the DOM document.cookie object. This session ID protection is mandatory to prevent session ID stealing through XSS attacks. - OWASP

      Und von der Paragon Initiative heißt es ganz ähnlich:

      In a similar vein, if you're using PHP's built-in session management features (which are recommended), you probably want to invoke session_start() like so:

      session_start([
          'cookie_httponly' => true,
          'cookie_secure' => true
      ]);
      

      This forces your app to use the HTTP-Only and Secure flags when sending the session identifier cookie, which prevents a successful XSS attack from stealing users' cookies and forces them to only be sent over HTTPS, respectively.


      Wenn das Skript über HTTP läuft, dann wir die Session-ID bei jeder Anfrage erneuert. Das macht asynchrone Anfragen zu einem Glücksspiel, weil die asynchronen Anfragen dann einer Race-Condition unterliegen. Wenn es einen Angreifer gibt, der eine Session-ID mitgelesen hat, kann diese Race-Condition für sich nutzen, um den eigentlichen Eigentümer der Session auszusperren.


      PHP Configuration

      PHP Configuration Cheat Sheet

      Auf der Seite wird das Skript unter anderem damit vermarktet, dass es ab PHP 5.3 funktioniert. PHP 5.3 erhält aber seit Jahren keine Sicherheits-Patches mehr. Eine Kette ist nur so stark wie ihr schwächstes Glied. Von der Paragon-Initiative:

      PHP 7.2 was released on November 30, 2017.

      As of this writing, only PHP 7.1 and 7.2 receive active support by the developers of the PHP programming language, while PHP 5.6 and 7.0 both receive security patches for approximately another year.

      Some operating systems provide long-term support for otherwise unsupported versions of PHP, but this practice is generally considered harmful. In particular, their bad habit of backporting security patches without incrementing version numbers makes it hard to reason about the security of a system given only its PHP version.

      Consequently, regardless of what promises another vendor makes, you should always strive to run only actively supported of PHP at any given time, if you can help it. That way, even if you end up on a security-only version for a while, a consistent effort to upgrade will keep your life free of unpleasant surprises.

      PHP 7.1 erhält ab Dezember diesen Jahres keine Sicherheitspatches mehr. Also sollte man schonmal auf 7.2 oder. 7.3 umsteigen.

      Password Storage

      Password Storage Cheat Sheet

      Für die PHP 5.3 Kompatibilität gibt es in dem Skript einen eigenen Salt-Generator, der ist allerdings kryptografisch nicht sicher.

      Aus dem Cheat Sheet:

      Follow these practices to properly implement credential-specific salts: [...]

      • Use cryptographically-strong random data;

      Im Code wird die PHP-Funktion rand dafür benutzt. Im PHP-Handbuch wird vor dem Einsatz dieser Funktion für kryptografisch sichere Zufallszahlen gewarnt:

      This function does not generate cryptographically secure values, and should not be used for cryptographic purposes. If you need a cryptographically secure value, consider using random_int(), random_bytes(), or openssl_random_pseudo_bytes() instead.

      1. Hallo 1unitedpower,

        Könntest du das im Wiki an eine passende Stelle schreiben?

        Bis demnächst
        Matthias

        --
        Pantoffeltierchen haben keine Hobbys.
        ¯\_(ツ)_/¯
        1. Könntest du das im Wiki an eine passende Stelle schreiben?

          Ich habe alle Entwürfe in diese Richtung bisher überworfen, weil ich an meinen eigenen Ansprüchen und Kenntnissen gescheitert bin. Die OWASP Cheat Sheets sind allerdings unter der selben Lizenz veröffentlicht wie unsere Wiki-Inhalte. Wir könnten die Artikel also übersetzen, das ist deutlich weniger Arbeit als die Inhalte eigenständig aufzuarbeiten. Wenn das eine Option für unser Wiki ist, dann würde ich da auch gerne helfen. Allerdings bin ich gerade sehr tief in ein Forschungsprojekt verwickelt und stehe dort unter massiven Zeitdruck wegen einiger nahender (und einiger bereits verzögerter) Deadlines.

      2. Für die PHP 5.3 Kompatibilität gibt es in dem Skript einen eigenen Salt-Generator, der ist allerdings kryptografisch nicht sicher.

        Äh? Nach langer und harter Diskussion um den Salt waren wir doch konsent, dass der keine kryptographische Sicherheit braucht. Oder ist der angespochene "credential-specific salt" nicht der beim Speichern des Passworts verwendete?

        Aber gut, dass Du mich erinnerst: Die Ersatzfunktionen für password_hash() und Co. sollte ich endlich mal "kicken" und durch eine Prüfung mit Fehlermeldung ersetzen. Weil die an anderer Stelle für Unsicherheit sorgen, denn so ist es "notlos" möglich das Skript auf asbachalten und also per Definition unsicheren Installationen zu "fahren".

        1. Für die PHP 5.3 Kompatibilität gibt es in dem Skript einen eigenen Salt-Generator, der ist allerdings kryptografisch nicht sicher.

          Äh? Nach langer und harter Diskussion um den Salt waren wir doch konsent, dass der keine kryptographische Sicherheit braucht.

          Ja, das habe ich früher auch schon ausgesagt. Nach meinem heutigen Kenntnisstand lag ich damit aber falsch.

          1. Nicht alles, was andere veröffentlichen, ist automatisch richtig.

            Bei einem Brut-Force Angriff von außen ist es egal weil der Hash und damit der Salt den Angreifer gar nicht interessiert. Die Berechnung von Passwörtern die aufgrund eines Konflikts und einem nur bedingt sicheren Zufall beim brut-force ausgelassen werden könnten dürfte auch eine anstrengende und teure Sportart werden. (Außerdem sollte mod_evasive und/oder fail2ban vor Brut-Force-Attacken schützen.)

            Falls der Angreifer die Passwortdatenbank mit den Hashes aber hat, dann hat er zwingend auch die Salts. Dann nützt die kryptographische Sorgfalt bei Erstellen der Salts nichts. Wozu sollte ein Angreifer etwas vorhersagen, was er doch schon weiß?

            Die Diskussion ist akademisch: Die Ersatzfunktionen sind ja nun wegen des Ablaufs der Unterstützung für PHP < 7.1 (und also ohne passwort_hash()) draußen.

            1. Falls der Angreifer die Passwortdatenbank mit den Hashes aber hat, dann hat er zwingend auch die Salts. Das gilt auch bei Verwendung des hoch aktuellen Argon2i als Methode:

              Usage of Argon2i in PHP

              The fourth parameter is the random salt value, encoded in Base64. This value is generated by password_hash() using a random value for each execution. This is why we have different hash outputs for the same input string. The default size of the salt is 16 bytes.

            2. Aloha ;)

              Nicht alles, was andere veröffentlichen, ist automatisch richtig.

              Und nicht alle Veröffentlichungen, denen jemand im Internet unter einem Pseudonym widerspricht, sind automatisch falsch.

              Um das ernsthaft und ausgeglichen zu diskutieren, bräuchten wir jetzt erstmal die Gründe, die zu dieser Aussage geführt haben - die führst du aber nicht an, sondern nur die dagegen.

              Kann man so machen, führt aber halt nicht dazu, dass jemand von außen noch irgendwas dazu beitragen kann.

              Ich will unter anderem deshalb jetzt auch gar nicht auf das Für und Wider eingehen, sondern einfach nur mal feststellen, dass @1unitedpower da eine sinnvolle Argumentationskette mit entsprechenden Belegen und Querverweisen zu best practices aufgezogen hat, die es tatsächlich am besten mal irgendwann ins Wiki schaffen sollte.

              Und wenn sie es dann mal dahin geschafft hat, dann kann man nochmal schauen, ob man das eine oder andere vielleicht mit Kontext ergänzen muss.

              Nur bitte jetzt nicht schon wieder ein Detail totdiskutieren, bevor es das große Ganze überhaupt ins Wiki geschafft hat.

              Grüße,

              RIDER

              --
              Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
              # Twitter # Steam # YouTube # Self-Wiki # Selfcode: sh:) fo:) ch:| rl:) br:^ n4:? ie:% mo:| va:) js:) de:> zu:} fl:( ss:) ls:[
              1. Um das ernsthaft und ausgeglichen zu diskutieren, bräuchten wir jetzt erstmal die Gründe, die zu dieser Aussage geführt haben - die führst du aber nicht an, sondern nur die dagegen.

                Weil ich die Gründe, die für eine Notwenigkeit kryptographischen Zufalls beim Erstellen der Salts sprächen, nicht kenne und auch nicht erkennen kann. Das einzige "Argument" welches gebetsmühlenartig wiederholt wird, ist dass andere das behaupten. Über diese anderen wird ebenfalls nur behauptet, dass diese rennommiert seien. Ich sehe keinerlei sachlich fassbaren Vortrag außer

                Wenn [→ Weil] der Pseudozufallsgenerator nicht genügend Entropie liefert,

                ... der aber leicht zu entkräften ist:

                Denn der Pseudozufallsgenerator nicht genug Entropie für Kryptographie liefert, dann wird der Pseudozufall wohl immer noch für den von mir postulierten Zweck ausreichen. Wie oft könnte man mit rand() wohl 200 oder 2000 Salts mit 16 Zeichen aus [0-9A-Za-z/.] konstruieren bis man das erste Mal den Fall hat, dass dabei pseudozufällig 2 gleiche Salts in der gleichen Gruppe entstehen? (Das ist das einzige, um was es geht!) Ein paar Millionen oder ein paar Billionen mal?

                Für mehr als 2000 gehaschte Passwörter ist doch schon die Speichermethode (text/csv) ungeeignet!

                Meine sachlicher, auf die "Regenbogentabellen" bezogener Einwand

                Die Kernfrage ist, wozu ich einen salt mittels kryptographischem Zufall bauen soll, wenn doch klar ist, dass die einzige Anwendung, bei der ein kryptographischer salt Vorteile bringen könnte, voraussetzt, dass der hash bekannt ist.** Mithin müsste dem Angreifer also zwar der hash nicht jedoch der salt bekannt sein, was im Hinblick darauf, dass beide in einem String stehen, "ziemlich selten wäre" - oder?**

                wird zu Gunsten irgendwelcher Veröffentlichungen (die auch keinen Grund nennen) von irgendwem (dessen Autorität dadarch bestimmt wird, dass er in einem "Wir tragen das gleiche T-Shirt-Verein" ist) einfach - und mit beachtlicher Sturheit - negiert.

                1. Hallo,

                  du solltest dich mit dem Gedanken anfreunden, das nicht alles, was du nicht verstehst oder nachvollziehen kannst, falsch sein muss.

                  Und hör endlich auf, Gruppierungen, die du nicht kennst und die an der Diskussion nicht beteiligt sind, zu verunglimpfen.

                  Gruß
                  Jürgen

                  1. Text vom Moderator gelöscht.

                    Jetzt hör mal gut zu. Vom Moderator gelöschte Postings hier als Screenshot einzubinden ist eine Sauerei. Jörg, du spielst mit dem Feuer. Das Löschen deiner Beiträge geht schneller, als du tippen kannst.

                    JürgenB

                    1. Hör endlich auf, über andere herzuziehen. Deine Argumente sagen nichts über die fachliche Qualifikation dieser Gruppe. Wenn du jemanden direkt und persönlich angreifen oder kritisieren willst, mach das direkt per Mail oder auf deiner Seite.

                      War das jetzt klar genug?

                2. Wie oft könnte man mit rand() wohl 200 oder 2000 Salts mit 16 Zeichen aus [0-9A-Za-z/.] konstruieren bis man das erste Mal den Fall hat, dass dabei pseudozufällig 2 gleiche Salts in der gleichen Gruppe entstehen? (Das ist das einzige, um was es geht!) Ein paar Millionen oder ein paar Billionen mal?

                  Wer Fehler findet mag's korrigieren:

                  [0-9A-Za-z/.] -> 58 Symbole

                  Salts mit 16 Zeichen -> 16 Stellen

                  58^16 = 16400152899115243850138976256 mögliche Iterationen

                  Durchschnittlich wird also (bei perfektem Zufall) aller 58^16/2 = 8200076449557621925069488128 Versuchen der gleiche Salt wie ein bestimmter (z.B.)vorheriger erzeugt.

                  Erzeugt man Gruppen von 200 Salts dann ergäbe sich, dass durchschnittlich nach 58^16/(2*200) = 41000382247788109625347440 Versuchen eine Gruppe von 200 Salts erzeugt wurde, welche mindestens 2 identische Salts enthält.

                  Wenn man mit einem derzeitig gebräuchlichem Server und PHP sowie rand() rangeht

                  <?php
                  class saltMaker {
                      private $s='0123456789abcdefghijklmnopqrstyuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/.';
                     
                      public function generate( $l=16 ) {
                          $s='';
                          for ($i = 0; $i < 16; $i++ ) {
                             $s = $s . $this -> s[ rand( 0, 57 ) ];
                          }
                          return $s;
                      }
                  }
                  
                  $tests = 1000000;
                  $sm = new saltMaker();
                  
                  $start = microtime( true );
                  for ( $i=0; $i < $tests; $i++ ) {
                     $sm -> generate();
                  }
                  $end = microtime( true );
                  echo  ($end - $start) . ' Sekunden (' . ($end - $start)/$tests . ' Sekunden pro Salt.)';
                  

                  dann kann man z.B. 100.000 Salts in einer Sekunde erzeugen. (Habs grad getan)

                  Dann dauert es also durchschnittlich 410003822477881096253 Sekunden bis eine Datei erzeugt wurde, die 200 Salts enthält von denen mindestens 2 identisch sind.

                  Ein Jahr hat rund (365.252460*60 = 31557600 Sekunden. Also würde es durchschnittlich 410003822477881096253/31557600 = 12992237130766 Jahre dauern bis man zwei solche Dateien erzeugt erzeugt hat. Die Erde wird voraussichtlich noch 1500000000 Jahre existieren. Man braucht also (mit heutiger Rechentechnik) nur rund 6900 mal so lange wie die Erde noch existieren wird.

                  Nach diversen Schätzungen ist der Zufall von rand() gegenüber kryptographischen Zufallsfunktionen um 20% "schlechter".

                  Demnach braucht man nur 58^16/(2200) 0.8 = 32800305798230487700277952 Versuche um eine Datei zu erzeugen, die 200 Salts enthält von denen mindestens 2 identisch sind. Und nur 3400 mal so lange, wie die Erde noch existiert…

                  Was spart ein Angreifer?

                  Nun, wenn jemand die Passwörter in einer Datei mit nur 199 statt 200 verschiedenen Salts zu knacken hat, dann spart er ein halbes Prozent der für die Erzeugung der Rainbow-Tables benötigten Zeit. Wie schon beschrieben durchschnittlich in jedem 41000382247788109625347440. Fall bei perfektem Zufall und in jedem 32800305798230487700277952. Fall bei Pseudo-Zufall.

                  Da kann er also ganz oft richtig zeitig Feierabend machen!

                  1. @@Indianerversteher

                    Wer Fehler findet mag's korrigieren:

                    [0-9A-Za-z/.] -> 58 Symbole

                    64.

                    LLAP 🖖

                    --
                    „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
                    1. @@Indianerversteher

                      Wer Fehler findet mag's korrigieren:

                      [0-9A-Za-z/.] -> 58 Symbole

                      64.

                      Ja schön. Dann kann man jetzt den bc benutzen um alle Zahlen neu auszurechnen und dann zu erkennen, dass zwar die Zahlen größer werden, sich aber die Aussage letztendlich nicht ändert:

                      (Alt)

                      Nun, wenn jemand die Passwörter in einer Datei mit nur 199 statt 200 verschiedenen Salts zu knacken hat, dann spart er ein halbes Prozent der für die Erzeugung der Rainbow-Tables benötigten Zeit. Wie schon beschrieben durchschnittlich in jedem 41000382247788109625347440. Fall bei perfektem Zufall und in jedem 32800305798230487700277952. Fall bei Pseudo-Zufall.

                      (Neu)

                      Nun, wenn jemand die Passwörter in einer Datei mit nur 199 statt 200 verschiedenen Salts zu knacken hat, dann spart er ein halbes Prozent der für die Erzeugung der Rainbow-Tables benötigten Zeit. Wie schon beschrieben durchschnittlich in jedem 198070406285660843983859875. Fall bei perfektem Zufall und in jedem 158456325028528675187087900. Fall bei Pseudo-Zufall.

                  2. Aloha ;)

                    Wie oft könnte man mit rand() wohl 200 oder 2000 Salts mit 16 Zeichen aus [0-9A-Za-z/.] konstruieren bis man das erste Mal den Fall hat, dass dabei pseudozufällig 2 gleiche Salts in der gleichen Gruppe entstehen? (Das ist das einzige, um was es geht!) Ein paar Millionen oder ein paar Billionen mal?

                    Wer Fehler findet mag's korrigieren:

                    Da brauch ich nicht lang suchen.

                    [0-9A-Za-z/.] -> 58 Symbole

                    Salts mit 16 Zeichen -> 16 Stellen

                    58^16 = 16400152899115243850138976256 mögliche Iterationen

                    Durchschnittlich wird also (bei perfektem Zufall) aller 58^16/2 = 8200076449557621925069488128 Versuchen der gleiche Salt wie ein bestimmter (z.B.)vorheriger erzeugt.

                    [Rechnerei]

                    Dann dauert es also durchschnittlich 410003822477881096253 Sekunden bis eine Datei erzeugt wurde, die 200 Salts enthält von denen mindestens 2 identisch sind.

                    Du ignorierst hier zwei Dinge, die deine Argumentation ad absurdum führen.

                    1.: Du sprichst hier von perfektem Zufall und baust darauf deine Argumentation darauf auf. Ja was bitte ist denn deiner Meinung nach ein kryptographisch sicherer Zufallsgenerator, wenn nicht einer, der im Gegensatz zu einem stinknormalen Zufallsgenerator genau diesem perfekten Zufall möglichst nahe kommt? Deine Argumentation, warum man diese Variante nicht benötigt, nimmt diese Variante zur Grundlage - was glaubst du, wo du damit landest?

                    2.: Deine Rechnung ist von vorne bis hinten eine Milchmädchenrechnung, da du das Geburtstagsparadoxon und die dahinterstehende Erkenntnis völlig vernachlässigst. Es geht gar nicht darum, dass der gleiche Salt wie ein bestimmter erzeugt wird. Das potenzielle Problem entsteht dann, wenn zwei beliebige Salts übereinstimmen, und dafür gelten ganz andere Wahrscheinlichkeiten.

                    Und um es nochmal ganz deutlich zu sagen: Du arbeitest dich hier an einem Detail der ganzen Geschichte ab, bei dem es nur darum geht, wie sicher der Zufallszahlengenerator ist - und ohne, dass es einen etwas kosten würde, einen kryptographisch sicheren Zufallszahlengenerator zu benutzen, versuchst du einem hier vorzurechnen, dass es ja sowieso egal ist und man deshalb auch den weniger sicheren benutzen kann. What the actual fuck?

                    Gerade im Bereich Sicherheit geht es darum, alle einfach umsetzbaren Mittel, die zu einem Plus an Sicherheit führen, anzuwenden, um eine größtmögliche Sicherheit zu erhalten. Es geht nicht darum, ein System zu implementieren, dass möglichst einfache Mittel verwendet, um damit eine Sicherheit zu erhalten, die Schätzungen zufolge für aktuell gängige Rechenleistungen schon ausreichen wird.

                    Ich werde das Gefühl nicht los, dass du hier aus persönlichen Gründen irgendwo einen Punkt setzen willst, dir gleichzeitig aber die Felle davonschwimmen und du deshalb versuchst, dich auf eine Aussage zu stützen, deren Bedeutung du kleinreden kannst.

                    Falls das so ist: lass das doch einfach. Das kostet nur alle hier Beteiligten Zeit. Weiterbringen tut das niemanden.

                    Grüße,

                    RIDER

                    --
                    Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
                    # Twitter # Steam # YouTube # Self-Wiki # Selfcode: sh:) fo:) ch:| rl:) br:^ n4:? ie:% mo:| va:) js:) de:> zu:} fl:( ss:) ls:[
                    1. Gerade im Bereich Sicherheit geht es darum, alle einfach umsetzbaren Mittel, die zu einem Plus an Sicherheit führen, anzuwenden

                      Mein Gott! Das Plus an Sicherheit gibt es nicht. In PHP vor 5.3 gab es keine Möglichkeit, kryptographisch sicheren Zufall zu erzeugen. Insbesondere nicht random_int(). In PHP 5.3 und später wurden meine Ersatzfunktionen gar nicht benutzt und konnten ergo die Sicherheit gar nicht mindern. Die Sicherheit der mit meinem Skript gehashten Passwörter war also stets auf dem jeweiligen "Stand der Technik" und wird es so lange bleiben wie PHP diesen mit den password_*-Funktionen unterstützt. Die Behauptung war aber, mein Skript sei unsicher - und diese Behauptung ist falsch.

                      Du sprichst hier von perfektem Zufall und baust darauf deine Argumentation darauf auf.

                      Wie, bitte, soll ich denn sonst vorrechnen, wie sich der unperfekte Zufall auswirkt, wenn ich nicht den perfekten Zufall gegenüberstelle? Das habe ich getan und also meine Argumentation gerade nicht auf dem "perfektem Zufall" aufgebaut sondern auf dem "Unterschied zwischen perfektem und unperfektem Zufall".

                      Die Behauptung war, nur durch perfekten Zufall bei der Zusammensetzung des Salts wären die Passwörter sicher gehasht. Das ist aber nicht der Fall, weil es eben nur darauf ankommt, dass zu jedem Passwort ein anderer Salt verwendet wird um die Anzahl der notwendigen Rainbow-Tables groß zu halten. Die nachgeschobene Behauptung, dass einem Angreifer das Spekulieren vereinfacht würde, ist bei dieser technischen Anwendung einfach neben der Sache weil betreffs des Hashes nicht spekuliert wird

                      Auch die Belege für Sicherheitsverletzungen durch schlechte Zufallsfunktionen waren neben der Sache. In allen diesen Fällen wurde fortlaufend etwas erzeugt, was vom Angreifer erraten werden musste und konnte - bei dem Passwort-Zeug muss aber der Salt vom Angreifer nicht erraten werden, just weil er den stets zusammen mit dem Hash bekommt.

                    2. 2.: Deine Rechnung ist von vorne bis hinten eine Milchmädchenrechnung, da du das Geburtstagsparadoxon und die dahinterstehende Erkenntnis völlig vernachlässigst. Es geht gar nicht darum, dass der gleiche Salt wie ein bestimmter erzeugt wird. Das potenzielle Problem entsteht dann, wenn zwei beliebige Salts übereinstimmen, und dafür gelten ganz andere Wahrscheinlichkeiten.

                      In meinem Text hast Du offensichtlich überlesen:

                      Erzeugt man Gruppen von 200 Salts dann ergäbe sich, dass durchschnittlich nach 58^16/(2*200) = 41000382247788109625347440 Versuchen eine Gruppe von 200 Salts erzeugt wurde, welche mindestens 2 identische Salts enthält.

                      Selbst wenn die Berechnungsmethode nicht perfekt sein sollte, es ist nicht die Methode für einen bestimmten Salt, sondern eben zwei beliebige, übereinstimmende Salts. Die für einen bestimmten Salt steht einen Absatz darüber.

                      1. Aloha ;)

                        Erzeugt man Gruppen von 200 Salts dann ergäbe sich, dass durchschnittlich nach 58^16/(2*200) = 41000382247788109625347440 Versuchen eine Gruppe von 200 Salts erzeugt wurde, welche mindestens 2 identische Salts enthält.

                        Selbst wenn die Berechnungsmethode nicht perfekt sein sollte, es ist nicht die Methode für einen bestimmten Salt, sondern eben zwei beliebige, übereinstimmende Salts.

                        Die Berechnungsmethode ist nicht nur nicht perfekt. Sie sagt schlicht und ergreifend nichts aus. Du hast nur zwei Zahlen, die mit dem Problem zu tun haben, mit einer Rechenoperation verknüpft.

                        Was du eigentlich möchtest, wenn überhaupt, ist die Wahrscheinlichkeit dafür, bei einer Menge von 200 Salts aus 58^16 zwei Gleiche zu finden. Das berechnest du über eine Gegenwahrscheinlichkeit, bei der die 200 nicht etwa der Nenner sind, sondern der Exponent im Nenner.

                        Deine Mengenbetrachtung ist schlichtweg völlig aussagelos, wenn dann brauchst du Wahrscheinlichkeitsrechnung.

                        Die Wahrscheinlichkeit, unter 23 Personen zwei mit dem selben Geburtstag zu finden, ist auch nicht 356/23. Genau darauf habe ich schon mehrfach hingewiesen, scheint dir aber egal zu sein.

                        Und nein, ich werde das nicht ausrechnen. Einfach deshalb, weil es völlug piepegal ist, um wie viel sicherer das ganze ist, solang es nur ohne Zusatzkosten sicherer ist.

                        Grüße,

                        RIDER

                        --
                        Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
                        # Twitter # Steam # YouTube # Self-Wiki # Selfcode: sh:) fo:) ch:| rl:) br:^ n4:? ie:% mo:| va:) js:) de:> zu:} fl:( ss:) ls:[
                  3. Hallo Indianerversteher,

                    deine schulmathematischen Überlegungen sind korrekt aber irrelevant. Die Analyse sicherheitsrelevanter Programmstrukturen erfolgt mit Mitteln, die weit über die Schulmathematik hinausgehen. Deshalb gibt es entsprechende Studiengänge, die auch bereits im ersten Studienjahr nur noch recht wenig mit der Schulmathematik zu tun haben.

                    Es könnte zum Beispiel sein, dass man herausfindet, dass bei Verwendung eines bestimmten Zufallsgenerators auf eine Zahl, die mit 2348973925868395 beginnt, mit einer Wahrscheinlichkeit von 0,042 % eine Zahl folgt, die auf 234348284 endet.

                    Ich kann mir dann zwar immer noch nicht vorstellen, wie man das ausnutzen könnte, aber man verwendet dann nicht mehr das bestmögliche System. Und genau das ist der Kritikpunkt an selbstgestrickten Lösungen. Sie können sehr sehr gut und sehr sehr sicher sein, aber eine eigene Lösung ist nicht die beste oder sicherste Variante.

                    Bis demnächst
                    Matthias

                    --
                    Pantoffeltierchen haben keine Hobbys.
                    ¯\_(ツ)_/¯
                    1. Hej Matthias,

                      Ich kann mir dann zwar immer noch nicht vorstellen, wie man das ausnutzen könnte, aber man verwendet dann nicht mehr das bestmögliche System. Und genau das ist der Kritikpunkt an selbstgestrickten Lösungen. Sie können sehr sehr gut und sehr sehr sicher sein, aber eine eigene Lösung ist nicht die beste oder sicherste Variante.

                      Und es ist auch unnötige Liebesmühe. Man nehme ein fertiges, getestetes, seit Jahren ständigen Angriffen ausgesetztes und über diese Zeit ständig weiter entwickeltes System und mache ganz früh Feierabend...

                      😉

                      Marc

                      --
                      Ceterum censeo Google esse delendam
                  4. Wer Fehler findet mag's korrigieren:

                    [0-9A-Za-z/.] -> 58 Symbole

                    Salts mit 16 Zeichen -> 16 Stellen

                    58^16 = 16400152899115243850138976256 mögliche Iterationen

                    Es gibt nur 2^32 − 1 = 4294967295 Möglichkeiten mit denen der Pseudo Random Number Generator (PRNG) von PHP geseedet werden kann [1]. Kenne ich den Seed, kann ich damit jede Ausgabe von rand vorhersagen. Dann ist es egal, ob du nur ein Zufallsbit erzeugst oder einen terrabyte großen Zufallswert. Ich kann den Wert mit dem Seed exakt reproduzieren.

                    Als Probe kann man den Seed einfach mal manuell mit srand(0) setzen. Die ersten drei Aufrufe von rand() liefern dann die Pseudozufallszahlen: 1178568022 1273124119 1535857466.

                    Du kommst mit rand nicht über 2^32 - 1 Möglichkeiten hinaus einen Salt zu bilden.


                    1. https://www.sjoerdlangkemper.nl/2016/02/11/cracking-php-rand/ ↩︎

                    1. Es gibt nur 2^32 − 1 = 4294967295 Möglichkeiten mit denen der Pseudo Random Number Generator (PRNG) von PHP geseedet werden kann [^1]. Kenne ich den Seed, kann ich damit jede Ausgabe von rand vorhersagen. Dann ist es egal, ob du nur ein Zufallsbit erzeugst oder einen terrabyte großen Zufallswert. Ich kann den Wert mit dem Seed exakt reproduzieren.

                      Der Indianerversteher hat nach nach dem konkreten Angriffszenario gefragt.

                      Ist es nicht so, dass du dafür den seed() setzen musst bevor die salts erzeugt werden? Also Zugriff auf den Server brauchst? Dann hätte der Betreiber aber ganz andere Probleme, die mit dem Skript nichts zu tun haben.

                      Als Probe kann man den Seed einfach mal manuell mit srand(0) setzen. Die ersten drei Aufrufe von rand() liefern dann die Pseudozufallszahlen: 1178568022 1273124119 1535857466.

                      1. Siehe oben

                      2. Müssten nicht, um die Salts zu vorherzusagen, alle salts nacheinander erzeugt worden sein- und zwar ohne dass PHP neu gestartet wurde? Ist das bei dem Passwortscript nicht völlig unwahrscheinlich? Wer tippt den so schnell?

                      3. Ist es nicht so, dass der seed auch wieder ergänzt wird

                      Du kommst mit rand nicht über 2^32 - 1 Möglichkeiten hinaus einen Salt zu bilden.

                      Meinst du jetzt die größte Zahl, die mit rand erzeugt werden kann?

                      In seinem Skript hat der Indianerversteher doch gezeigt wie er es macht. Er verwendet rand() pro Stelle des hashes, also mehrfach.

                      Meinst du damit aber nochmals die "4294967295 Möglichkeiten mit denen der Pseudo Random Number Generator (PRNG) von PHP geseedet werden kann", dann gelten ja wieder sehr spezielle Voraussetzungen bei denen ich einen Zusammenhang mit dem eigentlichen Skript verneinen würde.

                      Ist es nicht so, dass bei einem Lauf unter PHP ab 5.3 statt der auf rand() zurückgreifenden die originalen PHP-Funktionen password_hash() und password_verify() benutzt werden, dass also deine Einwände nur dann gelten könnten, wenn das System ohnehin unsicher ist?

                      Ist es nicht auch so, dass ein Angreifer, der den Angriff gegen mehrere hashes führen will, um die Passwörter zu ermitteln, ohnehin den salt ohnehin kennt, weil der, und der Indianerversteher hat da mehrfach beschrieben, der salt direkt dort steht, wo auch der hash steht? Ist es also nicht so, dass der demnach bekannte salt gar nicht erraten werden muss?

                      Die Rainbowtables sind bei dem verwendeten Algorithmus zudem wahrscheinlich auch ein sehr akademisches Argument - oder hat der Indianerversteher md5() als Algorithmus verwendet und keine Runden gedreht? Wäre schön, man könnte ihn fragen.

                      Ich denke schon dass du "Beweise" für die angebliche Unsicherheit des Skriptes anbringst, die bei Hinsehen keine "Beweise" dafür sind.

                      1. In seinem Skript hat der Indianerversteher doch gezeigt wie er es macht. Er verwendet rand() pro Stelle des hashes, also mehrfach.

                        Damit vergrößert sich aber nicht der Zufallsraum. rand ist eine deterministische Funktion, die ausschließlich von dem Startwert abhängt, dem sogenannten Seed. Es gibt 2^32-1 mögliche Startwerte. Wenn rand 16 mal aufgerufen wird, wird die Sequenz nicht zufälliger. Die 16 Zufallswerte sind vollständig durch den Startwert vorherbestimmt. Egal wie oft man rand aufruft, am Ende bleiben maximal 2^32-1 mögliche Salts, die man für eine fixe Länge generieren kann. Er hätte rand auch nur ein einziges mal aufrufen können, das hätte das System nicht unsicherer, sondern nur schneller gemacht. Das wiederholte Aufrufen von rand hat defakto nicht den geringsten Einfluss auf die Anzahl der möglichen Salts, die man damit generieren kann.

                        Ein kryptografisch sicherer Zufallsgenerator, hat diese Einschränkung nicht. Damit lassen sich mehr Zufallszahlen als die angesprochenen 2^32 erzeugen. OWASP empfiehlt mindestens 8^32, besser 8^64 Möglichkeiten. Mit einem kryptografisch sicheren Zufallsgenerator lassen sich so viele Möglichkeiten erzeugen, mit Pseudozufall bleibt man weit darunter. Das ist ein enormer Unterschied, um das mal in ein Verhältnis zu setzen: (2^32 / 8^32) ~= 7.8886091e-31, (2^32 / 8^64) ~= 9.9568244e-60. Da liegt Indianerverstehers Schätzung mit "20% schlechter" völlig abseits der Realtiät.

                        Ein Angreifer, der über ausreichend Ressourcen verfügt, kann das nutzen, um eine Regenbogen-Tabelle oder eine Lookup-Tabelle für die 2^32 möglichen Salts vorzuberechnen. Wenn er dann in den Besitz eines Passwort-Hashes gelangt, kann er die Tabelle nutzen, um eine Passwort-Kollision zu finden. Das ist ein erheblicher Time/Space-Tradeoff zugunsten des Angreifers.

                        Eine andere Angriffsfläche bietet der initiale Seed, der muss ja schließlich auch aus einer Zufallsquelle gespeist werden. Das ist häufig eine Kombination aus Serverzeit, Prozess-ID und noch ein paar anderen Faktoren. Das sind scheinbar schwer von außen zu ermittelnde Faktoren, aber sie liefern trotzdem deutlich weniger Entropie als ein Hardware-Device, das bspw. akkustisches Rauschen aus der Umgebung aufnimmt, das bei kryptografischen Zufallsgeneratoren eingesetzt wird.

                        1. Bitte weiche nicht aus und beantworte vor allem auch die Fragen, die mit "Ist es nicht so," beginnen.

                          1. Hej Mitleser,

                            Bitte weiche nicht aus und beantworte vor allem auch die Fragen, die mit "Ist es nicht so," beginnen.

                            Wozu? Was soll das bringen?

                            Zumal mir diese Fragen rhetorischer Natur zu sein scheinen, mindestens aber provokativ. Keine guten voraussetzungen, wenn man wirklich antworten möchte.

                            Aber ich finde es ist aus der Art der Frage erkennbar, dass du schon eine Antwort darauf hast, denn es sind überhaupt keine Fragen, sondern verklausulierte Feststellungen.

                            Marc

                            --
                            Ceterum censeo Google esse delendam
                          2. Hallo Mitleser,

                            Bitte weiche nicht aus und beantworte vor allem auch die Fragen, die mit "Ist es nicht so," beginnen.

                            1UP ist nicht ausgewichen, sondern hat mindestens einige deiner Fragen beantwortet. Das hat er nicht im Zitat-Stil getan, wie das hier oft üblich ist, nichtsdestotrotz hat er Antworten gegeben.

                            Welcher Teil ist dir denn unklar geblieben?

                            LG,
                            CK

                            1. Welcher Teil ist dir denn unklar geblieben?

                              1. Ist es nicht so, dass bei einem Lauf unter PHP ab 5.3 statt der auf rand() zurückgreifenden die originalen PHP-Funktionen password_hash() und password_verify() benutzt werden, dass also deine Einwände nur dann gelten könnten, wenn das System ohnehin unsicher ist?

                              Quelltext zur Gedächnisstütze:

                              if (! function_exists('password_hash') ) {
                                  function create_salt ($l=22, $allowed='1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJLKMNOPQRSTUVWXYZ./'){
                                      $salt='';
                                      for ( $i = 0; $i < $l; $i++ ) {
                                    	    $salt .= $allowed{rand(0,strlen($allowed)-1)};
                                      }
                                      return $salt;
                                  }
                                  function password_hash ($str, $dummy) {
                                  	if (CRYPT_BLOWFISH && ($hash=crypt($str,'$2y$10$'.create_salt().'$'))){
                              	      return $hash;
                              	   } elseif (CRYPT_SHA512 && ($hash=crypt($str,'$6$rounds=5000$'.create_salt(16).'$') ) ) {
                                     return $hash;
                              	} elseif (CRYPT_BLOWFISH && ($hash=crypt($str,'$2a$10$'.create_salt().'$')) ) {
                              	  return $hash;
                              	} else {
                              	  return false;
                                      }
                                  }
                                  function password_verify ($password, $hash) {
                                      return ( $hash == crypt($password, $hash) );
                                  }
                                  function password_needs_rehash ($password, $dummy) {
                                      return ('$2y$10$' != substr($password, 0, 7) );
                                  }
                              }
                              
                              1. Ist es nicht auch so, dass ein Angreifer, der den Angriff gegen mehrere hashes führen will um die Passwörter zu ermitteln, den salt ohnehin kennt, weil der, und der Indianerversteher hat das mehrfach beschrieben, der salt direkt dort steht, wo auch der hash steht? Ist es also nicht so, dass der demnach bekannte salt gar nicht erraten werden muss?

                              2. Ist es nicht so, dass du dafür den seed() setzen musst bevor die salts erzeugt werden? Also Zugriff auf den Server brauchst?

                              3. Es wurde (siehe Quelltext) in einer beachtlichen Anzahl von Runden zum hashen BLOWFISH und SHA512 verwendet. Ganz spitzfindig frage ich nochmal, wo und und zu welchen Kosten wie Du die Rainbowtables (deren Nützlichkeit Du behauptest - siehe Frage 2) 4.a) auch nur für einen Salt erzeugen und 4.b) speichern willst. Die entstehenden Datenmengen sind nämlich gewaltig.

                              (marctrix)

                              Aber ich finde es ist aus der Art der Frage erkennbar, dass du schon eine Antwort darauf hast, denn es sind überhaupt keine Fragen, sondern verklausulierte Feststellungen.

                              Nun, die könnten ja falsch sein. Sind diese "verklausulierte Feststellungen" aber richtig, dann ist belegt, dass die Gründe, aus denen heraus 1unitedpower das Skript als "unsicher" behauptet, unzutreffend sind. Und zwar alle.

                              1. Welcher Teil ist dir denn unklar geblieben?

                                1. Ist es nicht so, dass bei einem Lauf unter PHP ab 5.3 statt der auf rand() zurückgreifenden die originalen PHP-Funktionen password_hash() und password_verify() benutzt werden, dass also deine Einwände nur dann gelten könnten, wenn das System ohnehin unsicher ist?

                                Ja, das habe ich auch in meinem ersten Beitrag schon so ausgesagt.

                                1. Ist es nicht auch so, dass ein Angreifer, der den Angriff gegen mehrere hashes führen will um die Passwörter zu ermitteln, den salt ohnehin kennt, weil der, und der Indianerversteher hat das mehrfach beschrieben, der salt direkt dort steht, wo auch der hash steht? Ist es also nicht so, dass der demnach bekannte salt gar nicht erraten werden muss?

                                Wie schon erklärt, kann der Angreifer schon bevor er in den Besitz eines Salt+Hash-Paares gelangt, eine Lookup-Tabelle konstruieren. Wenn er dann schließlich in den Besitz eines solchen Paares kommen sollte, profitiert er von dem von mir beschriebenen Laufzeit-/Speicherplatz-Tradeoff.

                                1. Ist es nicht so, dass du dafür den seed() setzen musst bevor die salts erzeugt werden? Also Zugriff auf den Server brauchst?

                                Nein, irgendein Seed wird von PHP zufällig ausgewählt. In dem von mir beschriebenen Szenario macht der Angreifer sich zu nutzen, dass es verhältnismäßig wenig potenzielle Seeds gibt.

                                1. Es wurde (siehe Quelltext) in einer beachtlichen Anzahl von Runden zum hashen BLOWFISH und SHA512 verwendet. Ganz spitzfindig frage ich nochmal, wo und und zu welchen Kosten wie Du die Rainbowtables (deren Nützlichkeit Du behauptest - siehe Frage 2) 4.a) auch nur für einen Salt erzeugen und 4.b) speichern willst. Die entstehenden Datenmengen sind nämlich gewaltig.

                                4.a. Ich kann alle Seeds der Reihe nach aufzählen, dann starte ich für jeden Seed den Salting-Algorithmus aus dem Skript. So komme ich an alle maximal 2^32-1 möglichen Salts.

                                4.b. Ja, die Datenmengen sind gewaltig. Aber Speicherplatz ist günstig und wird ständig günstiger. Wenn dazu kriminelle Energie im Spiel ist, wird der Angreifer möglicherweise nicht mal den Marktpreis für den Speicherplatz bezahlen, sondern ein illegales Bot-Netzwerk dafür benutzen.

                                Man tut gut daran, davon auszugehen, dass einem potenziellen Angreifer deutlich mehr Ressourcen zur Verfügung stehen als einem selsbt.

                                Aber ich finde es ist aus der Art der Frage erkennbar, dass du schon eine Antwort darauf hast, denn es sind überhaupt keine Fragen, sondern verklausulierte Feststellungen.

                                Nun, die könnten ja falsch sein. Sind diese "verklausulierte Feststellungen" aber richtig, dann ist belegt, dass die Gründe, aus denen heraus 1unitedpower das Skript als "unsicher" behauptet, unzutreffend sind.

                                Ich hätte besser kryptografisch schwach anstatt kryptografisch unsicher geschrieben, das wäre die präzisere Wortwahl gewesen. Sicher ist kein qualitatives Merkmal, sondern ein quantitatives, wenn auch schwierig zu beziffern. Je weniger Angriffsoberfläche ein Skript bietet, desto sicherer würde ich es einstufen. Salting mit Pseudozufall ist um Größenordnungen besser als überhaupt kein Salting. Salting mit kryptografisch sicherem Zufall ist um Größenordnungen besser als kryptografisch schwaches Salting. Die Investionskosten für kryptografisch schwaches bzw. starkes Salting unterscheiden sich aber nicht, wieso würde ich mich also mit weniger zufrieden geben?

                                1. Wie schon erklärt, kann der Angreifer schon bevor er in den Besitz eines Salt+Hash-Paares gelangt, eine Lookup-Tabelle konstruieren. Wenn er dann schließlich in den Besitz eines solchen Paares kommen sollte, profitiert er von dem von mir beschriebenen Laufzeit-/Speicherplatz-Tradeoff.

                                  Der Angreifer konstruiert nach Deiner Darlegung also für 2^32-1 (also 4.294.967.295) mögliche Startwerte des Seeds die Rainbowtables vor um dann, wenn und falls er jemals an die Daten kommt schneller zu sein, weil er dann 200 Rainbowtables erzeugen müsste?

                                  4.b. Ja, die Datenmengen sind gewaltig. Aber Speicherplatz ist günstig und wird ständig günstiger. Wenn dazu kriminelle Energie im Spiel ist, wird der Angreifer möglicherweise nicht mal den Marktpreis für den Speicherplatz bezahlen, sondern ein illegales Bot-Netzwerk dafür benutzen.

                                  Soso. Damit kann er sicherlich gewaltige Datentransferraten erzielen um die Exabyte großen Partitionen der Tabellen transportieren zu können. Beziffer doch mal den Bedarf an Rechenleistung und Speicher. Vermutlich muss er alles beschäftigen, "was er kriegen" kann und die Cloudabteilungen von Amazon, Google und Microsoft sind dann dennoch auf Jahrzehnte, wenn nicht Jahrtausende ausgelastet. Außerdem wird Siliziumoxyd ("Sand, Gestein") erst knapp und dann so teuer wie Gold. Wir reden schließlich von sha512 und blowfish-Algos, welche dafür konstruiert wurden, dem bei MD5 sehr realen Problem der "Knackbarkeit mit Rainbowtables" effektiv entgegenzuwirken in diese Möglichkeit verteuert wird.

                                  Ob Hacker oder nicht: Über vier Milliarden Rainbowtables für sha512 und/oder blowfish zu erzeugen um dann an vielleicht (der Server muss ja trotzdem noch auf anderem Wege gehackt werden) 200 Passwörter heranzukommen ist völlig abstrus. Und zu einem Zeitpunkt, an dem es nicht mehr ganz vollständig abstrus, sondern schon nur noch einer Großmacht möglich wäre, ist zu befürchten, dass der Server, auf dem die 200 Passwörter mal gespeichert waren, seit "geologischen Zeiträumen" nur noch Staub ist.

                              2. Nun, die könnten ja falsch sein. Sind diese "verklausulierte Feststellungen" aber richtig, dann ist belegt, dass die Gründe, aus denen heraus 1unitedpower das Skript als "unsicher" behauptet, unzutreffend sind. Und zwar alle.

                                Bevor gefragt wird, wieso denn alle unzutreffend seien:

                                In diesem Beitrag ist der Indianerversteher auf die drei anderen Behauptungen eingegangen und hat dargelegt:

                                1. dass die aussagekräftigen Fehlermeldungen beim Login nur im Debugmodus angezeigt werden,
                                2. dass es Sache der Serverkonfiguration ist, für eine gesicherte Übertragung zu sorgen,
                                3. dass es ebenfalls Sache der Serverkonfiguration ist, dafür zu sorgen, dass dem Sessioncookie die Information mitgegeben wird, dass der Browser es JavaScript nicht zur Verfügung stellen möge.

                                Das blieb ohne sachbezogene Entgegnung. Offenbar ist die Richtigkeit dieser Darlegungenen auch nicht anzweifelbar.

                                1. Nun, die könnten ja falsch sein. Sind diese "verklausulierte Feststellungen" aber richtig, dann ist belegt, dass die Gründe, aus denen heraus 1unitedpower das Skript als "unsicher" behauptet, unzutreffend sind. Und zwar alle.

                                  Bevor gefragt wird, wieso denn alle unzutreffend seien:

                                  In diesem Beitrag ist der Indianerversteher auf die drei anderen Behauptungen eingegangen und hat dargelegt:

                                  1. dass die aussagekräftigen Fehlermeldungen beim Login nur im Debugmodus angezeigt werden

                                  Damit hat er recht, auf die entsprechenden Code-Zeilen hat er verwiesen. Für dieses Argument habe ich nur seine Testseite konsultiert, nicht den Code.

                                  1. dass es Sache der Serverkonfiguration ist, für eine gesicherte Übertragung zu sorgen,
                                  2. dass es ebenfalls Sache der Serverkonfiguration ist, dafür zu sorgen, dass dem Sessioncookie die Information mitgegeben wird, dass der Browser es JavaScript nicht zur Verfügung stellen möge.

                                  Das ist für mich ein klarer Fall von das eine zu tun ohne das andere zu lassen. Man kann diese Probleme sowohl auf Ebene der Server-Konfiguration als auch auf Ebene der Anwendung angehen. Macht man beides, verkleinert man die Angriffsoberfläche. Auf der Testseite wird keine der beiden Möglichkeiten genutzt.

                                    1. dass es Sache der Serverkonfiguration ist, für eine gesicherte Übertragung zu sorgen,
                                    2. dass es ebenfalls Sache der Serverkonfiguration ist, dafür zu sorgen, dass dem Sessioncookie die Information mitgegeben wird, dass der Browser es JavaScript nicht zur Verfügung stellen möge.

                                    Das ist für mich ein klarer Fall von das eine zu tun ohne das andere zu lassen. Man kann diese Probleme sowohl auf Ebene der Server-Konfiguration als auch auf Ebene der Anwendung angehen. Macht man beides, verkleinert man die Angriffsoberfläche. Auf der Testseite wird keine der beiden Möglichkeiten genutzt.

                                    Wirklich? Er gibt diese URL an:

                                    versuche doch auch

                                    Das Ergebnis spricht dafür, dass er eine der beiden Möglichkeiten nutzt.Man muss sich jedenfalls ziemlich anstrengen um die Benutzerdaten unverschlüsselt zu übertragen. Auch die Session-Id wird vom Server an den Client nur via https gesendet.

                                    Was jetzt die Nutzung von http_only für das Sessioncookie betrifft: da steht '/Tests' und der Benutzername sowie das Passwort auf der Seite mit dem Login... Würdest Du Dir dann die Mühe machen und für erweiterte Sicherheit zu sorgen?

                                    An anderer Stelle tut er es schließlich - dem Vergleich nach nicht mal schlecht.

                                    1. Hallo Mitleser, hallo 1unitedpower,

                                      ich würde es gut finden, dieses Gespräch zumindest in dieser Form zu beenden. Hier kann aus meiner Sicht nichts gutes mehr bei rumkommen.

                                      Bis demnächst
                                      Matthias

                                      --
                                      Pantoffeltierchen haben keine Hobbys.
                                      ¯\_(ツ)_/¯
                                      1. Hier kann aus meiner Sicht nichts gutes mehr bei rumkommen.

                                        Ob nun Gutes oder Schlechtes. Ich denke inhaltlich das nunmehr auf jeden Fall erschöpfend abgearbeitet.

                                        1. Hallo Mitleser,

                                          Ich denke inhaltlich das nunmehr auf jeden Fall erschöpfend abgearbeitet.

                                          Nicht nur inhaltlich, Jörg.

                                          LG,
                                          CK

                  5. Hej Indianerversteher,

                    Mit der Bitte um zukünftige Beachtung: Überschriften bitte nutzen, um Texte inhaltlich zu strukturieren. Nicht um andere virtuell anzubrüllen.

                    Danke!

                    Marc

                    --
                    Ceterum censeo Google esse delendam
                    1. Hallo,

                      er nimmt doch bloß hashtags…

                      😉

                      Gruß
                      Kalk

              2. dass @1unitedpower da eine sinnvolle Argumentationskette mit entsprechenden Belegen und Querverweisen zu best practices aufgezogen hat, die es tatsächlich am besten mal irgendwann ins Wiki schaffen sollte.

                Sorry: Da bestehen ernsthafte und argumentativ unterlegte Zweifel - bis hin zum Beweis der partiellen Unrichtigkeit seines Vortrages, der Überzogenheit der "best practices" und der Tatsache dass manche seiner Quellen "nicht gänzlich das ist, was von wem auch immer darüber gedacht oder vorgemacht wird."

                1. Aloha ;)

                  dass @1unitedpower da eine sinnvolle Argumentationskette mit entsprechenden Belegen und Querverweisen zu best practices aufgezogen hat, die es tatsächlich am besten mal irgendwann ins Wiki schaffen sollte.

                  Sorry: Da bestehen ernsthafte und argumentativ unterlegte Zweifel [... und so weiter und so fort].

                  Behalte deine Zweifel. Sie überzeugen mich nicht.

                  Im Gegenteil. Ich bin viel eher geneigt, dir Lobbyismus in der Sache zu unterstellen als @1unitedpower in seinen Aussagen.

                  Das hat auch viel mit dem zu tun, wie du dich auf Einzelheiten stürzt und daran verbeißt, gleichzeitig aber offenbar nicht in der Lage bist, die Richtigkeit im Großen und Ganzen anzuerkennen.

                  Grüße,

                  RIDER

                  --
                  Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
                  # Twitter # Steam # YouTube # Self-Wiki # Selfcode: sh:) fo:) ch:| rl:) br:^ n4:? ie:% mo:| va:) js:) de:> zu:} fl:( ss:) ls:[
                  1. aber offenbar nicht in der Lage bist, die Richtigkeit im Großen und Ganzen anzuerkennen.

                    Ich soll die Richtigkeit von etwas anerkennen, für das es keinen ernsthaften und brauchbaren Versuch gibt, dessen Richtigkeit zu beweisen und dass unter dem Umstand, dass auf meine Argumente nicht eingegangen wird?

                    Ich bin also zu blöd, "die Richtigkeit im Großen und Ganzen anzuerkennen" ?**

                    Da seh ich aber ganz anders:

                    • Weder Du noch 1united beschreibt das Szenario mit dem der Hacker vorgeht.

                    • Weder Du noch 1united geht mit einem einzigen Wort darauf ein, dass genau dann, wenn für einen Angriff auf die Passwörter eine Rainbow-Tabelle nötig wäre, ja die Hashes vorliegen müssten. Dann liegen aber auch die Salts vor! Dann aber braucht der Angreifer gar nicht spekulieren, welcher Salt als nächster kommt, weil er den dann ja auch hat. Nur wenn er spekulieren müsste hätte er bei der Verwendung "nicht kryptographischen" Zufalls bei der Erzeugung der Salts einen Vorteil - das ist doch nun wirklich nicht schwer zu verstehen!

                    Statt dessen kommst Du mir mit "Das hat auch viel mit dem zu tun, wie du dich auf Einzelheiten stürzt und daran verbeißt, gleichzeitig aber offenbar nicht in der Lage bist, die Richtigkeit im Großen und Ganzen anzuerkennen"?

                    Darin sind genau so viele echte Argumente enthalten, wie sie in der ganzen Diskussion meinen Darlegungen entgegengestellt wurden.

                    Nämlich kein einziges.

                    Kommt und gebt mir [-1] soviel Ihr wollt und findet Euch und Eure Pseudo-Argumentation gegenseitig so toll wie Ihr es wollt. Und wenn es Euch so passt, dann schreibt den widerlegten Unsinn halt auch ins SelfWiki. Ist ja das Eurige… und es kann mir eigentlich egal sein wenn Ihr Euch par tout "bis auf die Knochen" blamieren wollt.

                    Also macht's doch einfach!

                    1. Aloha ;)

                      Statt dessen kommst Du mir mit "Das hat auch viel mit dem zu tun, wie du dich auf Einzelheiten stürzt und daran verbeißt, gleichzeitig aber offenbar nicht in der Lage bist, die Richtigkeit im Großen und Ganzen anzuerkennen"?

                      Darin sind genau so viele echte Argumente enthalten, wie sie in der ganzen Diskussion meinen Darlegungen entgegengestellt wurden.

                      Nämlich kein einziges.

                      Nein, da ist kein sachliches Argument drin. Sondern lediglich die Feststellung, dass du dich an einer Einzelheit verbeißt, weil du offenbar nicht in der Lage bist, die Gesamtheit der Aussagen zu widerlegen, obwohl du das gerne würdest.

                      Wärst du in der Lage, anzuerkennen, dass die Aussagen in ihrer Gesamtheit völlig in die richtige Richtung gehen, dürfte es dir auch nicht schwerfallen, anzuerkennen, dass ein kryptographisch sicherer Zufallszahlengenerator nicht schadet, sondern eher noch nützt, um die Sicherheit um ein weiteres Quäntchen nach oben zu treiben.

                      Du tust ja in deinen Postings gerade so, als sei das mit den kryptographisch sicheren Salts das einzige, was an deinem System bemängelt wurde, und das ja zu unrecht, weil man das zwar machen kann, aber nicht rechnerisch belegbar muss, wenn man aktuelle Rechenleistungen zugrunde legt.

                      Grüße,

                      RIDER

                      --
                      Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
                      # Twitter # Steam # YouTube # Self-Wiki # Selfcode: sh:) fo:) ch:| rl:) br:^ n4:? ie:% mo:| va:) js:) de:> zu:} fl:( ss:) ls:[
                      1. Nein, da ist kein sachliches Argument drin. Sondern lediglich die Feststellung, dass du dich an einer Einzelheit verbeißt, weil du offenbar nicht in der Lage bist, die Gesamtheit der Aussagen zu widerlegen, obwohl du das gerne würdest.

                        Dann wiederhole ich jetzt eben auch meine Darlegungen…

                        • Das Plus an Sicherheit gibt es nicht. In PHP vor 5.3 gab es keine Möglichkeit, kryptographisch sicheren Zufall zu erzeugen. Insbesondere nicht random_int(). In PHP 5.3 und später wurden meine Ersatzfunktionen gar nicht benutzt und konnten ergo die Sicherheit gar nicht mindern. Die Sicherheit der mit meinem Skript gehashten Passwörter war also stets auf dem jeweiligen "Stand der Technik" und wird es so lange bleiben wie PHP diesen mit den password_*-Funktionen unterstützt. Die Behauptung war aber, mein Skript sei unsicher - und diese Behauptung ist falsch.

                        • Die Behauptung war ferner, nur durch perfekten Zufall bei der Zusammensetzung des Salts wären die Passwörter sicher gehasht. Das ist aber nicht der Fall, weil es eben nur darauf ankommt, dass zu jedem Passwort (Genauer: Benutzer) ein anderer Salt verwendet wird um die Anzahl der notwendigen Rainbow-Tables groß zu halten. Die nachgeschobene Behauptung, dass einem Angreifer das Spekulieren vereinfacht würde, ist bei dieser technischen Anwendung einfach neben der Sache weil betreffs des Salts und des Hashes gar nicht spekuliert wird.

                        • Auch die Belege für Sicherheitsverletzungen durch schlechte Zufallsfunktionen waren neben der Sache. In allen diesen Fällen wurde fortlaufend etwas erzeugt, was vom Angreifer erraten werden musste und konnte - bei dem Passwort-Zeug muss aber der Salt vom Angreifer nicht erraten werden, just weil er den stets zusammen mit dem Hash bekommt.

                        • Die anderen Behauptungen betrafen schlechte oder falsche Konfiguration des Servers und das mein Skript auf alten Versionen von PHP laufen kann. Was, bitte, kann ich dafür wenn jemand SOWAS tut?

            3. Bei einem Brut-Force Angriff von außen ist es egal weil der Hash und damit der Salt den Angreifer gar nicht interessiert.

              Wenn der Pseudozufallsgenerator nicht genügend Entropie liefert, dann muss ein Angreifer keinen Brute-Force-Angriff ausführen, er kann die Schwachstelle im Zufallsalgorithmus nutzen, um eine Regenbogen-Tabelle zu konstruieren und damit zu attackieren. Wikipedia führt eine Liste prominenter Beispiele solcher Schwachstellen.

              Nicht alles, was andere veröffentlichen, ist automatisch richtig.

              Nein, aber die Mathematik dahinter ist recht eindeutig. Je weniger Entropie ein Zufallsgenerator liefert, desto einfacherer lässt sich der Lösungsraum verkleinern - einfach im Sinne der Komplexitätstheorie.

              1. Wikipedia führt eine Liste prominenter Beispiele solcher Schwachstellen.

                ... die sich sämtlich inhaltlich und technisch aber sehr wesentlich von einem salted password hashing unterscheiden. Das reicht also nicht für ein positives Argument.

                eine Regenbogen-Tabelle

                braucht man für jeden salt. Da Regenbogentabellen mit einem brute-force-Angriff von außen nichts zu tun haben kommt nur der Angriff auf bekannte hashes in Betracht.

                Die Kernfrage ist, wozu ich einen salt mittels kryptographischem Zufall bauen soll, wenn doch klar ist, dass die einzige Anwendung, bei der ein kryptographischer salt Vorteile bringen könnte, voraussetzt, dass der hash bekannt ist. Mithin müsste dem Angreifer also zwar der hash nicht jedoch der salt bekannt sein, was im Hinblick darauf, dass beide in einem String stehen, "ziemlich selten wäre" - oder?

                1. Aloha ;)

                  Die Kernfrage ist, wozu ich einen salt mittels kryptographischem Zufall bauen soll, wenn doch klar ist, dass die einzige Anwendung, bei der ein kryptographischer salt Vorteile bringen könnte, voraussetzt, dass der hash bekannt ist.

                  Für mich ist die Kernfrage immer noch, warum an der Stelle ein ungelegtes Ei weiterdiskutiert wird.

                  Eine renommierte Quelle nennt das Kriterium.

                  Das sollte erstmal genügen, um eine Empfehlung auszusprechen.

                  Ob das Kriterium absolut notwendig ist, oder nur hilfreich, oder vielleicht auch nur nicht schädlich, ist doch eher nachrangig wichtig.

                  Zumindest im Sinne eines konstruktiven Weiterkommens.

                  Grüße,

                  RIDER

                  --
                  Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
                  # Twitter # Steam # YouTube # Self-Wiki # Selfcode: sh:) fo:) ch:| rl:) br:^ n4:? ie:% mo:| va:) js:) de:> zu:} fl:( ss:) ls:[
                  1. Eine renommierte Quelle nennt das Kriterium.

                    Dann so: Die Webseite der angeblich renommierte Quelle belegt nicht, dass diese "renommiert" ist. Ich sehe keine Verbindung zu bekannten Experten oder Firmen - aber viel Merchandising (Werbemittel wie Lanyards und T-Shirts, Konferenzen) und Annual Reports welche den Schluss zulassen, dass mit eben diesem Merchandising Geld an den Mitgliedern verdient wird.

      3. Wenn ein Login-Versuch fehlschlägt, antwortet das Skript mit einer präzisen Fehlerbeschreibung:

        Ja. Aber nur im Debug-Modus, der im Config-Teil abschaltbar ist:

        Quelltext (so seit 2016):

        (login.php)

        $HashedPassword = getHashedPassword( $_POST['username'] );
        if (false == $HashedPassword ) {
            if ( DEBUG_MODUS ) {
                error_log('Falscher Benutzer:' . $_POST['username']);
                show_login($_POST['username'], 'Den Benutzer gibt es nicht.');
            } else {
                if ( USE_ERROR_LOG_FOR_LOGIN_ERRORS ) { error_log( 'ftx_login_error' ); }
                show_login( $_POST['username'], 'Fehler bei der Anmeldung' );
            }
            exit;
        }
        // Schritt 2:  Überprüfen des Passwortes
        if (! password_verify ( trim( $_POST['passwort'] ), $HashedPassword ) ) {
            if ( DEBUG_MODUS ) {
                error_log( 'falsches Passwort' );
                show_login($_POST['username'], 'Falsches Passwort.');
            } else {
                if ( USE_ERROR_LOG_FOR_LOGIN_ERRORS ) { error_log('ftx_login_error'); }
                show_login( $_POST['username'], 'Fehler bei der Anmeldung' );
            }
            exit;
        }
        

        auth_config.php:

          // Befindet sich das System im Debug-Modus?
          define( 'DEBUG_MODUS', true );
          // Einstellung für Setup/Entwicklung/Debugging:
          if( DEBUG_MODUS ) {  error_reporting( E_ALL ); } else { error_reporting( NULL ); };
        

        Weiterhin sollte beim Session-Start die Option 'cookie_httponly' => true gesetzt werden, damit das Cookie nicht von JavaScript ausgelesen werden kann.

        Soweit ich das weiß ist das eine Einstellung, welche grunsätzlich schon in der PHP.ini aktiviert werden sollte. Nicht im Skript.

        Das Skript funktioniert sowohl mit HTTPS als auch mit unverschlüsseltem HTTP.

        Auch das ist m.E. nicht Sache des Skriptes sondern der Serverkonfiguration. Wenn das Skript gestartet wurde, dann sind die Daten bereits übertragen und ggf. für einen Angreifer sichtbar. Dann noch in Schönheit zu sterben ist nutzlos.

        Für die PHP 5.3 Kompatibilität … Im Code wird die PHP-Funktion rand dafür benutzt ...

        (Dann folgt ein Auszug aus dem Handbuch, der random_int() empfiehlt.

        Du kritisierts die Verwendung von rand() aber das mir nahe gelegte random_int() gibt es erst seit PHP 7. Wieso sollte ich also random_int() verwenden um die Kompatibilität zu PHP 5.3 herzustellen? Weil der Syntaxfehler dann das Ausführen verhindert?

        1. Aloha ;)

          Du kritisierts die Verwendung von rand() aber das mir nahe gelegte random_int() gibt es erst seit PHP 7. Wieso sollte ich also random_int() verwenden um die Kompatibilität zu PHP 5.3 herzustellen? Weil der Syntaxfehler dann das Ausführen verhindert?

          Ich habe den grundsätzlich falschen Ansatz mal für dich markiert.

          Grüße,

          RIDER

          --
          Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
          # Twitter # Steam # YouTube # Self-Wiki # Selfcode: sh:) fo:) ch:| rl:) br:^ n4:? ie:% mo:| va:) js:) de:> zu:} fl:( ss:) ls:[
          1. Nochmal:

            Die Kompatibilität zu PHP 5.3 wurde(sic!) in der 2016er Version dann und nur dann hergestellt, wenn es password_hash() nicht gibt. PHP 5.3 gibt es diese Funktionen.

            Logische Folge: Die Kompatibilität zu PHP 5.3 wurde nur in Versionen kleiner als 5.3 hergestellt.

            Mir wurde auch nahe gelegt, für die Ersatzfunktionen random_int() zu verwenden, welches erst ab PHP 7.0 verfügbar ist.

            Das kann, wie beschrieben, nicht funktionieren.

            Zur Sicherheit:

            • Wenn das Skript mit PHP 5.2 oder früher interpretiert wurde, dann wurden die Passwörter mit meinen Ersatzfunktionen deutlich sicherer gehascht als mit den damaligen Möglichkeiten von PHP.
            • Wenn das Skript mit PHP ab Version 5.3 ausgeführt wurde, dann wurden und werden die Passwörter mit den Password-Funktionen von PHP gehasht. Damit hat mein Skript beim Ablauf in diesen Version die Sicherheit zwar nicht verbessert - aber ganz gewiss auch nicht verschlechtert.
            • Und wieso soll ich, bitte, dafür verantwortlich sein wenn anno 2019 jemand meine Skript auf veralteten Installationen mit nicht mehr unterstütztem PHP und womöglich nicht mit (vollständig sicher konfiguriertem) HTTPS und auch sonst nicht optimal konfigurierten (session.cookie_httponly=0) Servern laufen lässt und mir die Vorhaltung machen lassen, dass mein Skript unsicher sei, weil DAS geht?