mysql über php
-
Hallo,
Habe ein Login in PHP programmiert. Nun sollte der Administrator die Möglichkeit haben User hinzuzufügen, auch dies habe ich programmiert, aber der Vergleich, ob ein User bereits existiert funktioniert nohc nicht so ganz. Folgendes habe ich bis jetzt zum Vergleich programmiert:
//Prüfen ob der User bereits existiert $sql2 = "SELECT * FROM benutzerdaten "."WHERE Nickname=".'"'.$_POST['user'].'"'; $erg = mysql_query($sql2); echo $erg; //Ende des Prüfvorganges
Es wird also ein Select auf die DB gefahren, ob der Benutzer, der eingegeben wird bereits existiert oder nicht.
Ich dachte ich könnte mit hilfe der $erg überprüfen ob dies der Fall ist, aber die einzige Ausgabe, die mir $erg liefert ist folgende:Resource id #4
Dies passiert auch wenn der Benutzer existiert und wenn er noch nicht existiert.
-
Natürlich gibt er das zurück. Das ist ja die Antwort von der DB. Du musst also erst ncoh die Antwort auswerten. Ich glaube da hilft dir mysql_num_rows().
-
1. http://de.wikipedia.org/wiki/SQL_Injection
2. Vergleiche von Strings solltest du nur durch Verwendung entsprechender Hash-Funktionen durchführen, da MySQL sonst Groß- und Kleinschreibung nicht beachtet. Man kann sich dann nicht nur als "root" anmelden, sondern auch als "Root", "ROOT", "RooT" etc. PHP bietet dafür schöne FunktionenWHERE SHA1(`userName`) = \''.sha1($_POST['userName']).'\'
-
Sorry, aber es ist sinnfrei den usernamen zu verschlüsseln. das bringt nichts erschwert aber vieles.
ob man usernames nun case sensitiv haben will oder nicht, sei mal dahin gestellt. wenn man aber case sensitive strings vergleichen will, dann gibts den operator "binary" in mysql.
und sql injections umgeht man indem man den string escaped: mysql_real_escape_string
-
Shade Of Mine schrieb:
Sorry, aber es ist sinnfrei den usernamen zu verschlüsseln. das bringt nichts erschwert aber vieles.
Seltsam; von diesen Erschwernissen habe ich noch nichts gemerkt. Kannst du das näher erläutern?
Shade Of Mine schrieb:
ob man usernames nun case sensitiv haben will oder nicht, sei mal dahin gestellt. wenn man aber case sensitive strings vergleichen will, dann gibts den operator "binary" in mysql.
Der im Beispiel das Gleiche bewirkt; mit dem Unterschied, dass du bei der Hashvariante Bruteforcing erschwerst (gut, ist beim Binary-Abgleich ebenfalls der Fall) und Man-in-the-Middle-Attacken eingrenzt.
Shade Of Mine schrieb:
und sql injections umgeht man indem man den string escaped: mysql_real_escape_string
Habe ich nie bestritten; es ist aber nicht die einzige Möglichkeit.
-
árn[y]ék schrieb:
Shade Of Mine schrieb:
Sorry, aber es ist sinnfrei den usernamen zu verschlüsseln. das bringt nichts erschwert aber vieles.
Seltsam; von diesen Erschwernissen habe ich noch nichts gemerkt. Kannst du das näher erläutern?
Klar: der name der Person ist nicht mehr auffindbar. Man kann niemanden mehr persönlich anschreiben bzw. vernünftige handles vergeben.
weiters hat man ein kollisionsproblem das komplett unnötig ist.
Shade Of Mine schrieb:
ob man usernames nun case sensitiv haben will oder nicht, sei mal dahin gestellt. wenn man aber case sensitive strings vergleichen will, dann gibts den operator "binary" in mysql.
Der im Beispiel das Gleiche bewirkt; mit dem Unterschied, dass du bei der Hashvariante Bruteforcing erschwerst (gut, ist beim Binary-Abgleich ebenfalls der Fall) und Man-in-the-Middle-Attacken eingrenzt.
man in the middle attacken kannst du damit kein bisschen ausschalten. bruteforce attacken sind in den meisten fällen über bekannte usernames möglich. weils es oft profile gibt wo man die namen auslesen kann.
was hashing bringt ist:
datenschutz
und sonst eher nichts. für den unwahrscheinlichen fall dass jemand die db lesen aber nicht schreiben kann - ok da bringen hashes auch etwas. aber da reicht es wenn passwörter verschlüsselt sind.weiters kosten hashes rechenzeit: also wozu unnötig zeit vergeuden wenn es nichts bringt?
Shade Of Mine schrieb:
und sql injections umgeht man indem man den string escaped: mysql_real_escape_string
Habe ich nie bestritten; es ist aber nicht die einzige Möglichkeit.
[/quote]
es ist die einzig richtige möglichkeit.hashes macht man auf passwörter aus gründen der datensicherheit.
für bruteforce angriffe sind hashes komplett uninteressant
für man in the middle angriffe sind hashes auch komplett uninteressant
für sql injections gibt es deutlich bessere möglichkeiten als alles zu hashen
-
Shade Of Mine schrieb:
árn[y]ék schrieb:
Shade Of Mine schrieb:
Sorry, aber es ist sinnfrei den usernamen zu verschlüsseln. das bringt nichts erschwert aber vieles.
Seltsam; von diesen Erschwernissen habe ich noch nichts gemerkt. Kannst du das näher erläutern?
Klar: der name der Person ist nicht mehr auffindbar. Man kann niemanden mehr persönlich anschreiben bzw. vernünftige handles vergeben.
Hast du dir meinen Quellcode richtig angesehen? Der Name wird nur gehasht abgeglichen; eine Speicherung erfolgt nach wie vor in Klartext. Und auf das Ergebnis des SELECT-Wertes hat es somit auch keinen Einfluss.
Kollisionsproblem? SHA1 erzeugt einen 40 Zeichen langen String. Dabei kann jedes Zeichen aus 0-9a-f bestehen. Dazu kommt das gleiche noch einmal für die Zeichen des Passworthashes (der z.B. als Whirlpool-Hash eine Länge von 128 Zeichen besitzt), die für eine Kollision ebenfalls identisch sein müssen. Dann kommen wir auf nahezu 168^15 = 2,3968410045765266524649638141624e+33 Möglichkeiten. Die Wahrscheinlichkeit auf eine Kollision dürfte - auch wenn die Hashalgorithmen entgegen meiner Pi*Daumen-Rechnung natürlich nicht stochastisch rechnen und ich den Faktor "benutzerdefiniertes Passwort" außer Acht gelassen habe - dennoch selbst bei Millionen von registrierten Nutzern gegen Null streben.
Mit Man-in-the-Middle-Attacken meinte ich vielmehr, das jemand, der die Verbindung abhört, keine Daten über den verwendeten Benutzernamen erhält. Alles, was er mitlesen kann, ist ein Benutzernamenhash und ein Passworthash. Diese bringen ihm weniger, als ein Benutzername + ein Passworthash, da er keine Rückschlüsse auf den Benutzer selbst ziehen kann, was andernfalls immer noch möglich ist. Sicher, dies ist nur ein Vorteil, wenn man davon ausgeht, dass der Angreifer auch das Script oder die Verbindung zur Datenbank cracken kann - aber so paranoid kann man ja ruhig sein. Und sollte dies wirklich geschehen, hat der Angreifer weiterhin zwei Unbekannte anstelle von nur einer.
Im Übrigen habe ich niemals behauptet, man solle SQL Injections durch Hashing verhindern. Da der Hash aber naturgebunden keine potentiell für SQL Injection geeignete Werte liefern kann, ist die Variable implizit escaped.
Aber die anderen Argumente erscheinen sinnvoll. Interessant nur, dass PHP-Sicherheitsexperten diese Technik dennoch vorschlagen :-\
-
árn[y]ék schrieb:
Hast du dir meinen Quellcode richtig angesehen? Der Name wird nur gehasht abgeglichen; eine Speicherung erfolgt nach wie vor in Klartext. Und auf das Ergebnis des SELECT-Wertes hat es somit auch keinen Einfluss.
Oh, das habe ich überlesen. Damit ist es lediglich sinnlose performance verbrennung.
Kollisionsproblem? SHA1 erzeugt einen 40 Zeichen langen String.
kollisionen gibt es dennoch. weiters verbratest du auch noch sinnlos traffic.
Mit Man-in-the-Middle-Attacken meinte ich vielmehr, das jemand, der die Verbindung abhört, keine Daten über den verwendeten Benutzernamen erhält.
Alles, was er mitlesen kann, ist ein Benutzernamenhash und ein Passworthash.wieso? der user sendet den benutzernamen in klartext. oder meinst du jetzt die kommunikation anwendung <-> db?
Sicher, dies ist nur ein Vorteil, wenn man davon ausgeht, dass der Angreifer auch das Script oder die Verbindung zur Datenbank cracken kann - aber so paranoid kann man ja ruhig sein. Und sollte dies wirklich geschehen, hat der Angreifer weiterhin zwei Unbekannte anstelle von nur einer.
ich dachte du speicherst benutzername doch in klartext?
Aber die anderen Argumente erscheinen sinnvoll. Interessant nur, dass PHP-Sicherheitsexperten diese Technik dennoch vorschlagen :-\
PHP und Sicherheitsexperte beisst sich ein bisschen - aber zeig mal ne URL oder so.
-
Shade Of Mine schrieb:
oder meinst du jetzt die kommunikation anwendung <-> db?
Ja, die meinte ich
Aber letztendlich hast du natürlich Recht; da die Übertragung vom Client zum Server schon unkodiert stattfindet, würde sich die Abfrage eigentlich erübrigen. Mit der Argumentation könnte man dann aber so ziemlich jeden Hashabgleich ab Serverebene anzweifeln (Abgleich - nicht Speicherung).Shade Of Mine schrieb:
PHP und Sicherheitsexperte beisst sich ein bisschen - aber zeig mal ne URL oder so.
In erster Linie würde mir dabei das Buch "PHP-Sicherheit", 2te Auflage von Christopher Kunz, Stefan Esser und Peter Prochaska einfallen, Kapitel 6 (Autorisierung und Authentisierung), Abschnitt 1.2 (Beliebte Fehler in Login-Formularen -> Falsche SQL-Abfrage).
Edit:
Ah, mir fällt gerade auf, dass ich oben einen Zahlendreher hab. Richtig wäre in der Rechnung natürlich 15^168 = 3,8311708649765895864983905223706e+197 ... Nur so am Rande
-
árn[y]ék schrieb:
Shade Of Mine schrieb:
oder meinst du jetzt die kommunikation anwendung <-> db?
Ja, die meinte ich
Aber letztendlich hast du natürlich Recht; da die Übertragung vom Client zum Server schon unkodiert stattfindet, würde sich die Abfrage eigentlich erübrigen. Mit der Argumentation könnte man dann aber so ziemlich jeden Hashabgleich ab Serverebene anzweifeln (Abgleich - nicht Speicherung).Wenn du die Kommunikation anwendung <-> db nicht mehr als sicher einstufen kannst, dann ist dein netzwerk ziemlich im arsch.
man sollte immer realistisch bleiben bei seinen einschätzungen der sicherheit...
In erster Linie würde mir dabei das Buch "PHP-Sicherheit", 2te Auflage von Christopher Kunz, Stefan Esser und Peter Prochaska einfallen, Kapitel 6 (Autorisierung und Authentisierung), Abschnitt 1.2 (Beliebte Fehler in Login-Formularen -> Falsche SQL-Abfrage).
Habe mir mal die 2 Probekapitel durchgelesen. Muss sagen Kapitel Nummer 7 ist teilweise lächerlich. Das vorgeschlagene Ticketsystem ist nicht implementierbar in der heutigen Zeit.
Der Sinn eines Cronjobs der die alten Session Daten löscht ist mir auch nicht wirklich klar. Es kann aus performancetechnischen Gründen Sinn machen aber mit Sicherheit hat das nichts zu tun.
session.timeout von 20 Minuten. Da dreht jeder User sofort durch. Das ist nur in Systemen relevant wo man nicht verweilt. zB einem Online Konto. Aber jede Anwendung die dem User Inhalt bietet, kann sich soetwas nicht mehr leisten.
Was du mir aber vielleicht erklären kannst: warum ist ein permissive Session Modell anfälliger für Session Riding als ein restriktives? Generell ist mir die Unterscheidung ein Rätsel. Es ist eigentlich komplett egal ob ein User sich die Session ID selber ausdenkt solange er nicht eingeloggt ist. In dem Moment wo er sich einloggt - oder generell ein wechsel der Permissions stattfindet, bekommt er eine auto generierte session id...
Erklär mir auch bitte mal die "Beliebte Fehler in Login-Formularen -> Falsche SQL-Abfrage". Bin immer daran interessiert mehr über Sicherheit zu erfahren. Aber aufgrund der 2 Probekapitel denke ich nicht, dass ich mir das Buch kaufen werde. Es sind zwar einige sinnvolle Infos drin, aber auch einiges an bullshit...
-
Shade Of Mine schrieb:
Wenn du die Kommunikation anwendung <-> db nicht mehr als sicher einstufen kannst, dann ist dein netzwerk ziemlich im *****.
Das ist wohl wahr. Aber ausblenden sollte man dieses Szenario imho dennoch nicht.
Shade Of Mine schrieb:
man sollte immer realistisch bleiben bei seinen einschätzungen der sicherheit...
Ist es nicht meistens so, dass wenn ein System gecrackt wurde, jemand eine Einschätzung der Sicherheit für zu unrealistisch hielt?
Habe mir mal die 2 Probekapitel durchgelesen. Muss sagen Kapitel Nummer 7 ist teilweise lächerlich.
Sicherlich. Es gibt in dem Buch einige Dinge, die zu kritisieren wären.
Es ist eigentlich komplett egal ob ein User sich die Session ID selber ausdenkt solange er nicht eingeloggt ist. In dem Moment wo er sich einloggt - oder generell ein wechsel der Permissions stattfindet, bekommt er eine auto generierte session id...
Es ging ja - soweit habe ich das verstanden - gerade darum, dass sich der Benutzer eine ausgedachte Session-ID selbst zuweisen kann, während er sich einloggt, und dann eingeloggt über die von ihm bestimmte ID verfügt. Diese würde er dann einem anderen Benutzer "unterschieben", welcher die Session ID beglaubigen könnte. Daraufhin könnte er diese Session wiederum übernehmen, da er sie bereitz kennte und sie nicht mehr erraten müsste. Dies beschreibt der Autor als Session Fixation. Anders währe es in er Tat ziemlich wurscht.
Erklär mir auch bitte mal die "Beliebte Fehler in Login-Formularen -> Falsche SQL-Abfrage".
Die Autoren erklären anhand von SQL-Injection-gefährdeten Anfragen der Art
SELECT ... WHERE userName = \''.$_POST['userName'].'\'
die Gefahr von SQL-Injections (dies tun sie öfters). Des Weiteren betonen sie, dass viele Anwender vergessen, das ein "normaler" Abgleich im WHERE-Statement die Groß- und Kleinschreibung nicht beachtet, und daher Bruteforcing wesentlich erleichtert. Daher schreiben sie: "Besser ist es, über die abgefragten Variablen per md5() zunächst Prüfsummen zu bilden und dann diese abzufragen." (besagtes Buch, S. 139 oben) Dadurch verhindere man, dass Benutzername und Passwörter ohne Beachtung der Groß- und Kleinschreibung verglichen werden, und verhindere zudem noch SQL-Injections.In der Tat muss ich aber sagen, dass mir deine Ausführungen da wesentlich sinnvoller erscheinen! Ich frage mich halt nur, weshalb die Autoren so etwas dann schreiben, denn ich denke eigentlich nicht, das es an Unwissenheit liegen dürfte :-\
-
árn[y]ék schrieb:
Ist es nicht meistens so, dass wenn ein System gecrackt wurde, jemand eine Einschätzung der Sicherheit für zu unrealistisch hielt?
Man sollte logisch denken. Wenn jemand den datenverkehr anwendung <-> db abfangen kann, dann kann er auch die login daten lesen. wenn er die login daten lesen kann ist die wahrscheinlichkeit sehr groß dass er auch selber eine verbindung aufbauen kann bzw die gesendeten daten manipulieren kann. in dem moment habe ich die volle kontrolle über die anwendung.
in dem moment liegt das problem nicht mehr bei der anwendung. denn irgendwo muss man ansetzen und sagen: diesen daten vertraue ich.
es hat dann also nicht die anwendungssicherheit versagt, sondern die netzwerksicherheit.
Es ging ja - soweit habe ich das verstanden - gerade darum, dass sich der Benutzer eine ausgedachte Session-ID selbst zuweisen kann, während er sich einloggt, und dann eingeloggt über die von ihm bestimmte ID verfügt. Diese würde er dann einem anderen Benutzer "unterschieben", welcher die Session ID beglaubigen könnte. Daraufhin könnte er diese Session wiederum übernehmen, da er sie bereitz kennte und sie nicht mehr erraten müsste. Dies beschreibt der Autor als Session Fixation. Anders währe es in er Tat ziemlich wurscht.
das ist aber nicht möglich wenn man dem punkt "session id immer neu generieren bei permission wechsel" folgt.
"Besser ist es, über die abgefragten Variablen per md5() zunächst Prüfsummen zu bilden und dann diese abzufragen." (besagtes Buch, S. 139 oben) Dadurch verhindere man, dass Benutzername und Passwörter ohne Beachtung der Groß- und Kleinschreibung verglichen werden, und verhindere zudem noch SQL-Injections.
und opfert sinnlos performance. ist einfach schwachsinn.
ein binary ist genau für solche sachen gedacht. man kann usernames zB auch als binary feld definieren, dann spart man sich den operator in den queries.
ein problem dabei ist ja eigentlich auch, dass man eine library verwenden sollte die db zugriffe etwas abstrahiert. da sollte dann ein mysql_escape_string automatisch erfolgen, so dass ein hashen dann doppelt gemoppelt wäre.
bei mir sieht es zB so aus:
$res=$db->query('select id from users where binary uname=:name: and pw=:pw:', array( 'name' => $_POST['uname'], 'pw' => md5($_POST['pw']) ));
oder ähnlich. hier nun hashes einzubauen würde das ganze system nur verkomplizieren. da man automatisch immer escapes auf den params hat. bei pw hat man es zum beispiel und das ist schon unnötig
aber da hat der hash ja nen anderen sinn als sql injections verhindern.
solche systeme wie diese abstraktion hier, bringt einem 3 sachen für relativ wenig aufwand:
- leichtere abstraktion der datenbank (zB ob man nun mysql_, mysqli_ oder pdo verwendet wird, kann problemlos gewechselt werden)
- leichetere debug zwecke (problemlos möglich alle queries zu loggen. man kann auch für jedes query in einem debug run auch ein explain laufen lassen und dann die komplexes queries explizit loggen, etc.)
- sicherheit gegen sql injections ohne mehraufwand
ein ewiges:
$res=mysql_query('select id from users where binary uname="'.mysql_escape_string($_POST['uname']).'" and pw="'.md5($_POST['pw']).'"');
suckt doch derbe :p
Ich frage mich halt nur, weshalb die Autoren so etwas dann schreiben, denn ich denke eigentlich nicht, das es an Unwissenheit liegen dürfte :-\
Wie gesagt, soll keine Beleidigung sein, aber PHP und Sicherheit sind 2 Sachen die absolut nicht zusammen passen. Sowohl der PHP Interpreter ansich ist voller Lücken (man kann bis dato einen PHP interpreter immer noch problemlos mit php code abschiessen und oft auch noch den apache mitnehmen). Selbiges gilt für die meisten php anwendungen. das problem ist, dass die ganzen professionellen leute sind bei ASP.NET, Ruby on Rails, ZOPE, JSP, und dergleichen.
es ist traurig - und ich verdiene immer noch einen großteil meines geldes mit php - aber die php community ist total unprofessionell. das schlägt sich auch in der literatur nieder. ich habe noch kein einziges php buch gelesen (und das sind mittlerweile schon etliche ;)) wo ich gesagt hätte "wow, das stimmt" oder dergleichen. es wirkt so als wäre die zielgruppe aller bücher script kiddies.
-
Shade Of Mine schrieb:
ein binary ist genau für solche sachen gedacht. man kann usernames zB auch als binary feld definieren, dann spart man sich den operator in den queries.
Zumindest hier ist aber immer noch anwendungsabhängig. Was tust du, wenn du in einer Anwendung mal case-sensitive und mal -insensitive Abgleiche benötigst? Ein Forensystem könnte z.B. beim Login die Groß- und Kleinschreibung beachten, um Bruteforcing zu erschweren, aber andererseits beim Registrieren ignorieren, um Identitätsdiebstahl zu erschweren. Was tust du dann, wenn du das Textfeld als Binary erklärt hast? Du könntest eine Upper- oder Lowercasefunktion auf den String anwenden, aber dann wärst du wieder bei Funktionsaufrufen oder Cast-Operatoren. Ganz vermeiden lässt sich das also imho nicht.
Shade Of Mine schrieb:
ein problem dabei ist ja eigentlich auch, dass man eine library verwenden sollte die db zugriffe etwas abstrahiert. da sollte dann ein mysql_escape_string automatisch erfolgen, so dass ein hashen dann doppelt gemoppelt wäre.
Naja, es gibt ja verschiedene Ansätze, eine Datenbank zu abstrahieren. Man kann der Wrapperklasse auch eine eigene escape()-Methode mitgeben, die halt ihrerseits die datenbankspezifische Funktion aufruft.
Das, was du da geschrieben hast, ist sicher wesentlich komfortabler zu verwenden, aber das andere habe ich auch schon öfters gesehen. Zumal deine vorgeschlagene Variante vom Ansatz her schon fast in Richtung Prepared Statement geht, und die relativ neu von PHP nativ verwendbar sind.
-
árn[y]ék schrieb:
Zumindest hier ist aber immer noch anwendungsabhängig. Was tust du, wenn du in einer Anwendung mal case-sensitive und mal -insensitive Abgleiche benötigst? Ein Forensystem könnte z.B. beim Login die Groß- und Kleinschreibung beachten, um Bruteforcing zu erschweren, aber andererseits beim Registrieren ignorieren, um Identitätsdiebstahl zu erschweren. Was tust du dann, wenn du das Textfeld als Binary erklärt hast? Du könntest eine Upper- oder Lowercasefunktion auf den String anwenden, aber dann wärst du wieder bei Funktionsaufrufen oder Cast-Operatoren. Ganz vermeiden lässt sich das also imho nicht.
klar. alles als binary feld definieren ist nicht die beste wahl. bei identitaetsdiebstahl hilft gross/klein schreibung ignorieren aber nicht viel
sonst registrier ich einfach einen
árn[y]èk
als benutzernamen.
den unterschied merkt so schnell niemand
oder
Shade Of Mínedas ist n ziemliches komplexes thema eigentlich.
Genau so bin ich der Meinung, dass man gute und saubere PHP-Skripte schreiben kann. Man benötigt nur einfach viel zu viel Ahnung um die ganzen Flickereien und Tricksereien in PHP. Zumal die Namenskonventionen ein Krampf sind.
dem stimme ich zu. mit php6 soll ja alles besser werden :p
naja, langsam wird php immer besser - das problem ist lediglich dass ich fürchte wen php6 raus kommt, dass wir immernoch alle php4 programmieren müssen. die sollten lieber etwas langsamer dafür gründlicher machen
manchmal wirkt es so als würde da ne firma dahinter stecken die einfach nur neue releases mit neuer feature liste veröffentlichen will
-
Shade Of Mine schrieb:
bei identitaetsdiebstahl hilft gross/klein schreibung ignorieren aber nicht viel
Stimmt, aber kostenlos wenig schadet auch nichts im Verhältnis zu kostenlos nichts :p
Shade Of Mine schrieb:
mit php6 soll ja alles besser werden :p
Wobei das auch bei PHP5 gesagt wurde (und zugegeben in OO-Richtung sicherlich auch der Fall war). Aber imho wirklich sinnvolle Änderungen wurden großteils ausgeschlagen (PHP case-sensitive machen, richtige Typehints und nicht diese Spielerei mit Objekten und Arrays, Objektmethodenzugriff nur per Variablenname (um z.Bsp. eigene Wrapperklassen für primitive Typen zu erstellen, die auch sinnvoll verwendet werden können)...)
Shade Of Mine schrieb:
das problem ist lediglich dass ich fürchte wen php6 raus kommt, dass wir immernoch alle php4 programmieren müssen.
Es kommt natürlich darauf an, wo bzw. wofür man programmiert. Das phpBB z.Bsp. legt penibelst Wert darauf, PHP4 zu unterstützen, da sie eine breite Masse erreichen wollen. So ziemlich jeder größere Hoster, den ich kenne, bietet aber inzwischen neben PHP4 auch PHP5 an. Wer also keine Software für die breite Masse schreibt, der kann i.a.R. relativ neue PHP-Derivate annehmen.