PHPGangsta - Der praktische PHP Blog

PHP Blog von PHPGangsta


Archive for the ‘curl’ tag

Bug bei Authentifizierung in curl

without comments

CURLcurl hat in der aktuell verwendeten Version im stabilen Ubuntu 13.10 einen Bug, der sich auch rein bis in die PHP-Scripte auswirkt.

Wenn man bei der Nutzung von curl die Authentifizierung nutzt und im Passwort ein Semikolon enthalten ist (was gute Passwörter ja so an sich haben), dann wird dieses Passwort abgeschnitten. Folgender Beispielcode:

$curlSettings[CURLOPT_HTTPAUTH] = CURLAUTH_BASIC;
$curlSettings[CURLOPT_USERPWD]  = '1testuser' . ':' . 'pass;word';

$curl = curl_init('http://www.phpgangsta.de/download/curl_auth_test.php');
               // content:   echo 'Password: '.$_SERVER['PHP_AUTH_PW'];
curl_setopt_array($curl, $curlSettings);

curl_exec($curl);
// should output:   Password: pass;word
// wrong output:    Password: pass

Es wird mittels des curl-Parameters CURLOPT_USERPWD der Username und das Passwort übertragen, und wie man an der Antwort des Servers sieht kommt nur das Passwort bis zum Semikolon beim Server an, es wird abgeschnitten.

Weiterlesen »

Written by Michael Kliewe

Februar 20th, 2014 at 1:11 pm

Posted in PHP

Tagged with , , ,

POST-Request mit mehreren gleichen Parametern verschicken

with 26 comments

Ich hatte ein komisches Problem, bei dem ich auch erstmal nachdenken und nachlesen musste wie ich das gelöst bekomme. Folgende Ausgangssituation:

Ich musste einen POST-Request machen zu einem Webserver. Soweit kein Problem. Doch bei diesem Request war das besondere dass es mehrere POST-Parameter gab mit dem selben Namen. Beispiel:

attr=blue
attr=yellow
attr=green
amount=14

Weiterlesen »

Written by Michael Kliewe

September 5th, 2012 at 10:34 am

Posted in PHP

Tagged with , , , ,

Push Notifications in Android Apps via C2DM

with 6 comments

Seit Android 2.2 gibt es in Android Apps die Möglichkeit auf Push-Nachrichten zu reagieren. Dieser Dienst wird Cloud to Device Messaging oder kurz C2DM genannt.

Die App registriert sich dazu bei den C2DM Servern an und bekommt dafür eine DeviceRegistrationID. Ab dann wird die Verbindung zwischen dem Android Market (neuerdings Google Play genannt) und den Google-Servern genutzt um die Push-Nachrichten auf das Handy zu bekommen.

Die DeviceRegistrationID muss die App dann an unseren Server melden, und alle Nachrichten an diese DeviceRegistrationID kommen dann auf genau diesem Handy an. Sollte das Handy ausgeschaltet sein werden die Nachrichten zugestellt sobald das Handy (und die App) wieder gestartet sind. Falls alle Nachrichten den selben „Collapse Key“ haben wird nur die neueste zugestellt.

Der Server, der eine Nachricht senden möchte, sendet dazu einen POST Request an Googles C2DM Dienst. Der Text der Nachricht ist auf maximal 1024 Byte beschränkt, sollte also nur für kurze „Aufweckpings“ bzw. Nachrichten a la „Es gibt Neuigkeiten vom Typ X, frag beim Server nach“ geeignet sein.

Weiterlesen »

Written by Michael Kliewe

März 20th, 2012 at 9:56 am

Local File Inclusion: Einige Beispiele

with 10 comments

Ich habe schon länger keine sicherheitsrelevanten Probleme mehr gepostet, heute schauen wir uns ein paar häufig gemachte und exisierende Fehler an. Schaut euch diesen Code-Schnipsel an:

<?

$url = $_POST['imageUrl'];

$content = file_get_contents($url);

// Put the content of that URL into a database for later use/display

Der Benutzer der Webseite kann also in ein Formular eine URL eintippen, beispielsweise die URL eines Bildes, einer XML-Datei oder einer Webseite. Das Script ruft diese Resource (z.B. ein Avatar Bildchen) ab und speichert es auf der Festplatte oder in einer Datenbank.

Auf einer anderen Seite kann der Benutzer (und vielleicht alle anderen Besucher der Webseite) dieses Bild dann abrufen.

Gibt es hier ein Sicherheitsloch? Ja, gleich mehrere! Was passiert wenn der Benutzer zum Beispiel folgende URLs eingibt:

Weiterlesen »

Written by Michael Kliewe

März 16th, 2012 at 10:05 am

Asynchron Aufgaben erledigen (lassen)

with 9 comments

Was könnte der Autor damit meinen, werdet ihr euch fragen. Naja, das ist schnell erklärt: hier und da hat man mal kleine Aufgaben, die evtl. etwas länger dauern, von dessen Ergebnis der User aber nicht wissen muss. Warum also soll man damit seine PHP-Scripte ausbremsen, und den User warten lassen? Ihn interessiert das Ergebnis ja (erstmal) nicht.

Beispiel: Nehmen wir an, das Versenden eine Informations-Email würde 1 Sekunde dauern (wenn man über einen externen SMTP versendet und nicht über den lokalen, kann das sogar sein). Dann bemerkt der User auf der Webseite eine Verzögerung, die Seite wird langsam.

Es gibt sicherlich noch bessere Beispiele, wie z.B. das Berechnen eines Vorschaubildes. Der User lädt ein Bild hoch (Avatar), und wir brauchen davon eine verkleinerte Version. Wenn dieser Algorithmus nun langsam wäre (was er im Normalfall nicht ist), würde der User vor seinem Bildschirm Däumchen drehen.

Für all solche Aufgaben (ihr findet sicherlich bessere) ist es sinnvoller, diese Aufgaben asynchron erledigen zu lassen. Da gibt es mindestens 2 Möglichkeiten:

  • Man trägt die Aufgabe in eine Task-Tabelle in der Datenbank ein, und lässt ein weiteres Script (Cronjob?) diese Task-Liste abarbeiten.
  • Man lässt einen Kindprozess diese Arbeit erledigen, welcher geforkt wird, und non-blocking ist

In beiden Fällen bekommt der User direkt die nächste Seite zu sehen und kann weiterarbeiten, der asynchrone Prozess kann aber erst einige Sekunden/Minuten später fertig sein.

Wie setzt man das nun um? Ich glaube, die erste Möglichkeit sollte jedem von euch bekannt sein, da es keine Schwierigkeit ist, eine neue Zeile in einer Datenbank-Tabelle einzufügen, und auch ein Script, das periodisch diese Zeilen liest und abarbeitet, sollte kein Hexenwerk sein.

Die zweite Möglichkeit haben wahrscheinlich deutlich weniger Leute genutzt. Ich finde sie auch ehrlich gesagt unschöner, aber möchte sie trotzdem vorstellen (da sie schneller umzusetzen ist, und häufig auch zum Ziel führt). Als erstes fällt einem da vielleicht der system() Aufruf ein, mit dem man einen weiteren Prozess starten kann. Das Problem daran ist, dass er blocking ist, sprich der nächste Befehl in PHP erst ausgeführt wird nachdem der System-Aufruf beendet ist. Genau das wollen wir ja nicht. Aber unter jedem Betriebssystem gibt es da Möglichkeiten, den Prozess in den Hintergrund zu schieben. Der system() Aufruf ist dann sofort beendet und PHP läuft weiter, parallel läuft ein weiterer Prozess mit der Aufgabe.

function execInBackground($cmd) {
	if (substr(php_uname(), 0, 7) == "Windows") {
		pclose(popen("start /B ". $cmd, "r"));
	}
	else {
		system($cmd . " > /dev/null &");
	}
 }

In Maugrim The Reaper’s Blog gibt es eine sehr ausführliche Serie zu dem Thema, mit vielen weiteren Beispielen und Code. Auf jeden Fall lesenswert.

Eine andere interessante Möglichkeit ist Gearman.
http://toys.lerdorf.com/archives/51-Playing-with-Gearman.html

Wenn man etwas andere Voraussetzung hat, könnten die curl_multi_* Funktionen interessant sein. Diese kann man nutzen, wenn man viele Dinge zu erledigen hat, aber auf die Ergebnisse warten muß (weil man sie dem User anzeigen muss). Man möchte also nicht asynchron, sondern simultan arbeiten. Das ganze ist in einem Blogartikel zum Thema „Simultaneuos HTTP requests in PHP with cURL super beschrieben.

Written by Michael Kliewe

Oktober 30th, 2009 at 7:49 pm

Posted in PHP

Tagged with , , , , ,