Archive for Februar, 2008

Feb 22 2008

[lang_de]PHP-Sicherheit: Session-Fixierung[/lang_de][lang_en]php security: session fixation[/lang_en]

Veröffentlicht by . Filed under: PHP

[lang_de]
PHP ist eine äußerst beliebte Programmiersprache. Wie jede Sprache hat sie natürlich ihre Vor- und Nachteile. Oft wird dabei die mangelhafte Sicherheit genannt. Das liegt jedoch nach meiner Meinung eher an schlechten Kenntnissen der meisten Programmierer. Ein solcher Punkt ist die sogenannte Session-Fixierung.

Problemsituation
In PHP ist es einfach, eine Session zu starten. Das geht häufig über

session_start();

Dabei wird geschaut, ob als Cookie oder als URL-Parameter (je nach Servereinstellung) eine Session-ID vorhanden ist. Ist sie das, wird die Session mit einer entsprechenden ID geladen. War sie bisher leer, so wird sie neu initialisiert. Ist hingegen keine ID vorhanden, so wird eine zufällige Session-ID verwendet.

Angriffszenario

Stellen wir uns einen Hacker vor, der einen Admin-Zugriff zu einem Shop haben will. Die einfachste Möglichkeit, an diesen zu gelangen, besteht darin, den Admin direkt danach zu fragen. So wäre folgende Mail an einen Shop-Inhaber denkbar:

Sehr geehrter Herr [Name],

ich habe heute Ihren Shop entdeckt und dabei ist mir aufgefallen, dass Ihr Shop eine Sicherheitslücke aufweist. Wenn Sie auf folgende URL klicken (manipulierte URL) und sich anschließend an Ihren Shop anmelden, sehen Sie, dass sich jeder Benutzer als Admin anmelden kann.

Der Shop-Besitzer, der natürlich Angst um seine Investition hat, wird ohne Nachdenken auf den Link klicken. Doch was tut dieser Link? Er leitet direkt an den Shop weiter, übergibt jedoch per Cookie oder per URL-Parameter eine festgelegte Session-ID. Den Namen der Session-ID hat der Hacker zuvor natürlich ausgekundschaftet, indem er einfach den Shop verwendete.

Das Problem ist jetzt, dass keine neue Session-ID erzeugt wird, da ja eine angegeben wurde. Der Shop-Besitzer muss sich nun lediglich anmelden und schon kann der Hacker als Admin tätig werden (er weiß die Session-ID ja).

Problemlösung
Die Lösung des Problems ist denkbar einfach: man muss beim Laden der Session lediglich prüfen, ob ein spezieller Wert schon angelegt wurde:

session_start();

if (!isset($_SESSION["init"])) {
//Session ist neu – neue ID auf jeden Fall vergeben
session_regenerate_id();
$_SESSION["init"]=true;
}

Sehr einfach und löst das Problem. Man muss es nur wissen.

[Update]
Nach Diskussion in den Kommentaren mit Erich folgender Hinweis: Natürlich ist es möglich, dass der Angreifer eine Session öffnet und diese offen hält. Diese Session-Daten könnte dann an einen Benutzer mit erhöhten Rechten mit Hilfe eines manipulierten Links gegeben werden. Klickt dieser darauf und meldet er sich an, so hab ich als Hacker die neuen Anmelde-Daten.

Im Prinzip übernimmt also der Benutzer die korrekte Session des Hackers, womit wir einen Fall von Session-Hijacking haben. Dies kann man mit oben beschriebenen Script nicht verhindern. Es gibt mehrere Möglichkeiten, das zu verhindern:

  • Ich verwende session_regenerate_id nach dem Anmelden. Damit stell ich sicher, dass ich auf jeden Fall eine neue ID verwende und der Hacker nicht mehr darauf zugreifen kann. Die alten Session-Daten werden dabei übernommen. Das Problem ist jedoch, dass je nach Session-Inhalt Daten übernommen werden, die weiterhin kritisch sind. Diese Lösung funktioniert deshalb nur, wenn ich auch darauf achte, dass die Session übernommen sein könnte. Wenn ich z.B. meine UserID in der Session speichere, muss ich berücksichtigen, dass die falsch sein könnte. Das Verfahren stellt also lediglich sicher, dass der Hacker keinen direkten Zugriff bekommt, weil er eine andere Session hat. Sie stellt aber nicht sicher, dass dadurch das System sicherer wird.
  • Die meiner Meinung nach bessere Möglichkeit besteht darin, sich wirklich gegen Session-Hijacking komplett zu schützen. Einen 100%-Schutz gibt es dabei nicht. Es hat sich aber bewährt, einen Fingerabruck vom Benutzer zu erstellen. Dazu sammelt man in einem Array erstmal Daten über den Benutzer und bildet darüber einen Hash-Wert.

    $fingerprintArray = array($_SERVER['HTTP_USER_AGENT'],substr($_SERVER["REMOTE_ADDR"],0,7),…);
    $fingerprint = md5(serialize($fingerprintArray));

    Wichtig ist dabei darauf zu achten, dass die Remote-Adresse nicht komplett benutzt wird, weil sie sich bei vielen Anbietern ständig ändert.

    Vergleicht man nun bei jeder Abfrage diesen Fingerabdruck, kann man recht sicher sein, dass der Benutzer korrekt identifiziert wurde. Heißt also: anderer Fingerabdruck? Session sofort löschen.

Sicher sollte man sein, indem man beide Techniken kombiniert.

[/lang_de]

[lang_en]
PHP is a loved programming language. But of course there are good and bad features as in any other programming language, too. Security can be heared to be one of the bad features. But in my opinion, the reason is not php but users who don’t know the problems. One problem is the so called session fixation

problem situation
It is very easy in PHP to start a session:

session_start();

If you start a session, the server looks if there is a cookie or a url param with a session id. If there is a session id, it will be used. If the session was not used before, it is created with this id. If there is no id, it will be generated randomly.

attack scenario

If you are a hacker and you want to have the admin access to a shop, what can you do. The simliest way is to ask the shop owner of course. So you write an email like this

Dear [Name],

I have found your shop and I have seen, that every user can get an admin access. I think this is a big security risk! If you click at this url (manupulated URL) and if you login, you will see that there is a big security hole.

The shop owner does not know anything about security and programming. So he will click the url to see the problem and to save his investment. But what does the url do? It only redirects the user to the shop and sets a cookie or a url param with a fixed session id. The name of the id is known by using the shop as costumer.

The problem is, that the session id is not regenerated. If the shop admin logs in, the hacker has an admin access.

problem solution
The solution of this problem is very simple. You only have to check if the session was used before. If not, you must regenerate the id for yourself:

session_start();

if (!isset($_SESSION["init"])) {
//session is new – regenerate the id!
session_regenerate_id();
$_SESSION["init"]=true;
}

Very easy, isn’t it?

[Update]
After disussing with Erich following notice: Of course, it is possible, that a hacker creates a valid session and that he can keep this session active. He can give a manipulated link to an user with higher rights. If this user would use the link and he would log on in the system, the hacker will have more rights.

In this case, the user uses a valid session, which is not his session. So, we have a special case of session hijacking. The above described script is NOT able to handle this. We can solve this problem like this:

  • Use session_regenerate_id after login, so that the user has surely a new session id. Old session data will remain, what is necessary in some systems. The problem is, that also critical session data will remain. So you have to be aware, that there can be wrong data (e.g. wrong user id) in your session. This solution will make sure, that the hacker gets no privileged access. But it does not make sure, that your application is secure at all.
  • In my opinion, it would be better to include a session hijacking protection. You can create a fingerprint of your user and you have to check this fingerprint at every connection. So collect information about your user and save it to the session as hash value:

    $fingerprintArray = array($_SERVER['HTTP_USER_AGENT'],substr($_SERVER["REMOTE_ADDR"],0,7),…);
    $fingerprint = md5(serialize($fingerprintArray));

    Important: don’t use the complete REMOTE_ADDR because it could change with every request.

    If the fingerprint is different to the stored fingerprint: delete the session.

The most secure way is to use both methods, surely.
[/lang_en]

1 Star2 Stars3 Stars4 Stars5 Stars
Loading ... Loading ...
22 responses so far

Feb 21 2008

Was ist ein schlechter Produktname?

Veröffentlicht by . Filed under: Uncategorized

Wenn ich weiß, wie die Werbung aussieht, ich aber auf den Namen nicht komme. Gott sei Dank liefert Google bei der Anfrage nach “PHP Sicherheit Wurst” die spanische Wurst: Chorizo. Fragt mich nicht, warum ich mir diesen Namen nicht merken kann.

1 Star2 Stars3 Stars4 Stars5 Stars
Loading ... Loading ...
No responses yet

Feb 20 2008

Gmail als Mail-Server?

Veröffentlicht by . Filed under: Software

Eine Kundin hat ein auffallend großes Mail-Aufkommen, so dass sie regelmäßig die Quota für ihren POP3-Mail-Server überschreitet. Sie will jedoch keine Mehrausgaben, weshalb eine andere Lösung, die ich ihr anbieten könnte, nicht akzeptabel ist. Jetzt ist die Frage: wie gut ist Gmail als Mailserver tauglich? Im Rahmen der Google-Apps hat man ja die Möglichkeit, den MX-Record auf Gmail weiterleiten zu lassen. Das wäre für sie eine gute Möglichkeit, das Mail-Problem zu lösen, ohne mehr Geld bezahlen zu müssen. Im Standard-Umfang ist Google-Aps ja kostenlos. Hat jemand Erfahrung, ob Gmail und POP3 (sie will ihr Outlook weiterhin verwenden) sich gut vertragen oder ob die Geschwindigkeit zu langsam ist?

1 Star2 Stars3 Stars4 Stars5 Stars
Loading ... Loading ...
No responses yet

Feb 20 2008

Wer hat sich denn diesen Blödsinn ausgedacht?

Veröffentlicht by . Filed under: Studium

Diplomarbeiten müssen von zwei Betreuern begutachtet werden. Einer davon muss Professor an der Uni sein (bei mir also Uni Ulm), einer muss mindestens Doktor sein. Soweit so gut. Nun dachte ich, dass es für beide Betreuer eine maximale Zeitspanne gibt, bis sie die Arbeit begutachtet haben müssen – schließlich braucht man auch irgendwann ein Zeugnis. Tja, weit gefehlt. Es gibt lediglich für den ersten Betreuer eine Frist von 6 Wochen, der zweite ist völlig frei.

Und so warte ich nun schon seit 2 Monaten auf mein Ergebnis :( . Nächste Woche ist meine letzte Prüfung. Bin mal gespannt, ob ich die Note noch davor bekomme oder nicht. Dementsprechend entscheidet sich nämlich, ob ich mich noch richtig anstrengen muss (gut, eigentlich ist es völlig egal, aber man geht halt doch entspannter in die Prüfung).

Viel interessanter ist aber die Frage: Wer hat sich denn diesen Blödsinn ausgedacht? Und warum?

1 Star2 Stars3 Stars4 Stars5 Stars
Loading ... Loading ...
One response so far

Feb 20 2008

[lang_de]Lange Formulare kosten Geld[/lang_de][lang_en]long forms are expensive[/lang_en]

Veröffentlicht by . Filed under: eCommerce

[lang_de]Ich sage es meinen Kunden immer wieder gerne, auch wenn sie es nicht glauben möchten: zu lange Formulare, die zu viele Informationen abfragen, führen zu Bestellabbrüchen. Formulare sollten stets nur die Informationen abfragen, die auch dringend für den Ablauf einer Bestellung notwendig sind.

Heute bin ich auf eine sehr interessante Seite gestoßen: John Miller hat im Zusammenspiel mit Google AdWords nachgewiesen, dass diese Regel wirklich korrekt ist. Dabei hat er ermittelt, wie viele Kunden über unterschiedliche Formulare gewonnen werden konnten. Er kam primär zu folgendem Ergebnis:

  • kurze Formulare haben eine Erfolgsrate von 13,4% (in seinem Fall kostet damit ein neuer Kunde $31.24)
  • mittlere Formulare haben eine Erfolgsrate von 12,0% (Kosten: $34.94)
  • Lange Formulare haben eine Erfolgsrate von 10.0% (Kosten: $41.90

Soweit sollte also klar sein: Will man möglichst viele Kunden zu einem erfolgreichen Bestellabschluss führen, sollten so wenig Informationen wie möglich abgefragt werden. Ein sehr interessanter Teil des Ergebnisses ist jedoch der, dass die Angabe der Telefonnummer zu einer deutlich höheren Abbruchrate führt. Diese Information ist für die meisten Kunden also offensichtlich kritisch. Wenn man bedenkt, wie viele Shop-Systeme die Telefonnummer zwingend voraussetzen, ist diese Erkenntnis erschreckend!
[/lang_de]

[lang_en]Many clients want to save everything about users of their webshop. But this is a critical thing because it is known, that long forms prevent users of completing their shopping activities. It is very important that you only collect informations that are really necessary for you.

Today, I have found a really interessint page: John Miller has shown, that this rule is correct. To do this, he has used Googe AdWords to get new clients. By using different forms, he shows that smaller forms are better. His results for his example:

  • Short Form: Conversion rate 13.4%, cost per conversion $31.24
  • Medium Form: Conversion rate 12.0%, cost per conversion $34.94
  • Long Form: Conversion rate 10.0%, cost per conversion $41.90

You can see: If you want your clients to complete their shopping activities, you have to collect only information, that you really need. A very interesint part is, that phone numbers are very critical. It seems that most users don’t want to give this information. So think twice if you want to save a phone number!
[/lang_en]

1 Star2 Stars3 Stars4 Stars5 Stars
Loading ... Loading ...
No responses yet

Next Entries » | « Previous Entries

^