Marc Reichelt: C++ als CGI - Anfänge und Sicherheitsaspekte

Beitrag lesen

Hallo Robert,

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?

Nein, keine Meldungen diesbezüglich. Aber es war gut, mal wieder in die error_log zu schauen - da habe ich soeben festgestellt, dass PHP bei der Initialisierung dauernd einen Fehler ausgibt, da ein Fehler in der php.ini ist (ich hatte für Kommentare das Zeichen "#" verwendet, und nicht das Zeichen ";").
Nun ist das schon mal behoben. :)

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.  
  
Jepp, hatte es dort noch vergessen gehabt. Ist jetzt ebenfalls in einem Kommentar (siehe Link auf aktuellen Quelltext).  
  

> > [...code-gewurschtel vom marc...]  
> Es ist performanter, die komplette Ausgabe in einem Rutsch zu erledigen, als dafür sehr oft `cout <<`{:.language-c++} aufzurufen. C und C++ bieten dir an, so genannte Zeichenkonstanten bis zu einer Länge von 500+etwas über mehrere Zeilen zu notieren:  
>   
> ~~~c++
  

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

Supi! Das ist doch schon mal eine ordentliche Steigerung.

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++}?  
  
Doch, das fehlte. Habe ich inzwischen bereits geändert gehabt. ;)  
  

> > 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.  
  
Hehe, schau dir meinen Befehl nochmal gut an... \*g\*  
  

> > - 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.  
  
Das ist ein guter Ansatz. Ich habe mir auch bereits gedacht, dass es vielleicht sinnvoll sein könnte, das String-Objekt aus Java direkt nachzubauen, um eine solche Klasse dann in C++ verwenden zu können.  
  
Performanter wird es allerdings bestimmt sein, wenn ich mit std::string arbeite.  
Das mit den Referenzen habe ich mir bereits in meinem derzeitigen Buch angeschaut, das ist wirklich eine schöne Sache (und bin ich ja auch von PHP so bzw. ähnlich gewohnt).  
  

> 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.  
  
Das wäre doch mal schön, wenn es solche Bibliotheken gibt.  
Mit dem "In den Quelltext schreiben" habe ich mittlerweile keine Probleme mehr, das geht nach ein paar Jahren HTML ziemlich flüssig.  
  
Vielleicht lohnt es sich ja, mal einen schönen Feature-Artikel darüber zu schreiben, der alles genau erklärt. Aber so wie es aussieht, nehmen die meisten hier PHP, Python, Java Servlets oder Perl. Was ja auch ziemlich sinnvoll ist.  
  
Eventuell könnte ich die Server-Anwendungen ja auch weiterhin mit PHP schreiben, wenn ich einen guten Compiler da habe, der mir PHP-Skripte in lauffähigen Maschinencode übersetzt.  
Gibt es da ein paar gute Programme?  
  
Bei Python scheint es da wesentlich bessere Lösungen zu geben, jedenfalls gibt es dafür so einige Compiler - es gibt selbst Python Bytecode, was dem Prinzip von Java doch sehr ähnelt.  
  
Hmm, vielleicht sollte ich mich doch in Python einarbeiten.  
  
Auf jeden Fall sollte es eine Sprache sein, mit der ich sowohl die Web-Applikation als auch den Server an sich schreiben kann. Das würde mit PHP zum Beispiel eher ein böses Unterfangen werden, wohingegen mit Python das alles zu schaffen wäre.  
  

> > - 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.  
  
Das mit den Warning-Flags sollte selbstverständlich sein, aber der flawfinder scheint ebenfalls ein echter Tipp zu sein.  
  

> 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.  
  
Das Projekt, dass ich vorhabe, ist noch nicht als OpenSource geplant. Ich bin mir sicher, dass ich den Quelltext (bei Erfolg) irgendwann freigeben werde. Bis dahin birgt es aber die Gefahr, dass sich jemand anderes den Quelltext schnappt, und einfach ein eigenes Projekt auf die Beine setzt. Dazu braucht er nur ein wenig Startkapital und eine gute Marketing-Abteilung - den Quelltext hat er dann nämlich schon.  
  

> > - 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)  
  
Sehr schön. Ich liebe dieses Forum, da gibt's so viele Leute, die sich einfach gut mit den Sachen auskennen, die ich erst lernen möchte... :D  
  
  
Grüße  
  
Marc Reichelt || <http://www.marcreichelt.de/>  

-- 
Linux is like a wigwam - no windows, no gates and an Apache inside!  
  
Selfcode: ie:{ fl:| br:> va:} ls:< fo:} rl:( n4:( ss:) de:> js:| ch:? sh:| mo:) zu:)  
<http://emmanuel.dammerer.at/selfcode.html>