Blog

1 Jahr Blog

Heute vor einem Jahr habe ich meinen Blog gestartet.

Damals wusste ich noch nicht, welche Erfahrung ich damit machen würde. Heute, nach 366 Tagen und ein paar dutzend Blog-Einträgen bin ich ein wenig schlauer.

Denn erst mal ist so ein Blog doch mehr Arbeit, als ich dachte. Es fällt schwer, sich immer gute Themen auszudenken, und oft frage ich mich auch, ob das Thema überhaupt interessiert. Ein Blog ist ein weiteres Mittel der Selbstdarstellung im Web, und ich bin eher der Typ, der die Klappe hält, wenn er nichts zu sagen hat. Vielleicht keine gute Kombination? Vielleicht habe ich nur zu viele Hemmungen?

Auf jeden Fall werde ich meinen Blog aber beibehalten. Ich habe mir vorgenommen, in Zukunft häufiger etwas zu schreiben. Vielleicht fallen mir auch die entsprechenden Themen ein. 😉

Wie auch immer… Einen Witz wollte ich heute noch loswerden.

Ein Lastwagenfahrer transportiert eine Ladung Computer in seinem Anhänger. Nach einer langen Fahrt kommt er an einem abgelegenen Rastplatz vorbei und beschließt, dort eine Pause zu machen.

Am Eingang des Rasthauses steht ein riesiges Schild: “Keine Computerfreaks!” Der Fahrer ist verwundert, geht aber hinein, setzt sich an den Tresen und bestellt was zu Essen. Der Wirt schnuppert, schaut den Gast verwundert an und fragt ihn, was er denn beruflich mache. Er riecht so seltsam nach Computern.

“Ach, ich bin Lastwagenfahrer!” antwortet er. “Ich habe eine Ladung von dem Zeug in meinem Anhänger.” Der Wirt ist beruhigt und bedient ihn.

Plötzlich geht die Tür auf, und ein Typ mit geklebter Hornbrille, pickeligem Gesicht und einem PDA in der Hand betritt den Rastplatz. Der Wirt fackelt nicht lange, sondern holt eine Knarre unter dem Tresen hervor und schießt den Typen über den Haufen. Der Lastwagenfahrer hängt der Unterkiefer runter. Er kann nicht glauben, was er da eben gesehen hat. “Das war nur ein Computerfreak!” erklärt der Wirt ihm. “Davon gibt es hier zu viele. Sie sind Freiwild, man kann sie einfach abknallen. Sie brauchen noch nicht mal einen Jagdschein!”

Als der Fahrer fertig gegessen hat, steigt er wieder in seinen Laster und setzt seine Fahrt fort. Dennoch ist ihm die Gegend ein wenig unheimlich, und er möchte möglichst schnell weg. Und siehe da, da kommt schon so ein Wesen mit Zottelhaaren und einem Notebook unterm Arm auf die Straße gesprungen, direkt vor den Laster. Der Fahrer kann gerade noch ausweichen, aber bei der Aktion öffnet sich die Ladeklappe und die Computer purzeln auf die Straße. Aus allen Ecken tauchen nun Gestalten auf und machen sich über seine Fracht her. “Ich muss meine Fracht retten!” denkt sich der Fahrer, und an die Worte des Wirts denkend, holt er seine Waffe aus dem Laster und beginnt, die Freaks einem nach dem anderen abzuschießen.

Ein Polizeiwagen fährt vorbei und bremst mit quietschenden Reifen ab. Der Polizist springt aus dem Wagen. “Halt, hören sie sofort auf!” brüllt er.

“Was denn?” fragt der Fahrer. “Ich dachte, die Freaks sind Freiwild, und man darf sie einfach abschießen.”

“Das stimmt,” antwortet der Polizist, “aber es ist verboten, sie zu ködern!”

In dem Sinne: auf ein weiteres munteres Shredblog-Jahr. 😁

Speichereien

256MB RAM ist heutzutage nicht mehr wirklich viel auf einem Rechner, auf dem auch programmiert wird. Und da mein Rechner schon seit Längerem überwiegend mit Swappen beschäftigt ist, dachte ich, es ist höchste Zeit, dem Computer einen neuen Speicherriegel zu spendieren. Auf Grund des Alters der Kiste musste es ein PC100- oder PC133-SDRAM sein. Zum Glück gibt es diese Antiquitätchen noch im Handel, wahrscheinlich in verstaubten Schubladen in der hintersten Ecke des Lagers, direkt neben den Lochkarten.

Ich betrete also eine Filiale von Knauser&Meckernich, um dort den Speicher käuflich zu erwerben. Der Laden scheint relativ leer, und das Laienauge mochte die kurze Schlange vor dem Tresen tatsächlich getäuscht haben. “Och, nur sechs Leute vor mir,” mag der naive Computerspezi denken, der zum ersten Mal in diesem Laden ist, “das geht ja dann schnell.” Aber wer denkt, die Bedienung am Bauteiltresen in der Kölner Filiale eines Hirschauer Elektronikversandriesen ist an Trägheit nicht mehr zu überbieten, wird sich hier eines Besseren belehren lassen müssen. Mit lässiger Routine fertigen hier zwei Bedienstete die Kunden in Seelenruhe ab, und nehmen sich auch gerne Zeit für eine ausführliche Beratung. Jederzeit. Den Kunden freut’s natürlich… Solange er nicht in der Schlange steht.

Ich bin allerdings nicht das erste Mal dort, und so wusste ich, dass ich mir diesmal wieder die Beine in den Bauch stehen werde. Ich ließ meinen Blick über die Einrichtung des Ladens schweifen. Gewiss, man geht hier nicht hin, um sein Auge von einer schönen Inneneinrichtung verwöhnen zu lassen, sondern einfach nur um gnadenlos Geld zu sparen. Dem entsprechend ist halt alles spartanisch. Schmucklose weiße Holzregale, randvoll gestopft mit Hardware aller Art. Im Hintergrund ragen Towergehäuse wie Wolkenkratzer von einem Metallregal in die Höhe. Drei Stühle in einer Ecke vermitteln ein Gemisch von Luxus und Wartezimmeratmosphäre. Falls einem kurz vor dem Tresen die Beine weich werden, kann man sich mit letzter Kraft auf einen dieser Stühle retten. Nur einschlafen sollte man dann nicht.

Ein junges Pärchen vor mir kommt an die Reihe. Sie möchte eine neue Festplatte und eine dickere Grafikkarte, braucht Beratung vom einen Verkäufer. Der andere Bedienstete fertigt in der Zeit einen Kunden in der Express-Ecke ab. Ein zweiter Kunde in der Express-Ecke wirkt leicht genervt, scheint er dort doch noch länger warten zu müssen als ein regulärer Kunde. Ich machte mir Gedanken, ob das Express-Schild, das dort an der Decke hängt, nicht ein genialer Einfall von Selbstironie ist. Vielleicht gibt es hier sogar den Lebensmitteldiscountern ähnliche Versöhnungs-Aktionen, halt nur auf die ganz eigene Art des Hauses. So etwas wie “Wenn sie kürzer als 10 Minuten warten müssen, erhalten Sie 5 Euro”. Ich muss kichern.

Der Mann an der Theke holt dem Pärchen einen RAID-Controller. Nicht zum Kaufen, nur zum Betrachten. Nur noch ein Herr vor mir trennt mich mittlerweile davon, bedient zu werden. Ich stelle mir vor, dass er einen Einkaufszettel für seinen neuen Komplett-PC aus der Tasche zücken wird und dann mit dem Verkäufer stundenlang darüber diskutiert, ob er noch ein 3½-Zoll-Diskettenlaufwerk braucht oder doch nicht mehr. Hoffentlich verhungert er, bevor er an der Reihe ist.

Eine Preisliste an der Wand fängt meine Aufmerksamkeit und verdrängt den Gedanken an meinen Vordermann. Ich lese sie. Kühlermontage auf die CPU: € 5. Eine Windows-Installation inklusive Test: € 30. Das Zusammenschrauben eines Komplett-PCs: € 100. Reklamation einer Komponente, die in deren Testrechner dann doch läuft: € 10. Kulanz: unbezahlbar.

Der zweite Angestellte aus der Express-Ecke hat den einen Kunden schließlich abgefertigt, den anderen zum weiteren Warten verdonnert und kümmert sich nun um den Herren vor mir. Hurra, danach komme ich endlich dran! Ich werfe einen Blick hinter mich auf die bedauernswerten Kreaturen, die das Warten noch vor sich haben. Die Schlange geht mittlerweile fast bis zur Tür.

Das Pärchen lässt sich davon jedoch nicht beeindrucken. Sie lassen sich weiter ausgiebig beraten. Manchmal wünsche ich mir, ich hätte auch so die Ruhe weg wie die Leute hier. Der Herr vor mir wollte doch keinen Komplett-PC, sondern nur eine Festplatte, die aber nicht mehr vorrätig war. Die letzte wurde am Nachmittag verkauft. Er räumt frustriert das Feld. Sein Verkäufer geht wieder zur Express-Ecke. Der Kunde dort setzt mittlerweile Spinnweben an. Ich warte weiter.

Nach einer Ewigkeit wird das Pärchen dann doch mal fertig. Gekauft haben sie nichts. Das Ergebnis der langen Konversation war ein Ausdruck auf einem Blatt Recycling-Endlospapier. Na egal… Ich bin endlich dran, rücke vor zum Tresen.

“Was bekommen Sie?” fragt mich der Verkäufer.

“Einen 256MB PC133 SDRAM bitte” antworte ich. Der Verkäufer tippt was in den Rechner. Der Speicher ist vorrätig.

“Wissen Sie, ob der Speicher in Ihrem Rechner funktionieren wird?” fragt er weiter. Scherzkeks! Woher soll ich denn wissen, ob mein Computer den neuen Speicher mögen wird? Das ist so absurd wie die Frage, ob es in einer Sache unvorhersehbare Probleme geben wird.

“Wenn der Speicherriegel wegen Inkompatibelität nicht läuft, können Sie ihn nicht umtauschen.” belehrt mich der Verkäufer, und ich meine für einen Moment ein Grinsen in seinem Gesicht zu sehen. “Wir stecken ihn dann hier in den Testrechner, und wenn er läuft, haben Sie Pech gehabt.” Aha… Das ist, als würde mir ein Schuhverkäufer sagen, ich könne einen Schuh nach dem Anprobieren nicht umtauschen, denn der Schuh ist ja technisch vollkommen in Ordnung und wenn er nicht an meinen Fuß passt, ist das mein Problem.

Ich erinnere mich an die Preisliste. “Wohlmöglich darf ich den Test dann auch noch bezahlen?” frage ich ihn. Er grinst jetzt wirklich. “Nein, dafür würde ich Ihnen kein Geld abnehmen.” Er vielleicht wirklich nicht, aber was ist mit seinem Kollegen aus der Express-Ecke? Die Sache stinkt.

Ich versuche es mit Protest. “Was soll ich denn dann mit einem intakten Speicherriegel, wenn er in meinem Computer nicht funktioniert?”

Er zuckt nur mit den Achseln.

“Und was soll ich Ihrer Meinung nach jetzt machen?” frage ich ihn weiter.

“Am besten bestellen Sie in unserer Versandzentrale, dann haben Sie 14 Tage Umtauschrecht.” Dass ich dann aber auch Portokosten zu tragen habe, ist so selbstredend, dass er das schon gar nicht erst erwähnt. Mir reicht’s jetzt. Die Katze im Sack kaufe ich gewiss nicht.

Resigniert bedanke ich mich bei dem Verkäufer und gehe. Vorbei an der Schlange mit den anderen Wartenden, die mich zur Tür eskortiert. Manche Leute scheinen völlig irritiert zu sein, weil ich schon so schnell fertig geworden bin. Für Knauser&Meckernich ist das wahrhaft ungewöhnlich.

PS: Die Konkurrenz zickte übrigens gar nicht herum. Umtauschrecht innerhalb von 14 Tagen, kein Problem, bittesehr! War auch nicht wirklich teurer, und warten brauchte ich da auch nicht.

Ende der Abzocke

Liebe junge Leute, um diesem Artikel von 2004 etwas Sinn zu geben: Zu der Zeit war es noch üblich, sich mit einem Modem ins Internet einzuwählen. Man wählte die Telefonnummer seines Providers und surfte dann zum Minutenpreis über die Telefonleitung. Bei der Betrugsmasche, um die es hier geht, stellte eine Malware - der so genannte Dialer - die Rufnummer heimlich auf eine teure Abzock-Nummer um. Die “Überraschung” kam dann zum Monatsende in Form einer Telefonrechnung in vierstelliger Höhe.

Heutzutage geht praktisch jeder per DSL, Kabel oder Mobilfunk ins Internet. Dort funktioniert die Masche schon technisch nicht.

Kaum etwas verkörpert die Abzocke im Internet besser als der so genannte Dialer. Selbst Gesetzesänderungen schienen ihm kaum etwas anhaben zu können. Doch jetzt hat das BGH Recht gesprochen.

Ein Dialer ist ein Programm, dass die Internet-Verbindungseinstellungen des Rechners auf einen anderen Anbieter umstellt; meist auf eine teure 0190- oder 0900-Nummer. Die wenigen seriösen Dialer, die die Verbindungskosten vorher deutlich bekannt geben, sind dabei von dem Urteil nicht betroffen. Es geht hier vielmehr um die “Abzock-Dialer”, welche das System unbemerkt umstellen. Wenn sie vorher überhaupt fragen, geben sie sich lediglich als “Optimierungstool für Internet-Verbindungen” aus, verschweigen die dabei anfallenden immensen Kosten jedoch. Wenn man die Frage, ob er sich installieren soll, verneint, installieren sie sich meist erst recht, und auch eine Deinstallation hilft selten wirklich. Andere Dialer installieren sich völlig verborgen. Abzock-Dialer durchseuchen das Netz zunehmend, man findet sie nicht mehr nur auf Pornoangeboten, sondern auf Seiten zur Währungsumrechnung oder mit Geburtstagsgedichten, in E-Mails und mittlerweile sogar auf Webseiten, die speziell für Kinder gemacht sind. Manche nutzen Sicherheitslücken des Windows-Betriebssystems, um sich unbemerkt aktivieren zu können.

Selbst ein kürzlich dazu erlassenes Gesetz, das eine Registrationspflicht für Dialer eingeführt hat und die Kosten begrenzt, konnte dem Treiben kaum einhalt gebieten. Wer sowieso Recht bricht, schert sich wenig um neue Gesetze.

Das Problem des betrogenen Kunden ist, dass der Betrüger selten auszumachen ist. Die 0190-Nummern werden von der RegTP im Block an Netzbetreiber vergeben, welche ihrerseits Teile des Blockes an Mehrwertdienstunternehmen vermieten. Oft sitzt hinter den betrügerischen Dialer-Unternehmen jedoch eine Briefkastenfirma im Ausland. Es fällt immens schwer, überhaupt die Adresse des Betrügers ausfindig zu machen, und wenn er im Ausland sitzt, hat man schließlich wenig Chancen, sein Geld zurück zu erhalten.

Der Telefonnetzbetreiber, der seinem betrogenen Kunden eigentlich helfen sollte, zuckt meist mit den Schultern, weil er die gleichen Probleme hat, den Betrüger ausfindig zu machen - aber verdient dennoch an dem ergaunerten Geld mit, da er einen Teil der 0190-Gebühren für Mehrwertdienste einbehält.

Die Forderung nach Gegenmaßnahmen verpufften. So recht schienen die Netzbetreiber kein Interesse zu haben, ihre Kunden zu schützen und den Betrugsmaschen ein für allemal einen Riegel vorzuschieben.

Das Urteil des BGH vom Freitag wird dies nun ändern. Das BGH hat nämlich festgestellt, dass der Netzbetreiber an den 0190-Nummern mitverdient, und deshalb auch ein Risiko mittragen muss. Für den Kunden heißt es, wenn er einen betrügerischen Dialer untergeschoben bekommen hat, braucht er die von ihm verursachten Gebühren nicht zu zahlen, sondern nur die Onlinegebühren, die er hätte bezahlen müssen, wenn der Dialer nicht installiert gewesen wäre. Der in diesem Fall beklagte Telefonnetzbetreiber blieb also auf den Gebühren von €9000 sitzen, die der Dialer beim Kunden verursacht hatte.

Zugegeben: der Netzbetreiber ist nicht Verursacher des Problems gewesen, er hat jetzt lediglich den schwarzen Peter zugeschoben bekommen. Allerdings hat der Netzbetreiber eher die Macht und die Möglichkeit, die Verträge mit den Mehrwertdiensteanbietern zu gestalten und zum Beispiel die Haftung für betrügerische Dialer weiterzureichen, bis es letztendlich den Betrüger selbst treffen würde. Damit würde dieser Sumpf der Abzock-Dialer endgültig ausgetrocknet werden.

Und das wird auch wirklich höchste Zeit!

Das BGH-Urteil trägt das Aktenzeichen III ZR 96/03.

Spam-Statistik

Meine offizielle Spam-Statistik für August 2003

Insgesamt erhielt ich im August 595 Spam-Mails und 4 Viren, das macht im Schnitt 19,3 Mails pro Tag. Wenn der Spam halten würde, was er verspricht, hätte ich am Monatsende folgendes zusammen gehabt:

Körper und Gesundheit

  • Diät: 45 Monatsrationen HGH umsonst. Damit hätte ich in fast 4 Jahren gut 1350 kg abnehmen können.
  • Penis: Verlängerung um 325 inches. Das entspricht einer Penislänge von über 8 Metern.
  • Viagra: 2 Flaschen und 5 Tabletten kostenlos.
  • Brustvergrößerung: 3 Flaschen umsonst. Das entspräche einer Vergrößerung um 9 Cups.
  • Rauchen: 2 mal Rauchen aufhören in zwei Wochen. Dabei bin ich Nichtraucher.

Geld

  • Nigeria-Connection: US $273.520.000,00 hätte ich als “vertrauenswürdiger Partner” anteilig bekommen.
  • Lottogewinne: US $7.000.000,00 habe ich im Lotto gewonnen, obwohl ich kein Lotto spiele.
  • Geldgewinne: US $30,00 habe ich einfach so gewonnen.
  • Versicherungen: € 8.000,00 pro Jahr hätte ich an Versicherungsprämien sparen können. Das ist mehr, als ich pro Jahr für Versicherungen ausgebe.

Partnerschaft

  • Videonachrichten: 9 mal habe ich eine Videonachricht erhalten, aber nie abgerufen. Wie gemein von mir!
  • Nette Nacht: 1 mal bedankte sich eine unbekannte Frau für die nette Nacht mit mir.
  • Kontaktanfrage: 2 Frauen wollten mit mir zwecks Partnerschaft in Kontakt treten.

Sonstiges

  • Diplome: 2 Diplome beliebiger Art hätte ich mir kaufen können.
  • Reisen: 12 Tage Bahamas und 9 Tage Orlando mit freiem Eintritt in Disney World habe ich geschenkt bekommen.

Mit anderen Worten: Ich würde nun mehrfacher Multimillionär sein und mich am Strand der Bahamas als Prof. Dr. mit athletischer Figur, einem 8 Meter langen Schwanz und Titten, die Dolly Buster erblassen lassen würde, mit einem Dutzend schöner Frauen amüsieren. Und da sag noch mal einer, Spam macht nicht glücklich… Nur das Viagra könnte ich nicht nehmen, da der Blutsturz mich umbringen würde. 😆

Parameterprüfung

Hier wird beschrieben, wie du durch Parameterprüfung deine Seite absichern kannst.

Traue grundsätzlich niemandem

Wenn man PHP-Seiten entwirft, kommt man zwangsläufig mit Parametern in Kontakt, die dem Script über den Aufruf übergeben werden. Diese Parameter sind ein ganz simpler Angriffspunkt für Hacker, da sie sich sehr leicht manipulieren lassen.

Grundsatzregel ist also: misstraue immer allen Daten, die vom Benutzer kommen! Neben den Parametern, die man in $_GET und $_POST findet, gehören auch die Cookies dazu, da sie beim Benutzer lokal abgelegt werden und von ihm manipuliert werden können. PHP fasst alle Parameter, die grundsätzlich suspekt sind, in dem superglobalen Array $_REQUEST zusammen. Allerdings lässt sich auch der HTTP-Request vom Browser manipulieren, so zum Beispiel der HTTP_REFERER.

Die einfachste Art der Manipulation ist, bei einem GET-Request einfach die Parameterzeile im Browser zu verändern. Eine URL wie

posting.php?id=13&admin=no

schreit geradezu danach, mit den Werten herumzuspielen. Ich könnte zum Beispiel die ID verändern und so vielleicht an Postings kommen, die ich eigentlich gar nicht lesen dürfte. Oder ich setze admin auf yes und schaue, ob ich dann unerlaubt Admin-Rechte erhalte.

Man darf sich also grundsätzlich nicht darauf verlassen, dass die übergebenen Parameter vernünftig oder gültig sind. Selbst Einschränkungen zum Beispiel über eine begrenzte Auswahl in Select-Boxen oder eine Formularprüfung per JavaScript lassen sich auf diese Weise hervorragend aushebeln. Ebenso lassen sich eigentlich nicht änderbare Werte in hidden-Feldern vom Angreifer jederzeit verändern.

Es hilft nicht wirklich, die Parameter in der URL durch Frames oder POST-Requests zu verschleiern. Auch wenn eine Manipulation dann erschwert wird, ist sie dennoch weiterhin möglich. Frames lassen sich umgehen, und POST-Requests ganz leicht durch ein selbstgebautes kleines HTML-Formular nachbilden.

Also noch einmal: misstraue immer allen Daten, die vom Benutzer kommen!

Sensible Daten in Sessions auslagern

Eine Abhilfe ist schon mal, besonders sensible Daten nicht per Parameter an das nächste Script zu übergeben, sondern über die Session. Da die Session-Daten selbst auf dem Server gespeichert werden, hat der Benutzer keine Möglichkeit, diese zu lesen oder zu manipulieren.

So gehören also zum Beispiel die User-ID des eingeloggten Users oder etwa Rechte-Flags in die Session. Also einfach alles, wodurch sich der Benutzer durch Änderung der Werte Rechte erschleichen könnte, die er eigentlich nicht hat. Aber auch SQL-Queries sollten niemals als Parameter übergeben werden, sondern immer über die Session.

Permanente Daten gehören in eine Datenbank

Sessions leben nur so lange, bis der Browser geschlossen wird. Daten, die länger gespeichert werden sollen, kann man beim Benutzer als Cookie ablegen. Aber auch Cookies sind manipulierbar und damit stets suspekt.

Sensible Daten wie Benutzerrechte dürfen nicht im Cookie abgelegt werden. Eine Möglichkeit wäre, die Daten statt dessen auf dem Server in einer Datenbank zu speichern und dann lediglich eine Benutzerkennung im Cookie abzulegen. Der Benutzer darf allerdings keine Möglichkeit haben, durch Manipulation am Cookie eine andere Benutzerkennung zu erraten. Lege also bitte keine User-ID im Cookie ab. Stattdessen kannst du per Zufallszahlengenerator einen zufälligen Text erzeugen lassen, der durch md5() gehashed und dann mit in die Datenbank abgelegt wird. Dieser Hash-Code kann im Cookie abgelegt werden, denn es ist praktisch ausgeschlossen, den Hash-Code eines anderen Benutzers zu erraten.

Die sicherste Methode, Benutzerdaten permanent auf dem Server zu halten, ist allerdings nach wie vor, Benutzerkonten zu führen und jeden Benutzer zu bitten, sich am Anfang mit einem Usernamen und einem eigenen Passwort in das System einzuloggen.

Parameterprüfung

Ein weiterer wichtiger Schritt ist, die an das Script übergebenen Parameter auf plausibilität zu prüfen, also zu kontrollieren, ob der Wert auch sinnvoll ist. Diese Prüfung sollte ganz am Anfang erfolgen, noch bevor andere Programmteile auf die Parameter zugreifen. Ist ein Wert offensichtlich manipuliert worden, sollte das Script sich sofort beenden (zum Beispiel mit die()), um eine fehlerhafte Verarbeitung durch den falschen Wert zuverlässig zu verhindern. Da dieser Fehler nur durch einen gezielten Angriffsversuch ausgelöst werden kann, kann auf eine schmucke Fehlerseite verzichtet werden.

Ein Wert wurde zum Beispiel offensichtlich manipuliert, wenn man eine Selectbox im Formular hatte und nun einen Wert bekommt, der dort gar nicht zur Auswahl stand. Oder wenn man eine Datenbank-ID erhält, die es gar nicht in der Datenbank gibt.

Es liegt allerdings kein Manipulationsversuch vor, wenn der Benutzer schlicht und einfach eine falsche Eingabe gemacht hat. Wenn du also zum Beispiel ein einfaches Texteingabefeld für eine Jahreszahl hast, und du dort eine vierstellige Jahreszahl erwartest, der Benutzer aber nur “90” (für 1990) eingibt, ist das natürlich kein bösartiger Angriff, sondern nur eine Fehleingabe. Du solltest den Benutzer dann mit einer sprechenden Fehlermeldung höflich darauf hinweisen, was er falsch eingegeben hat und wie er eine richtige Eingabe tätigt, statt gleich das ganze Script abzubrechen und die Alarmglocken schrillen zu lassen.

Hilfreich für den Benutzer ist auch eine Formularprüfung per JavaScript, noch bevor die Daten zum Server geschickt werden. Das Formular sollte allerdings auch ohne JavaScript abzuschicken sein, und es sollte immer auch eine zusätzliche Überprüfung auf dem Server stattfinden! Ein Angriff lässt sich niemals durch geschickte JavaScript-Programmierung verhindern.

Ein Beispiel

Eine einfache Möglichkeit der Parameterprüfung ist, alle Parameter, die man erwartet, durch Prüffunktionen zunächst prüfen zu lassen. Diese Funktionen prüfen zumindest elementar die übergebenen Werte und kopieren sie im Erfolgsfall in ein eigenes, sichereres Parameter-Array um. Diese Funktionen können sich gleichzeitig um die Entfernung von Magic-Quotes kümmern.

Die grundlegendste Prüffunktion ist parText(). Sie erwartet den Namen des Parameters und optional einen Defaultwert, wenn der Parameter nicht übergeben wurde. Er liefert true zurück, wenn der Parameter übergeben wurde, sonst false.

function parText($name, $default=null) {
  global $PAR;
  $PAR[$name] = $default;
  if(isset($_REQUEST[$name])) {
    $val = $_REQUEST[$name];
    if(get_magic_quotes_gpc()) $val = stripslashes($val);
    $PAR[$name] = $val;
    return true;
  }
  return false;
}

Ein paar Beispiele, wie man so eine Parameterprüfung aufrufen kann:

require_once('parameter.php');      // die Funktion einbinden

// 1: Es gibt einen optionalen Parameter namens 'foo'.
parText('foo');

// 2: Es gibt einen optionalen Parameter 'foo'. Gibt es ihn nicht,
//    wird 'Hallo' als Defaultwert angenommen.
parText('foo', 'Hallo');

// 3: Parameter 'foo' ist ein Pflichtparameter. Gibt es ihn nicht,
//    liegt eine Manipulation vor.
if(!parText('foo')) die("Parameter 'foo' fehlt!");

// Der Wert von 'foo' liegt anschließend im Array $PAR
if(isset($PAR['foo'])) {
  print("foo ist: ".htmlspecialchars($PAR['foo']));
}else {
  print("foo ist nicht übergeben worden.");
}

Das Array $PAR ist natürlich keine superglobale Variable und muss in Funktionen weiterhin mit global $PAR eingebunden werden. Durch diese Trennung weiß man jedoch, dass die Werte in $PAR zumindest eine einfache Prüfung durchlaufen haben und dadurch ein wenig vertrauenswürdiger sind als die Werte in $_REQUEST.

Analog dazu kann man jetzt weitere Prüffunktionen schreiben. Für die meisten Eingabefelder a la input type="text" reicht es zum Beispiel, den Text auf 256 Zeichen zu begrenzen. Da die Eingabe nur eine Textzeile zulässt, können außerdem alle Zeilenumbruch-Steuerzeichen herausgefiltert werden. In Code gegossen sieht das dann so aus:

function parPlain($name, $default=null) {
  global $PAR;
  $PAR[$name] = $default;
  if(isset($_REQUEST[$name])) {
    $val = trim($_REQUEST[$name]);
    if(get_magic_quotes_gpc()) $val = stripslashes($val);
    if(strlen($val)>256) $val = substr($val,0,256);
    $PAR[$name] = preg_replace('/(\n|\r)*/', '', $val);
    return true;
  }
  return false;
}

Erwarte ich zum Beispiel eine natürliche Zahl als Eingabe, kann ich folgende Funktion verwenden:

function parInt($name, $default=null) {
  global $PAR;
  $PAR[$name] = $default;
  if(isset($_REQUEST[$name])) {
    $val = trim($_REQUEST[$name]);
    if(get_magic_quotes_gpc()) $val = stripslashes($val);
    $PAR[$name] = intval($val);
    return true;
  }
  return false;
}

Nachdem überflüssige Leerzeichen abgeschnitten wurden, wird mittels der Funktion intval() anschließend sicher gestellt, dass sich im umgesetzten Parameter in $PAR garantiert eine Zahl befindet. Im Anschluss könnte man noch prüfen, ob die Zahl innerhalb eines Gültigkeitsbereichs liegt.

Die Vorprüfung für ein Formular mit User-ID, Vor- und Nachname sowie einem optionalen Freitext sähe dann zum Beispiel so aus:

require_once('parameter.php');      // die Funktion einbinden

// User-ID (Pflichtparameter)
if(!parInt('id'))         die("Parameter 'id' fehlt!");

// Vor- und Nachname (Pflichtparameter)
if(!parPlain('vorname'))  die("Parameter 'vorname' fehlt!");
if(!parPlain('nachname')) die("Parameter 'nachname' fehlt!");

// Ein mehrzeiliger Freitext (optional)
parText('freitext');

Dies ist allerdings nur eine sehr grundlegende Prüfung. Es sollten nun weitere Prüfungen folgen, zum Beispiel ob die User-ID gültig ist.

Behandlung von Passwörtern

Wenn du in einem Formular ein Eingabefeld für Passwörter verwendet, solltest du stets das input type="password"-Eingabefeld verwenden. Dies schützt das Passwort vor neugierigen Blicken auf den Bildschirm.

Außerdem sollten Formulare mit Passwörtern stets ausschließlich per POST an den Server geschickt werden. So erscheint das Passwort niemals in der URL und wird zum Beispiel auch nicht in Proxies zwischengespeichert.

Entsprechend solltest du im Script das Passwort nur von dem $_POST-Array entgegennehmen, nicht jedoch von $_GET oder von $_REQUEST.

Dateiuploads

Dateiuploads lassen sich bei PHP über ein Hidden-Feld in dem Formular in der Größe beschränken. Aber auch dieses Feld ist manipulierbar. Du solltest also unbedingt auch noch im Script prüfen, ob die empfangene Datei das Größenlimit überschritten hat, und gegebenfalls die Ausführung abbrechen.

Mittlerweile sollte sich auch herumgesprochen haben, dass man für Dateiuploads stets das $_FILES-Array oder die is_uploaded_file()-Funktion zur Prüfung verwenden sollte. Gerade der Dateiupload bietet eine relativ einfache Möglichkeit für einen Angreifer, Dateien und Passwörter vom Server auszuspähen, wenn man hier nicht sorgfältig genug vorgeht.

Code-Injections

Größte Vorsicht ist geboten, wenn man Parameter vom Server als Programmteil ausführen lässt, wenn sie also ganz oder teilweise an system(), eval(), mysql_query() oder entsprechend andere Funktionen übergeben werden. Du gibst damit einem Angreifer die Chance, Daten auszuspähen oder massiven Schaden anzurichten.

Bei Funktionen wie include() oder require() erlaubt es PHP normalerweise, auch externe Quellen (per “http://”, “ftp://” etc) anzugeben. Wenn ein Parameter ungeprüft an include() übergeben wird, könnte ein Angreifer so sehr bequem ein beliebiges externes Script einbinden.

Solche Parameter lassen sich nur schwer auf bösartigen Code überprüfen, du solltest es also meiden wie der Teufel das Weihwasser! Wenn es sich absolut nicht vermeiden lässt, solltest du entsprechende Vorsichtsmaßnahmen ergreifen und darauf achten, dass sich diese Maßnahmen nicht aushebeln lassen. Siehe dazu auch den Artikel über SQL-Injections.

Zusammenfassung

Um dich gegen Angriffe durch manipulierte Parameter zu schützen, solltest du:

  • grundsätzlich allen Daten misstrauen, die vom User kommen (GET-Parameter, POST-Parameter, Cookies, HTTP-Header)!
  • sensitive Daten niemals per Request, sondern per Session an andere Scripte weitergeben.
  • alle Parameter vor ihrer Benutzung auf Plausibilität prüfen.
  • niemals Parameter an system(), eval(), mysql_query() oder andere Funktionen der Art übergeben, ohne sie gründlich zu prüfen und vor dem Aushebeln der Prüfmechanismen zu schützen.
  • Passwörter stets mit POST übertragen und nur vom $_POST-Array entgegennehmen.

Plausibilitätsprüfungen schließen ein:

  • Sind alle Pflichtparameter vorhanden?
  • Ist ein erwarteter numerischer Wert (Datenbank-ID) wirklich numerisch?
  • Existiert ein Datenbankeintrag mit der übergebenen ID?
  • Enthält ein einzeiliges Eingabefeld unerlaubte Zeichen (z.B. Zeilenumbrüche)?
  • Wurde von einer Selectbox ein Wert übermittelt, der gar nicht in der Selectbox stand?
  • Wurden Mehrfachparameter übergeben, obwohl nur eine Einfachauswahl erlaubt ist? Wurden beispielsweise mehrere Radio-Buttons einer Gruppe ausgewählt, oder mehrere Einträge einer Selectbox mit Einfachauswahl?
  • Wurde die Datei tatsächlich hochgeladen und übersteigt sie nicht die erlaubte Maximalgröße?
  • Hat der Benutzer tatsächlich das Recht, die Aktion auszuführen oder den Datenbankeintrag zu sehen?