Das gegenstück sozusagen.
Dort hab ich auch angefangen. Kanns nur empfehen.
Beiträge von cottton
-
-
Ich denke das einfachste wäre die Google Suche zu nutzen/einzubauen, die dann auf der eigenen Domain sucht.
Hat ja bestimmt schon mal jeder gesehen. Wird aber bestimmt nicht jeder haben wollen =)Das, o.ä., nachzubauen kann wohl aufwendig werden. Vorallem, wenn es als eine Art "Tool" auf jeder Seite funktionieren soll.
ABER
Um das zu erreichen, würde wohl eine "file_get_contents"-Suche am besten funktionieren.
heißt:
bei der Suche von "Apfel" auf der eigenen Seite/Domain grasen wir alle unsere Pages via file_get_contents (o.a.) ab.
Somit ist es Wurst, ob der content dynamisch oder fest ist.
Wir suchen also nicht in unseren Files ect, sondern dort, wo der Benutzer auch hinkommt.An der Auswertung kann man sich denk ich am besten an Google ein Bsp nehmen (was sonst :D).
Also: content, content, content, title, description, content.
EDIT: ich glaub es ist sinnvoll das Ganze via JS umzusetzen. Denn dadurch kann man zB den body in ein neues Elemen (createElement) setzen und "sieht" ein einer Suche nach Worten den Inhalt so, wie es der Nutzer sehen würde.
-
Von was wurde denn ausgegangen? Dyn content, content aus der db, content in den pagexyz.html ?
-
Ihr includer ihr

-
-
Ha! Danke!
War eben doch was total blödes - das File war schon (in ner anderen Klasse) geladen -.-
-
aber der Trend geht so wie ich das beobachte und bevorzuge zu einer guten mobilen Webseite anstatt einer eigenen nativen App.
ich hab auch nie so richtig verstanden, warum man für alles eine App braucht.
Wenn es nicht wirklich notwendig ist, dann ist doch eine mobile Page mMn sinnvoller.
Aber das is wohl off topic, ... =) -
Das ist ein cut einer Klasse die dafür sorgt, dass das gesammte db-Modell erstellt wird. Die Dateien die da geladen werden sind die Tabellen-"Modelle".
Es sind zu viele um es in ein File zu schreiben (user, usergroups, useractions, languages, ...,...).Mir bleibt da jetzt erstmal nix anderes übrig als require (ohne _once) zu nutzen.
Den Fehler jag ich aber noch
Das is bestimmt irgendwas dämliches, wie immer 
Danke fürs Testen -
Also entweder sehe ich da irgentwas nicht, oder es ist ein Bug.
Wobei ich denke, ich übersehe da was.Ablauf:
- class die files via require_once einbinden soll
- die files returnen jeweils ein array
- require_once soll mir also den inhalt der files liefernProblem:
Im Testfall funktioniert das ohne Probleme.
Im eigtl Script nicht - dort returnt require_once 1 (also true), obwohl der Aufbau der gleiche ist.
Mit require oder include (ohne _once) funktioniert es bei beiden Varianten.Was ist da los?
Kann das jemand bei sich feststellen?
Hab mal den Test hochgeladen: html-seminar.de/woltlab/attachment/523/
Wäre mal interessant bei wem require_once 1 returnt.Ich kann zwar jetzt require nutzen damit es funktioniert, allerdings möchte ich wissen wo das Problem liegt

Danke schon mal! -
Also Zusammenfassung:
- einmal (oder alle paar Jubeljahre) einen Cost für die eigene Hardware generieren und irgendwo als Konstante oder in einer Tabelle speichern
- grundsätzlich nur PASSWORD_DEFAULT als Algorithmus verwenden, da dieser regelmäßig erweitert wird.
- KEINEN Salt vorschreiben, aber evtl. einen Pepper verwenden (kann zB zusammen mit dem Cost und den DB Logindaten irgendwo weggesperrt werden)
- Nach erfolgreichem LOGIN eines Users prüfen, ob das Pass noch den aktuellen Anforderungen gerecht wird und ggf. mit aktuellen Optionen rehashen
- Dem Hash in der DB empfohlenerweise min. 255 Zeichen zugestehen (CHAR oder VARCHAR, CHAR schneller, VARCHAR weniger Speicher)Hab ich was vergessen?
Nö, passt alles mMn =)Thema CHAT und VARCHAR:
bitte nicht falsch verstehen - ich will nicht klugscheißen. Ich will es halt immer wissen/selbst testen.
Hat dann den Vorteil, dass man sich Sachen auch besser Einprägt =)
Tests:
2 Datenbanken :: `pw_char` und `pw_varchar`
Jeweils befüllt mit 1 mio Usern (`uname` 1-5 Stellig und `pw` 60 Stellig)
Einzige Unterschied:
`pw_char`.`tbl` column `pw` = CHAR(255)
und
`pw_varchar`.`tbl` column `pw` = VARCHAR(255)SQL
Alles anzeigenCREATE DATABASE IF NOT EXISTS `pw_varchar`; CREATE DATABASE IF NOT EXISTS `pw_char`; USE `pw_varchar`; CREATE TABLE IF NOT EXISTS `tbl`( `id` INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, `uname` VARCHAR(32) NOT NULL, `pw` VARCHAR(255) NOT NULL, INDEX (`uname`) ); USE `pw_char`; CREATE TABLE IF NOT EXISTS `tbl`( `id` INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, `uname` VARCHAR(32) NOT NULL, `pw` CHAR(255) NOT NULL, INDEX (`uname`) );
Größenunterschiede: html-seminar.de/woltlab/attachment/521/Zeitunterschiede:
Tests mit 100.000 SELECTs
CHAR:Code
Alles anzeigenTestlauf 1 # DEBUG: Timer::outputAll() type: array val: Array ( [SQL] => Array ( [time] => 18.634069919586 [count] => 100000 ) ) #/DEBUG Testlauf 2 # DEBUG: Timer::outputAll() type: array val: Array ( [SQL] => Array ( [time] => 18.147032737732 [count] => 100000 ) ) #/DEBUG
VARCHAR:Code
Alles anzeigenTestlauf 1 # DEBUG: Timer::outputAll() type: array val: Array ( [SQL] => Array ( [time] => 18.586066007614 [count] => 100000 ) ) #/DEBUG Testlauf 2 # DEBUG: Timer::outputAll() type: array val: Array ( [SQL] => Array ( [time] => 18.206033468246 [count] => 100000 ) ) #/DEBUGAlso Bei der Geschwindigkeit sehe ich so keinen Unterschied. Es kann natürlich sein, dass es bei komplexeren Queries auffälliger wird.
Und bei der Größe sehe ich einen enormen Unterschied. CHAR "reserviert" eben den gesammten Platz (es werden "freie"/ungenutzte Stellen mit Leerzeichen aufgefüllt).
Also hat VARCHAR die Nase vorn.EDIT:
So einen ähnlichen Test hatte ich auch vor kurzem gemacht zwecks INT(Anzeigebreite) oder INT.
Die Frage war also: macht es bei TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT Sinn eine Anzeigebreite mitzugeben?
Antwort: Nein
Tests mit 2 Datenbanken
Unterschiededb.tbl mit Angaben:
TINYINT(1), SMALLINT(1), MEDIUMINT(1), INT(1), BIGINT(1)db.tbl ohne Angaben:
TINYINT, SMALLINT, MEDIUMINT, INT, BIGINTBei 700 Einträgen mit $i++ gab es keine Größenunterschiede.
Es gibt auch witzigerweise keine genauen Angaben zu dem Thema @dev.mysql.com.
Auch beachtenswert: bei einem INT(1) Feld werden trotzdem "zu große Werte" korrekt gespeichert.
Man könnte ja meinen INT(1) lässt nur 0-9 zu. Aber - nö. Wird mehr Platz gebraucht, wird er sich genommen (bis hoch zum jeweiligen Maximun des Types).Fazit: Numerische Typen (AUßER FLOAT! - anderes Thema) benötigen keine Anzeigebreite. Diese werden ignoriert und haben keinerlei Einfluss auf die Größe der db.
-
Passend zum Thema: http://www.youtube.com/watch?v=hywbooiNUZ4
Finde ich muss man gelesen, gehört haben =) -
Na, moment mal eben ...
Was meinst Du denn immer mit automatisch?
Die Variante, wo man die COST speichert ist ja Wurst- Aber man muss den Wert halt irgendwo hinlegen, FALLS man ihn mitgeben will.Und ob man ihn statisch oder dynamisch mitgeben will - man sollte auf jeden Fall, wie Du schon sagtest, den best möglichen Wert ermitteln.
Da die Maschiene sich nicht dauernd ändern wird, könnte man nun aller paar Wochen/Monate den COST Wert erneut prüfen und aktualisieren.WENN man nun den COST Wert mitgeben und auch from time to time ändern will, dann sollte man die password_needs_rehash() function nutzen.
Damit wird sichergestellt, dass nicht nur die neu registrierten User, sondern auch die schon vorhandenen User von der besseren Variante "profitieren".Was macht password_needs_rehash():
- prüfen, ob algo sich geändert hat
- prüfen, ob cost sich geändert hat
Das Salt und PW sind btw nicht per . getrennt.
Ich sehe auch keinen Grund auf VARCHAR zu verzichten. Selbst wenn CHAR schneller ist (müsste man prüfen) - VARCHAR belegt nur soviel Speicher, wie es benötigt.
Und wenn ich die Wahl hätte zw. IMMER 255 belegt, oder paar micro(?) sec langsamer, dann ist wohl VARCHAR die bessere Wahl.
Stellt euch auch mal vor ihr habt 1 mio user und CHAR belegt 255 anstatt der eigtl momentan benötigten 60. Da kann das schon was ausmachen.
Ablauf wäre dann in etwa:PHP
Alles anzeigen$_POST['uname'] = 'cottton'; $_POST['pw'] = '12345678'; $pepper = 'bisschenPfeffer?'; define('COST',13); # eigener cost wert # bei registrierung $hash = password_hash($_POST['pw'].$pepper,PASSWORD_DEFAULT,array('cost'=>COST)); # user speichern in db ... ############ # bei login # daten aus db holen ... $db_user = 'cottton'; $db_hash = '$2y$13$TG3MmIG0EYpEoPIQdWE1n.jo2g.rUfBTdEynPPoZOPu9iSkzayLna'; # login prüfen if(password_verify($_POST['pw'].$pepper,$db_hash)){ # login ok # hat sich evtl der PASSWORD_DEFAULT algo geändert, oder haben wir die COST geändert? if(password_needs_rehash($db_hash,PASSWORD_DEFAULT,array('cost'=>COST))){ # ja, algo oder cost im hash sind nicht PASSWORD_DEFAULT-algo oder COST # also den db_hash des eingelogten users aktualisieren: $hash_update = password_hash($_POST['pw'].$pepper,PASSWORD_DEFAULT,array('cost'=>COST)); # hier sollte man daran denken, dass beim login das pw evtl 2 mal gehasht wird. Bedeutet doppelte zeit - also ~2xCOST # für paranoide: if(!password_verify($_POST['pw'].$pepper,$hash_update)){ # error ... }else{ # UPDATE ... WHERE ... } } }
PASSWORD_DEFAULT und PASSWORD_BCRYPT sind momentan übrigends genau das gleiche.
Daher verwirrt die php.net docu ein bischen. Bei bcrypt kann man die cost mitgeben, bei default auch, da dort ja bcrypt genutzt wird.
Fragts sich was passiert, wenn man per PASSWORD_DEFAULT die cost mitgibt, der default algo sich aber mal ändert und keine cost mehr akzeptiert wird
da evtl vom neuen algo nicht unterstüzt. Aber das soll mal php.net´s Sorge sein ;D -
Korrekt
Man könnte die "cost"-Prüfung sogar mit vor die Passwortprüfung einbauen (oder direkt in die index.php), falls jemand keinen Cronjob einsetzen kann/will.
Wenn wir die "cost" immer "aktuell" halten möchten, dann müssen wir ja den Wert irgentwo hinspeichern und beim hashen mitgeben.
Also Speichern wir in einer kleinen Tabelle zB
cost - 11
last_chk - timestampWenn nun x Tage/Wochen vergangen sind, lassen wir die Prüfung laufen und aktualisieren die beiden Werte.
-
-
Probier mal <audio preload id="klick">
Kann mir allerdings vorstellen, dass beim Klick auf den Link das Ganze hinfällig wird, da die Neue Seite ja schon geholt wird.
Du kannst das ja mal testen, in dem Du den link "tot" machst: <a href="#" onclick="klecks(this)"><p id="more">More</p></a>Btw - da fehlt doch noch was - Du erwartest in der function ein currentElement, aber das wird da nicht verwendet
-
Bin da gestern drüber gestolpert:
bcrypt
password_hash()
password_verify()
password_needs_rehash()Zum Thema "Salt":
Falls sich jemand fragt,
"warum denn den Salt mit speichern. Und was, wenn die db gehackt wird? Dann hat der Angreifer ja alle zugehörigen Salts?!">>The only requirement for a salt is for it to be globally unique. It does not have to be kept secret. password_hash() takes care of it for you. Don't do anything fancy and stupid.
Einfache Übersetzung:
Das wichtigste ist, dass das Salt einzigartig ist. Es muss nicht geheim sein.
password_hash() kümmert sich um das Salt. Es macht also keinen Sinn sich eine "Beste-Salt-function-ever" zu basteln.
heißt: der Funktion password_hash() kein eigenen Salt mitgeben
siehe auch: php.net: "Caution It is strongly recommended that you do not generate your own salt for this function."&
>>Sehr gute Erklärung - also lesen!
Hier mal eine kurze Zusammenfassung (ohne Übersetzung =)
- The reason we use salts is to stop precomputation attacks, such as rainbow tables.
- So, we use a salt. A salt is a random unique token stored with each password.
- nobody has rainbow tables that include that hash.
- The goal is to force the attacker to have to crack the hashes once he gets the database, instead of being able to just look them all up in a rainbow table.
- One other idea to consider is a pepper. A pepper is a second salt which is constant between individual passwords, but not stored in the database. (KDF(password + pepper, salt))
- So, how do we prevent brute-force attacks now?
- A more solid approach is to use a key derivation function with a work factor. These functions take a password, a salt and a work factor. The work factor is a way to scale the speed of the algorithm against your hardware and security requirements:
hash = KDF(password, salt, workFactor) (siehe password_hash() "cost"-Faktor)Hier ein einfaches Bsp:
PHP
Alles anzeigen/*(simuliert) formular daten bei registrierung:*/ $_POST['uname'] = 'cottton'; $_POST['pw'] = '12345678'; /*fester "geheimer" wert ("pepper")*/ // kann zB in einer config.php als constant definiert werden: define('PEPPER', 'bisschenPfeffer?') wobei schon etwas konstantes und schwer zu erratenes genutzt werden sollte $pepper = 'bisschenPfeffer?'; /*hash:*/ // wird erst erstellt, wenn alle benötigten benutzereingaben vorhanden sind $hash = password_hash($_POST['pw'] . $pepper, PASSWORD_BCRYPT, array('cost' => 12)); # ^= $2y$12$sWGjyoZ9xDwuGLou6fvije3q3T5SV1cGbgS.wCKsWicdTXK9czeV6 /*speichere nutzerdaten in db:*/ // hier testweise nur ein var_dump ! var_dump($hash); /*(simuliert) formular daten bei anmeldung:*/ $_POST['uname'] = 'cottton'; $_POST['pw'] = '12345678'; /*(simuliert) daten aus db laden:*/ $db_daten = array( 'uname' => 'cottton', 'pw' => '$2y$12$sWGjyoZ9xDwuGLou6fvije3q3T5SV1cGbgS.wCKsWicdTXK9czeV6', ); /*prüfen ob hash aus db zu passwort aus anmeldung passt*/ // dabei muss PEPPER an die gleiche stelle angehangen werden, wie es beim erstellen des hashes geschehen ist $valid = password_verify($_POST['pw'] . $pepper, $db_daten['pw']); var_dump( $valid ? 'Password is valid!' : 'Invalid password!' );Zusammenfassung:
Wir haben also erreicht, dass der Angreifer:
- in die db eindringen muss (klar) um den Passwort-hash und Salt zu bekommen
- aber auch zugriff auf das Pfeffer ($pepper) haben muss - sich somit also auch Zugriff auf die Files verschaffen muss
- gezwungen ist den Passwort-hash zurück zu Rechnen, anstatt in "rainbow tables" danach zu suchen.Das Ganze nun noch abgerundet, indem man Prepared Statements nutzt (siehe php.net "PDO"), um eine SQL-injection zu verhindern (wenn richtig angewandt!).
EDIT: 05.06.2016
Es ist wichtig die Funktion password_verify zur Prüfung des Passwortes zu nutzen
wenn sich User sich einloggt nicht if ($hash === $hashLogin), sondern wirklich password_verify() nutzen
Warum: um Timing_attacks zu unterbinden.
Siehe http://stackoverflow.com/a/29489833/3411766Zitat von http://stackoverflow.com/a/29489833/3411766
The answer is YES it uses length-constant time comparison.This is an excerpt of php's password_verify function
Code/* We're using this method instead of == in order to provide * resistance towards timing attacks. This is a constant time * equality check that will always check every byte of both * values. */ for (i = 0; i < hash_len; i++) { status |= (ret->val[i] ^ hash[i]); }
You can have a look at the full source code at https://github.com/php/php-src/bl…dard/password.c
"Man kanns auch übertreiben ..." ? - Nein. Man kann es auch gleich richtig machen =) -
richtig.
hm, hab alles versucht - bei mir hängts beim ersten start im FF. -
Nö.
Wenn ich zB http://jsfiddle.net/zqDWM/embedded/result/ im FF aufrufe, dann scheint mir das focus event nicht zu greifen.ich lade die seite neu, klicke auf ein anderes fenster (wodurch focus 0 sein sollte), aber er reagiert nicht.
edit:
FF 26.0edit2:
moment, ich glaub das liegt an jsfiddle
... werd das nochmal prüfen ...edit3:
also im FF (inzw updated latest version) bekomme ich bei ersten laden der page: html-seminar.de/woltlab/attachment/520/Ich glaub aus irgendeinem grund will er nicht in die function: tick:function(){}
Jemand ne idee? -
Blöde Frage, wäre das Thema nicht eigentlich in JavaScript besser aufgehoben?
Stimmt. Keine Ahnung warum ich das damals hier geposted hab
lauras - kannste das evtl verschieben?
danke -