Klassisches CGI
Ein Prozess pro Request. Einfach zu verstehen und zu isolieren, aber teuer bei vielen oder schweren Aufrufen.
Request, Prozess, Ausgabe, Fehler und die technische Spur im Log.
Ein erheblicher Teil früher Webpraxis spielte sich außerhalb der sichtbaren HTML-Seite ab: Shell-Accounts, Dateirechte, CGI-Verzeichnisse, Formularparameter, Server-Umgebungsvariablen, Prozessstarts, Antwortheader und Logdateien gehörten unmittelbar zur technischen Arbeit.
CGI war dabei eine wichtige Schnittstelle zwischen Webserver und externem Programm. Eine Anfrage konnte ein Skript starten, Eingabedaten übergeben und daraus eine dynamische Antwort erzeugen. Damit kamen zusätzliche Ebenen hinzu: Interpreter, Pfade, Benutzerrechte, Eingabeprüfung, HTTP-Ausgabe und Fehlermeldungen.
Diese Seite dokumentiert genau diese Laufzeit- und Diagnoseebene: CGI/1.1, klassische Perl-Praxis, GET und POST, Meta-Variablen, Formulardaten, Antwortheader, Access- und Error-Logs, sichere Eingabeverarbeitung, Logrotation sowie reproduzierbare Fehlersuche.
CGI – das Common Gateway Interface – beschreibt eine Schnittstelle, über die ein Webserver ein externes Programm zur Bearbeitung einer Anfrage aufrufen und dessen Ausgabe in die Serverantwort einbeziehen kann. Damit wurde serverseitige Dynamik möglich, ohne die Programmlogik fest an eine einzelne Programmiersprache zu binden.
Eine statische HTML-Datei kann unmittelbar ausgeliefert werden. Ein klassisches CGI-Programm wird dagegen für eine Anfrage ausgeführt. Der Server stellt Requestinformationen als Meta-Variablen und gegebenenfalls einen Body über Standardinput bereit; das Programm erzeugt CGI-Antwortfelder und einen optionalen Body über Standardoutput.
Diese Einfachheit machte die technischen Abhängigkeiten deutlich sichtbar: Interpreter, Pfade, Dateirechte, Umgebung, Eingabedaten und Ausgabeformat mussten zusammenpassen. Fehler ließen sich deshalb oft auf eine konkrete Schicht zurückführen.
Der Browser spricht nicht direkt mit dem Perl-Skript. Der Webserver bleibt für Verbindung, Request-Lesen, URL-Zuordnung, Zugriffskontrolle und die endgültige HTTP-Antwort zuständig.
Klassisches CGI startet für jeden Request ein neues Programm. Das schafft eine klare Zustandsgrenze: Der Prozess erhält genau seine Umgebung, verarbeitet genau diesen Request und endet wieder.
Ein Prozess pro Request. Einfach zu verstehen und zu isolieren, aber teuer bei vielen oder schweren Aufrufen.
Apache-Module für CGI-Ausführung; mod_cgid verlagert das Starten externer Programme auf geeigneten Unix-MPMs in einen Daemon.
Dauerhafte Anwendungsprozesse vermeiden wiederholten Interpreterstart, müssen aber Speicher, globalen Zustand und Request-Trennung sauber behandeln.
Kein Anwendungsprozess pro Abruf. Wo keine Eingabe- oder Zustandslogik benötigt wird, bleibt das die kleinste Angriffs- und Fehlerfläche.
„Dauerhaft“ ist nicht automatisch sicherer oder einfacher. Klassisches CGI bezahlt mit Prozesskosten; persistente Systeme bezahlen mit langlebigem Zustand, Speicherverwaltung und komplexerer Isolation.
Frühe CGI-Praxis lag unmittelbar an der Server- und Benutzerumgebung. Dateien befanden sich in realen Verzeichnisstrukturen; Benutzer- und Gruppenrechte, Skriptpfade, Shebang-Zeilen, Interpreterversionen und Umgebungsvariablen konnten über Erfolg oder Fehler entscheiden.
Ein Shell-Zugang war deshalb häufig ein wichtiges Arbeitsmittel: Dateien übertragen, Rechte prüfen, Skripte direkt ausführen, Logdateien lesen, Verzeichnisse untersuchen und unterscheiden, ob ein Problem aus Programmcode, Pfad, Dateirechten oder Serverkonfiguration entstand.
Die Laufzeitumgebung war damit keine Nebensache, sondern Bestandteil des Programmsystems. Ein Skript, das im interaktiven Benutzerkontext funktionierte, musste unter dem tatsächlichen Webserverkontext nicht zwangsläufig dieselben Pfade, Rechte oder Umgebungswerte vorfinden.
| Variable | Bedeutung und Vorsicht |
|---|---|
| GATEWAY_INTERFACE | CGI-Schnittstellenversion, typischerweise CGI/1.1. |
| REQUEST_METHOD | HTTP-Methode; nicht ungeprüft auf GET und POST beschränken, wenn der Server weitere Methoden durchreicht. |
| QUERY_STRING | Unverarbeiteter Query-Teil ohne führendes Fragezeichen; vollständig untrusted. |
| CONTENT_TYPE | Medientyp des Request-Bodys einschließlich möglicher Parameter wie Charset oder Multipart-Boundary. |
| CONTENT_LENGTH | Dezimale Anzahl der Bytes, die das Skript vom Standardinput lesen darf. |
| SCRIPT_NAME | URL-Pfadanteil, der das Skript identifiziert. |
| PATH_INFO | Zusätzlicher URL-Pfad hinter dem Skript; muss getrennt von Dateisystempfaden behandelt werden. |
| SERVER_NAME / SERVER_PORT | Serveridentität und Port nach Serverkonfiguration; bei Proxybetrieb nicht automatisch öffentliche Ursprungs-URL. |
| REMOTE_ADDR | Netzwerkadresse des direkten Gegenübers; hinter Reverse Proxy häufig Proxyadresse. |
| REMOTE_USER | Vom Server authentisierter Benutzer, sofern eine entsprechende Zugriffsauthentisierung aktiv war. |
| HTTP_* | Aus Client-Headern abgeleitete Werte wie HTTP_USER_AGENT oder HTTP_REFERER; niemals als vertrauenswürdig behandeln. |
Bei einer URL wie /cgi-bin/item.pl/gruppe/42 bezeichnet
SCRIPT_NAME typischerweise das Skript, während
PATH_INFO den zusätzlichen Pfadteil enthält.
Diese Trennung erlaubte früh sprechendere CGI-URLs.
PATH_INFO ist jedoch kein geprüfter lokaler Dateiname.
Punkte, Schrägstriche, Kodierung und Normalisierung können zwischen
URL-, Server- und Betriebssystemebene unterschiedlich behandelt werden.
open, unlink oder Shellkommandos weiterreichen.
Einer der frühesten und wichtigsten Lerneffekte bei CGI war die Tatsache, dass die Antwort formal beginnen musste. Bei einer normalen Dokumentantwort liefert das Skript mindestens Content-Type; fehlt ein eigener Status-Header, wird üblicherweise Status 200 angenommen. Nach den Headerfeldern folgt eine leere Zeile und erst danach der optionale Message-Body.
Für heutige Systeme klingt das trivial. In der frühen Praxis war es eine konstante Fehlerquelle. Ein zusätzliches Leerzeichen an falscher Stelle, eine Warnung vor dem Header, eine kaputte Zeichenausgabe, ein Modulhinweis, ein Debug-Print zu früh – und schon war die Antwort aus Sicht des Servers beschädigt. Der Browser zeigte oft nur einen generischen Fehler. Das Error-Log hingegen war meist präziser.
Gerade daran lernte man ein frühes Gefühl für Protokolldisziplin. Das Problem war selten „CGI allgemein“. Das Problem war meistens sehr konkret: falscher Header, Header zu spät, Zeichensatzfrage, ungewollte Ausgabe, fehlende Leerzeile oder ein Skriptabbruch, bevor überhaupt ein Header zurückgegeben wurde.
| Antwort | Typische Felder |
|---|---|
| Dokument | Content-Type, optional Status und weitere erlaubte Response-Header, danach Body. |
| Fehlerstatus | Status: 400 Bad Request oder anderer Status plus Content-Type und erklärender Body. |
| Client-Redirect | Location mit absoluter URI; Server erzeugt daraus die Weiterleitungsantwort. |
| Lokaler Redirect | Location mit lokalem Pfad; Server verarbeitet das neue Ziel intern nach seiner Konfiguration. |
Ein CGI-Skript sollte erwartbare Benutzerfehler nicht als unkontrollierten Prozessabbruch behandeln. Eine definierte 4xx-Antwort ist diagnostisch und betrieblich klarer als ein generischer 500er.
GET und POST unterscheiden sich zunächst durch ihre HTTP-Semantik. GET ist für das Abrufen einer Ressource definiert und gilt als sichere Methode. POST übergibt eine Darstellung an die Zielressource, damit diese sie gemäß ihrer eigenen Semantik verarbeitet.
Bei klassischen HTML-Formularen mit method="get" werden die
Formulardaten in den Query-Teil der Ziel-URL codiert. Bei
method="post" werden Formulardaten typischerweise im
Request-Body übertragen. Ein Body schafft jedoch ohne TLS keine
Vertraulichkeit und darf nicht mit einer Sicherheitsfunktion verwechselt werden.
| Methode | Praktische Eigenschaft |
|---|---|
| GET | Für abrufende Operationen. Query-Daten können in Verlauf, Lesezeichen, Referer-Kontexten, Serverlogs oder anderen Zwischenstellen sichtbar werden. |
| POST | Für Verarbeitung von übermittelten Daten. Body-Daten stehen nicht im normalen URL-Feld, können aber durch Anwendung, Proxy oder Diagnosewerkzeuge protokolliert werden. |
Entscheidend bleibt die serverseitige Verarbeitung. Prozentkodierung, Zeichensätze, Mehrfachwerte, Zeilenumbrüche und Grenzfälle müssen nach klaren Regeln behandelt werden. Methode und Transportform ersetzen keine Validierung.
| Medientyp | Verarbeitung |
|---|---|
| application/x-www-form-urlencoded | Schlüssel-Wert-Paare mit Prozentkodierung; Plus wird in Formularsemantik häufig als Leerzeichen interpretiert. |
| multipart/form-data | Mehrteiliger Body mit Boundary; notwendig für reguläre Dateiuploads und komplexere Formularteile. |
| text/plain | Für HTML-Formulare technisch möglich, aber mehrdeutig und für zuverlässige strukturierte Verarbeitung ungeeignet. |
| application/json | Keine klassische HTML-Formularcodierung, aber bei moderneren CGI-Endpunkten möglich; eigenen Parser und klare Größen-/Typgrenzen verwenden. |
Das Skript darf nicht unabhängig vom CONTENT_TYPE denselben
Parser verwenden. Besonders Multipart-Daten sollten mit einer bewährten
Bibliothek verarbeitet werden; selbstgeschriebene Boundary-Parser sind
fehleranfällig.
Ein Parametername kann mehrfach vorkommen:
tag=unix&tag=perl. Ein Parser muss deshalb festlegen,
ob er eine Liste, den ersten oder den letzten Wert liefert.
Stillschweigende Unterschiede zwischen Bibliotheken können
Sicherheitsprüfungen und Anwendungslogik auseinanderlaufen lassen.
Frühes CGI war oft praktisch gleichbedeutend mit Perl. Nicht weil Perl die einzige Möglichkeit gewesen wäre, sondern weil es auf vielen Systemen vorhanden, textstark, pragmatisch und gut genug für genau diese Übergangsschicht war. Formulare lesen, Strings zerlegen, Mail zusammensetzen, Dateien öffnen, Datum und Zeit formatieren, kleinere Zustände verwalten – all das ließ sich in Perl mit vergleichsweise wenig Aufwand umsetzen.
Gleichzeitig war Perl kein Schutzraum. Wenn das Skript schlampig war, war das Ergebnis schlampig. Wenn Variablen unklar geführt wurden, wurde die Fehleranalyse unangenehm. Wenn reguläre Ausdrücke schlecht saßen oder Eingaben blind übernommen wurden, entstanden echte Probleme. Gerade deshalb war frühe Perl-Praxis für viele lehrreich: nicht wegen Eleganz im akademischen Sinn, sondern weil sich die Folgen jeder Nachlässigkeit unmittelbar zeigten.
Stringverarbeitung, kleine Webformulare, Mail-Dispatch, Zustandsdateien, schnelle Prototypen, klare Textausgabe.
unsaubere Eingabeprüfung, Dateirechte, Shell-Aufrufe, Zeichensatzfragen, nicht abgefangene Warnungen, schwer lesbar gewordene Ein-Datei-Skripte.
Wer mit Perl-CGI arbeitete, lernte außerdem etwas Wichtiges über Webdynamik: Der eigentliche Aufwand lag selten im sichtbaren HTML. Der Aufwand lag in korrekter Übergabe, validen Zuständen und reproduzierbarer Fehlersuche. Genau deshalb waren Access- und Error-Logs kein Nebenthema, sondern permanenter Bestandteil der Arbeit.
-T zusätzliche Prüfungen für fremd beeinflusste Daten aktivieren, ist aber kein Ersatz für Validierung oder ein Berechtigungsmodell.Für viele war CGI zuerst über Formulare sichtbar. Kontaktformulare, einfache Bestellanfragen, Gästebuch-Einträge, kleine Suchmasken oder Konfigurationsübergaben – all das lief im Kern auf dieselbe Frage hinaus: Wie kommen Benutzereingaben kontrolliert auf dem Server an und was passiert dann damit? Browserseitige Pflichtfelder und JavaScript waren dabei nur Bedienhilfe; die maßgebliche Prüfung musste serverseitig erfolgen.
In der frühen Praxis war das häufig ein Mail-Skript. Der Browser schickte ein Formular, CGI nahm Felder entgegen, prüfte sie mehr oder weniger gut und setzte daraus eine E-Mail oder eine lokale Datendatei zusammen. Technisch simpel, praktisch aber voller Fallstricke: fehlende Feldprüfung, ungefilterte Sonderzeichen, kaputte Newlines, Header-Manipulation, falsche Rechte auf temporären Dateien oder ein Sendmail-Aufruf, der lokal anders funktionierte als gedacht.
Gerade daran trennte sich frühe Webromantik von tatsächlicher Webarbeit. Ein Formular war eben nicht „fertig“, nur weil es hübsch erschien. Es war erst dann brauchbar, wenn Eingaben sauber entgegengenommen, protokolliert, geprüft und nachvollziehbar verarbeitet wurden.
Gästebücher, Zähler und einfache Formularablagen schrieben häufig direkt in Dateien. Genau dort entstanden Nebenläufigkeits- und Rechteprobleme: zwei gleichzeitige Prozesse konnten denselben Stand lesen und einander anschließend überschreiben.
Ein erfolgreiches open bedeutete noch nicht, dass ein
Mehrbenutzerbetrieb korrekt war. CGI machte Nebenläufigkeit selbst bei
kleinen Seiten zu einer realen Systemfrage.
Bei klassischem CGI werden Interpreter, Module und Programmlogik für jeden Request neu gestartet. Für gelegentliche Formulare war das oft akzeptabel; bei hohem Verkehr oder großen Abhängigkeiten wurde es teuer.
| Ursache | Auswirkung und Behandlung |
|---|---|
| Interpreterstart | CPU- und Speicheraufwand je Request; kleine Skripte und wenige Module helfen. |
| Externe Programme | Weitere Prozesse, Wartezeiten und zusätzliche Fehlerpfade. |
| Langsame Clients | Request-Lesezeiten müssen auf Serverebene begrenzt werden. |
| Große Bodies | Vor dem Einlesen server- und anwendungsseitig begrenzen. |
| Dauerhafte Alternativen | FastCGI/PSGI sparen Startkosten, verlangen aber saubere Request-Trennung und Lebenszyklusverwaltung. |
Das Access-Log war die rohe Spur des Verkehrs. Dort stand nicht die philosophische Bedeutung eines Zugriffs, sondern ganz praktisch: wann etwas angefordert wurde, von welcher direkten Netzwerkadresse, mit welcher Methode, auf welches Ziel, mit welchem finalen Statuscode, in welcher Größe und – je nach Format – mit welchem Referer oder User-Agent. Hinter Proxy oder Loadbalancer ist die protokollierte Gegenstelle nicht automatisch der ursprüngliche Benutzer.
Für frühe Webarbeit war das enorm nützlich. Man sah, ob eine Seite wirklich aufgerufen wurde, ob ein CGI-Endpunkt 200 oder 500 lieferte, ob ein Formular mit GET statt POST ankam, ob ein Bot über alte Pfade lief oder ob jemand immer wieder dieselbe defekte URL abfragte. Das Access-Log war damit kein Statistikspielzeug, sondern Betriebsprotokoll.
Gerade in Kombination mit dem Error-Log wurde daraus eine brauchbare Arbeitsmethode: Im Access-Log sah man, dass etwas passiert war. Im Error-Log sah man oft, warum es scheiterte.
Apache kann das Zugriffsformat über LogFormat festlegen.
Das klassische Common Log Format enthält Gegenstelle, Identität,
Benutzer, Zeitpunkt, Requestzeile, finalen Status und übertragene Bytes.
Das Combined Log Format ergänzt Referer und User-Agent:
%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-agent}i"| Token | Bedeutung |
|---|---|
| %h | Remote Host beziehungsweise Adresse nach Serverauflösung. |
| %l | Identd-Wert; in der Praxis meist Bindestrich. |
| %u | Authentisierter Remote-Benutzer oder Bindestrich. |
| %t | Zeitpunkt des Requests im konfigurierten Logformat. |
| %r | Erste Requestzeile mit Methode, Ziel und Protokollversion. |
| %>s | Finaler Status nach internen Weiterleitungen. |
| %b | Antwortgröße ohne Header; Bindestrich bei null Bytes. |
Logfelder sind Beobachtungen, keine automatisch verifizierten Tatsachen. Referer und User-Agent stammen gewöhnlich direkt aus Client-Headern.
| Klasse | Diagnostische Einordnung |
|---|---|
| 2xx | Request wurde verarbeitet; fachlicher Inhalt kann trotzdem falsch oder unvollständig sein. |
| 3xx | Weiterleitung oder Bedingungsantwort; Ziel und Redirect-Schleifen prüfen. |
| 4xx | Request, Berechtigung oder Ressource passt nicht; 404 kann echter Altlink oder automatischer Scan sein. |
| 5xx | Server- oder Anwendungsfehler; Error-Log und CGI-STDERR unmittelbar daneben auswerten. |
Ein 200er beweist nur, dass der Server eine erfolgreiche Antwort geliefert hat. Er beweist nicht, dass eine Mail zugestellt, ein Datensatz dauerhaft geschrieben oder eine fachliche Transaktion korrekt abgeschlossen wurde.
Das Error-Log war für CGI meistens der eigentliche Arbeitsplatz. Browserfehler waren oft unpräzise. Eine leere Seite, ein 500 Internal Server Error oder einfach nur eine kaputte Antwort sagten wenig. Das Error-Log dagegen sagte häufig das Entscheidende: Syntaxfehler, fehlende Module, falscher Interpreterpfad, unzulässige Rechte, Header-Probleme, Warnungen vor dem Header, Datei nicht gefunden, uninitialisierte Variablen oder Shell-Aufrufe, die nicht durchliefen.
Wer ernsthaft mit CGI arbeitete, gewöhnte sich früh an diese Reihenfolge: Nicht zuerst den Browser anstarren, sondern das Error-Log lesen. Dort lag meistens die eigentliche Wahrheit. Und wenn dort nichts stand, war das auch eine Information – dann musste man die Logkonfiguration, die Rechte oder den tatsächlichen Ausführungspfad prüfen.
Ein CGI-Programm sollte Diagnosemeldungen auf Standardfehler und die eigentliche CGI-Antwort auf Standardoutput schreiben. Vermischen sich beide Kanäle, können Warnungen vor dem Header eine ansonsten richtige Antwort zerstören.
Access- und Anwendungslogs können IP-Adressen, Zeitpunkte, aufgerufene Pfade, Query-Strings, Referer, User-Agent, Benutzernamen und fachliche Vorgänge zusammenführen. Schon eine URL kann Suchbegriffe, interne IDs oder persönliche Angaben enthalten.
Die konkrete rechtliche Bewertung gehört in die aktuelle Datenschutz- und Betriebsdokumentation der Domain, nicht in eine historische CGI-Anleitung.
Requestziele und Header können vom Client beeinflusst sein. Rohlogs können deshalb Steuerzeichen, täuschende Zeilenumbrüche, Terminalsequenzen oder absichtlich irreführende Texte enthalten.
Ein laufender Webserver hält Logdateien geöffnet. Nur eine Datei umzubenennen oder zu löschen garantiert deshalb nicht, dass der Prozess sofort in eine neue Datei schreibt.
Apache kann Logs auch an ein Rotationsprogramm weiterleiten. Dieses Modell vermeidet manuelle Signalfolgen, erhöht aber die Abhängigkeit von einem weiteren laufenden Prozess.
Frühe CGI-Arbeit bedeutete oft Debugging ohne die Bequemlichkeiten späterer Entwicklungsumgebungen. Kein hübscher Live-Inspector, kein eingebauter Stacktrace im Browser, kein vollintegriertes Observability-System. Stattdessen: Skript lokal aus der Shell aufrufen, Testparameter manuell setzen, Header-Ausgaben kontrollieren, temporäre Debug-Ausgaben einbauen, Logdateien lesen und dann die Kette aus Request, Skript und Antwort gedanklich sauber nachverfolgen.
Gerade diese Reduktion hatte einen Vorteil: Man lernte, die Schichten zu trennen. Läuft das Skript überhaupt? Kommt der Interpreter hoch? Sind die Variablen gesetzt? Ist die Methode korrekt? Ist die Content-Length als Bytezahl plausibel und innerhalb des Limits? Kommt vor dem Header ungewollte Ausgabe? Ist ein Dateipfad relativ falsch? Ist ein Modul vorhanden? Jede Frage griff in eine andere Ebene – und genau so musste man sie behandeln.
Reproduzieren, Access-Log prüfen, Error-Log lesen, Skript direkt testen, Eingabedaten isolieren, Ausgabeformat kontrollieren, Rechte und Pfade verifizieren.
Weniger Vermutung, mehr Eingrenzung. Weniger Oberfläche, mehr tatsächlicher Laufweg. Genau dort wurde frühe Webarbeit ernst.
„Debugging hieß oft nicht, auf eine IDE zu warten. Es hieß lesen, was wirklich passiert war.“
Ein Skript kann in einer kontrollierten Shellumgebung mit denselben Kernvariablen und Eingabebytes getestet werden. Dadurch trennt man Parser- und Programmlogik vom Webserver.
Der Test muss mit derselben Interpreterversion, demselben Benutzerkontext, denselben Dateirechten und möglichst derselben Umgebung erfolgen. Ein Skript, das als eigener Shell-Benutzer funktioniert, kann unter dem Webserverkonto weiterhin an Rechten oder Pfaden scheitern.
Frühes CGI war praktisch, brachte aber auch zahlreiche unzureichend abgesicherte Lösungen hervor. Gerade Mail-Skripte, Gästebücher, Suchmasken, Dateioperationen oder Shell-nahe Hilfsskripte wurden oft schnell geschrieben und schlecht abgesichert. Das war nicht nur ein historisches Qualitätsproblem. Ein CGI-Programm kann grundsätzlich mit allen Rechten des ausführenden Serverkontos auf Systemressourcen zugreifen, die dieses Konto erreichen darf.
Typische Probleme waren ungeprüfte Eingaben, blindes Durchreichen an Shell-Aufrufe, Header-Injection in Mail-Skripten, Dateipfade mit unzureichender Kontrolle, schreibbare Verzeichnisse ohne klare Trennung oder schlicht ein zu großes Vertrauen in das, was „der Benutzer schon nicht absichtlich falsch machen wird“.
Genau deshalb blieb von dieser Zeit nicht nur Webromantik, sondern auch ein dauerhafter Reflex: lieber weniger Dynamik, wenn sie nicht wirklich gebraucht wird; lieber klare serverseitige Prüfung; lieber statische Auslieferung dort, wo keine Prozesslogik nötig ist. Die praktische Erfahrung mit CGI-Fehlern zeigte unmittelbar, dass zusätzliche Dynamik auch zusätzliche Angriffs- und Fehlerflächen erzeugt.
| Klasse | Technische Ursache und Abwehr |
|---|---|
| Command Injection | Benutzerdaten werden Teil eines Shellkommandos; Shell vermeiden, Argumente trennen, Allowlist und geringste Rechte verwenden. |
| Header Injection | CR/LF aus Formularwerten erzeugen zusätzliche Mail- oder HTTP-Header; Zeilenumbrüche ablehnen und Headerbibliotheken verwenden. |
| Path Traversal | Benutzerpfad verlässt das erlaubte Verzeichnis; IDs statt Pfade, kanonisieren und Basisgrenze prüfen. |
| Cross-Site Scripting | Fremde Daten werden ohne kontextgerechte HTML-Ausgabecodierung zurückgegeben. |
| CSRF | Authentisierte oder zustandsändernde Operation wird durch fremde Seite ausgelöst; Token und geeignete Same-Site-/Origin-Prüfung verwenden. |
| Upload-Missbrauch | Dateityp, Größe, Inhalt, Name oder Speicherort werden nicht begrenzt; außerhalb des Webroots speichern und verifizieren. |
| Resource Exhaustion | Große Bodies, langsame Requests, teure Regexe oder endlose externe Prozesse; Limits und Timeouts setzen. |
| Secret Leakage | Passwörter, Tokens, Umgebungen oder Formulardaten gelangen in HTML oder Logs; Redaction und Minimalprotokollierung. |
Ein CGI-Skript muss nicht kompromittiert sein, um einen Server zu überlasten. Eine formal gültige Eingabe kann zu groß, zu langsam oder zu rechenintensiv sein.
Limits gehören auf mehrere Ebenen: Webserver, Betriebssystem, CGI-Programm und gegebenenfalls nachgelagerter Dienst.
Ein wesentlicher Wert der frühen CGI-Praxis lag im Umgang mit Access- und Error-Logs. Sie machten Requests, Statuscodes, Pfade, Zeitpunkte und Fehlermeldungen direkt sichtbar und zwangen dazu, Symptome von nachweisbaren technischen Zuständen zu unterscheiden.
Dadurch entstand eine Arbeitsweise in Ereignisketten: Anfrage, Zuordnung, Prozessstart, Eingabe, Ausgabe, Status und Logeintrag. Statt einen Fehler als unspezifisches „Webproblem“ zu behandeln, ließ er sich einer bestimmten Schicht zuordnen.
Moderne Observability- und Entwicklungswerkzeuge können wesentlich mehr Kontext bereitstellen. Die grundlegende Haltung bleibt trotzdem gültig: Diagnose sollte sich auf überprüfbare Zustände stützen und nicht auf Vermutungen.
Ein altes Skript allein reicht nicht. Die Ausführung hing von Webserver, Interpreter, Modulen, Dateirechten, Verzeichnisstruktur, Mailtransport und Konfiguration ab.
CGI war weder in jedem Detail elegant noch für jede Lastsituation geeignet. Seine Stärke lag jedoch in der sichtbaren Kette zwischen Request, Prozessausführung und Antwort. Gerade dadurch eignete sich die Technik gut, um die beteiligten Systemschichten praktisch zu verstehen.
Webentwicklung wurde damit als Zusammenspiel von Protokoll, Prozess, Eingabe, Ausgabe, Rechten, Pfaden, Dateien, Nebenläufigkeit, Datenschutz und Fehleranalyse erfahrbar. Diese technische Transparenz erklärt einen Teil der späteren Vorliebe für statische, schlanke und nachvollziehbare Lösungen dort, wo keine serverseitige Dynamik benötigt wird.
Die Host- und Accountebene steht auf shell-accounts-und-hosts.htm. Die Entstehungszeit der frühen Webseiten wird auf erste-webseiten-1995-1996.htm dokumentiert. Der Webarbeitskontext von 1996 steht auf webdev-1996.htm; die langfristige Wartungsperspektive auf webmaster.htm.
CGI und Logdateien liegen zwischen Webentwicklung, Hostbetrieb, Sicherheit, Datenschutz und langfristiger Wartung. Die bekannten Zielseiten sind bereits mit ihren endgültigen Dateinamen verknüpft, auch wenn einzelne Seiten erst im weiteren Neuaufbau überarbeitet werden.
sslxy.de ist ein privates, nicht-kommerzielles Technik- und Webarchiv. Diese Seite dokumentiert historische Webtechnik, CGI-Praxis, Logdateien, Eingabeverarbeitung und technische Fehlersuche. Unter der Bezeichnung sslxy werden keine gewerblichen Programmier-, Hosting-, Server-, Security- oder IT-Dienstleistungen angeboten.
Genannte Techniken, Programmiersprachen, Serverbegriffe, Standards, Marken- und Produktnamen dienen ausschließlich der sachlichen technischen und historischen Einordnung. Historische CGI-Skripte und nicht mehr gepflegte Laufzeitumgebungen sollten nicht ungeprüft öffentlich betrieben werden.
Logdateien können IP-Adressen, URLs, Zeitpunkte, Benutzerkennungen und weitere sensible Angaben enthalten. Historische Beispiele und Archivmaterial werden deshalb nicht ungeprüft mit realen personenbezogenen oder geheimen Daten veröffentlicht.
Kontakt für sachliche oder technische Hinweise: mail@sslxy.de
Auch diese Unterseite ist als informative, statische HTML-Seite konzipiert. Es werden keine Tracking- oder Analysewerkzeuge und keine zustimmungspflichtigen Cookies eingesetzt. Weitere Angaben stehen in der Datenschutzerklärung.
Statische Seite. Lokale Gestaltung. Technischer Archivinhalt ohne unnötige Datensammlung.