Robert Bienert: C++ als CGI - Anfänge und Sicherheitsaspekte

Beitrag lesen

Moin!

da ich für ein zukünftiges Projekt eine ziemlich performante Webapplikation benötige, möchte ich diese nicht mit PHP und MySQL aufbauen, sondern mit kompilierten C++-Programmen.

Das klingt doch interessant. Ich bin in dieser Hinsicht kein Experte, habe aber schon ein paar Gehversuche hinter mir. Und bei C++ kann ich dir wohl auch weiterhelfen.

Da ich mir sicher bin, dass es vielleicht noch andere da draußen geben könnte, die das interessiert, gehe ich jetzt mal ganz detailliert darauf ein.

Das zeigen ja auch schon die Antworten.

Um mich mal in die Welt der CGI-Programmierung einzuarbeiten, habe ich auf meinem Server ein Verzeichnis "cgi-test" erstellt und darin folgende .htaccess-Datei abgelegt:

AddHandler cgi-script .cgi
DirectoryIndex index.cgi
Options +ExecCGI

Das scheint ja zu funktionieren, oder stellst du irgendwelche Meldungen in deiner error_log fest?

Nun habe ich folgenden Quellcode in die Datei index.cpp geschrieben:

Wir besprechen das mal hier:

#include <iostream>

#include <cstdlib>

  
BTW: Diesen ^^^ Include brauchst du doch nur, wenn du die Ausgabe der Umgebungsvariablen einkommentierst.  
  

> ~~~c++

using namespace std;  

>   
> int main() {  
>   // Header-Informationen  
>   cout << "Content-Type: text/html; charset=utf-8\r\n";  
>   cout << "\r\n";  
>   
>   // HTML-Teil  
>   cout << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";  
>   cout << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n";

Es ist performanter, die komplette Ausgabe in einem Rutsch zu erledigen, als dafür sehr oft cout << aufzurufen. C und C++ bieten dir an, so genannte Zeichenkonstanten bis zu einer Länge von 500+etwas über mehrere Zeilen zu notieren:

  
cout << "Content-Type: text/html; charset=utf-8\r\n"  
        "\r\n"  
        // HTML-Teil  
        "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"  
        "…";  

Außerdem frage ich mich, weshalb du XHTML 1.0 Strict als text/html mit der XML-Deklaration auslieferst.

// snip

cout << " </body>\n";
  cout << "</html>\n";

  
Fehlt hier nicht etwas, z.B. `return 0;`{:.language-c++}?  
  

> `}`{:.language-c++}  
>   
> Danach habe ich die Datei [index.cgi](http://marcreichelt.de/cgi-test/index.cgi) mit folgendem Befehl erstellt:  
> g++ -O2 -Wall index.cpp -o index.cgi  
  
Du möchtest zur Vermeidung gröbster Fehler mindestens noch -Wall anschalten. Viele weitere sinnvolle Warning-Flags findest du in der GCC-Manual.  
  

> Nun habe ich ein paar Fragen an euch:  
>   
> - Was sollte man generell bei Benutzung von C++-Applikationen als CGI beachten?  
  
Mit C++ machst du im Vergleich zur Verwendung „sicherer Programmiersprachen“ einen im Vergleich zu C kleinen Topf mit Würmern auf, da ein String erst einmal ein Zeichenarray ist, welches mit einem NULL-Byte abgeschlossen wird. Du musst also z.B. prüfen (lassen), ob dies der Fall ist; Abhilfe kann hier die Verwendung von std::string sein. Auch sind Pointer nicht immer einfach zu benutzen, aber dafür gibt es in C++ Referenzen.  
  
Im Vergleich zu solch integrierten Lösungen wie ASP, PHP, PerlEmbed, … gibt es bei der Verwendung von C++ keine so hübsche Lösung, den Programmcode in das HTML einzubetten, weshalb dir im Editor der HTML-Code immer nur als Zeichenkette angegeben wird. Du wirst also in deinem Browser die Quelltextansicht häufiger benutzen. In wie fern es CGI-Bibliotheken für C++ gibt weiß ich nicht, aber so etwas erleichert die Arbeit ungemein.  
  

> - Wie sieht das mit den Benutzerrechten aus? Kann das Programm unter anderen Benutzernamen und anderen Gruppen gestartet werden?  
  
Sofern das Programm das x-Bit gesetzt für die entsprechende Gruppe oder den entsprechenden Benutzer gesetzt hat, lässt es sich ausführen.  
  

> - Und wie ist das mit der Sicherheit? Ist schon allein durch die Freigabe des kommentierten Quellcodes in meinem Beispiel (zwischen /\* und \*/) ein Sicherheitsloch geöffnet?  
  
Sicherheit ist im Zusammenspiel mit C und C++ ein potenziell heikles Thema. Programme wie der [flawfinder](http://www.dwheeler.com/flawfinder) können dir bei der Suche nach unsicheren Funktionsaufrufen behilflich sein, aber viele Fehler sind sehr gut versteckt. Auch ist es ratsam, den GCC mit etlichen Warning-Flags mehr aufzurufen, womit du einige weitere subtile Dinge entdecken kannst.  
  
Was die Freigabe des Quellcodes anbetrifft: Sollte in deinem Programm ein veritabler Bock sein, dürfte das Fehlen von Kommentaren dieses kaum verschleiern. Obwohl das Veröffentlichen des Quellcodes an sich die Gefahr birgt, dass jemand eine Lücke findet, die er ausnutzen kann, dienen solche so genannten Code-Audits dazu, die Öffentlichkeit zu ermuntern, Fehler zu finden, die man selbst nie entdeckt hätte. Wie Opensource an sich halte ich Audits für sehr sinnvoll und fruchtbar.  
  

> - Gibt es gute Literaturquellen, die ihr mir bezüglich C++ als CGI empfehlen könnt?  
  
Prinzipieller Natur dürfte, falls dich C++ interessiert, das C++-Buch von Bjarne Stroustrup, dem Erfinder von C++, sein. Ansonsten gibt es im Internet haufenweise gute Dokus zum Thema sicheres Programmieren mit C und/oder CGI, wobei ich hier grad mal ein paar Links auf Lager hab, aber eine gute Suchmaschine und SELF-Kompetenz („die Community“) sollten dir weiter helfen:  
  
 \* [Secure Programming for Unix and Linux HOWTO](http://www.dwheeler.com/secure-programs)  
 \* [Die Datenschleuder – Wer hat Angst vorm bösen Wolf?](http://ds.ccc.de/081/insertion-attacks)  
 \* [The World Wide Web Security FAQ](http://www.w3.org/Security/Faq/www-security-faq.html)  
 \* und ein bisschen Eigenwerbung: [„Sicherheit” mit PHP/CGI, MySQL](http://robertbienert.de/dokumente/web/PHPMySQLSicherheit.html) (wird von mir grad überarbeitet)  
  
Viele Grüße,  
Robert