CGI / 1.1

Custom CGI Scripting reference for the server-side web

CustomCGI is a reference guide to custom CGI programming and server-side web scripting, covering form handlers and mailers, e-commerce scripts, authentication and session management, file uploads, CGI security hardening, and the automation of web tasks with Perl, Python, and shell scripts.

Start here Form handlers

Why CGI still matters

Millions of sites still run Perl, Python, and shell CGI scripts. We chose to document how they actually work, not just point you toward a modern framework.

14 Topic and guide hubs covering CGI from scratch to production
3 Server-side languages: Perl, Python, and shell scripts
1997 Year the domain first went live as a CGI programming resource

A reference in scenes

From the terminal to the network

Hover to explore each angle. The same CGI/1.1 protocol connects a browser request to a server script, an email delivery, a file upload, and a checkout flow.

What this is

CustomCGI is a reference guide to custom CGI programming and server-side web scripting, covering form handlers and mailers, e-commerce scripts, authentication and session management, file uploads, CGI security hardening, and the automation of web tasks with Perl, Python, and shell scripts.

Script types

Common CGI script categories

The most deployed CGI scripts solve a handful of recurring problems. Each guide explains the pattern, the code, and the security considerations.

By language

Perl, Python, and shell

CGI is language-agnostic. These guides cover each interpreter with working examples you can deploy on a standard shared host.

Why CustomCGI

Reference-first, no framework push

Most server-side web guides route you straight to modern frameworks. CustomCGI documents the protocol itself: how a web server forks a process, what environment variables it sets, how your script reads them, and how you write a valid HTTP response to stdout. That knowledge is what lets you maintain a legacy application, set up a simple form-to-email script on a shared host, or understand what the framework is doing underneath.

The domain originally ran as Internet Effects Custom CGI Programming from 1997, selling products like Killercart, MultiMail, and RealRefer. We have rebuilt it as a reference guide on the same topic. Browse the getting started guide, the Perl CGI and Python CGI references, CGI security, and the guide to modern alternatives when you are ready to migrate.

Explore in depth

A fuller guide to CGI programming

If you are getting oriented to CGI or maintaining a legacy application, the sections below go deeper on how the protocol works, the languages involved, security, and when to use a modern alternative instead.

How CGI actually works: the request lifecycle

When a browser requests a URL that maps to a CGI script, Apache (or another CGI-capable server) forks a child process and executes the script. Before execution, the server populates a set of standard environment variables: REQUEST_METHOD, QUERY_STRING, CONTENT_LENGTH, CONTENT_TYPE, HTTP_HOST, SERVER_NAME, GATEWAY_INTERFACE, and others defined in RFC 3875. The script reads these variables, reads POST data from standard input if present, and writes its response to standard output starting with HTTP headers.

The minimal required header is 'Content-type: text/html' followed by a blank line. The server reads stdout, prepends HTTP/1.x status if the script used a Status: header, and forwards the response to the browser. Every request spawns a new process, which is why CGI is slower than persistent interpreters under high load, but also why it is maximally simple and safe: the script exits when done, leaving no lingering state.

Perl CGI: the language that built the early web

Perl dominated server-side web programming from the mid-1990s through the early 2000s because it shipped on nearly every Unix system and provided mature regular expression support and the CGI.pm module, which abstracted environment parsing, form decoding, and HTML generation. A basic Perl CGI script starts with a shebang, enables strict and warnings, imports CGI.pm, prints the Content-type header, then proceeds with application logic.

The CGI.pm module has been maintained since 1995 and is still the standard choice for Perl CGI. Modern Perl best practice supplements it with Scalar::Util for safe type checks, HTML::Escape or similar for output encoding, and Email::Stuffer or MIME::Lite for mail dispatch. Avoid the ancient sendmail pipe approach without careful input sanitization: it is the classic source of header-injection vulnerabilities in old form mailers.

Python CGI: cleaner syntax, same protocol

Python's standard library includes a cgi module that provides FieldStorage, the primary class for parsing both GET query strings and POST bodies, including multipart file uploads. A Python CGI script uses the same Content-type + blank line convention as Perl, but the syntax is cleaner and the language is easier to read for most modern developers. The shebang line should point to the server's Python 3 interpreter, typically /usr/bin/python3.

For new CGI scripts in Python, WSGI (via mod_wsgi or uWSGI) is the more efficient alternative because it reuses a persistent interpreter process rather than forking per request. But for simple scripts on shared hosts where WSGI is not available, Python CGI works reliably and is the correct choice. Always use cgitb.enable() during development for formatted tracebacks, and remove it in production.

CGI security: the most common vulnerabilities and how to prevent them

CGI scripts that accept user input are a classic source of security vulnerabilities when written carelessly. The three most damaging categories are: shell injection (passing user input to system(), exec(), or the sendmail pipe without sanitization), path traversal (using client-supplied filenames or paths to read or write arbitrary server files), and header injection (allowing newlines in values printed into HTTP headers or email headers).

Every input must be validated against a strict allowlist of expected characters before use. In Perl, match against /^[a-zA-Z0-9 .@-]+$/ rather than stripping bad characters after the fact. File uploads must be written to a non-web-accessible directory with a server-generated filename, never the client-supplied one. HTTP headers must be printed before any user data, and user data printed into the response body must be HTML-encoded. The cgi-security guide covers each category in depth with working code examples.

What this guide covers and what we deliberately do not publish

CustomCGI is a reference guide to CGI programming and server-side web scripting, built around the confirmed historic niche of the domain: Internet Effects Inc, which operated from the late 1990s through the mid-2000s selling CGI products including Killercart (shopping cart), MultiMail (form mailer), RealRefer (referrer tracking), TrueVirtual (virtual hosting), and Vlinto (tour application).

We cover: CGI form handlers, file upload scripts, shopping cart scripts, authentication and session management, redirect scripts, CGI security, Perl CGI, Python CGI, shell scripting, getting started on shared hosting and VPS, debugging, and a comparison with modern alternatives. We do not publish prices, guarantees, or claims about specific hosting providers. AFFILIATE_SLOT_HOSTING and LEAD_SLOT_CUSTOM_DEV markers in our content identify monetization placeholders that will be wired on deployment. All technical content is general educational information.

Get help

Request custom CGI development

Need a CGI script built or an existing one debugged? Use the form below to describe your project. There is no obligation.

Custom development inquiry

No spam. Your inquiry is answered within 1 business day.

Hosting setup help

No spam. Your inquiry is answered within 1 business day.

Start here

Common CGI programming questions

What is CGI programming?
CGI (Common Gateway Interface) is a standard protocol that lets a web server execute a program and pass the output back to the browser as an HTTP response. The server invokes a script, typically written in Perl, Python, or shell, sets a defined set of environment variables describing the request, and reads the program's standard output as the response body. CGI was the dominant form of dynamic web content from the mid-1990s through the early 2000s, and millions of sites still run CGI scripts today on shared Linux hosts.
Is CGI still used in 2024?
Yes. Shared hosting environments on Apache and LiteSpeed typically have a /cgi-bin directory enabled by default, and many legacy applications written in Perl or shell have never been rewritten. CGI is also the simplest way to add server-side logic to a static site on a traditional host without installing a framework. Modern alternatives like WSGI (Python) and FastCGI reduce per-request overhead, but CGI remains widely deployed and well supported.
Which languages can you use to write CGI scripts?
Any language that can read environment variables and write to standard output works as a CGI script: Perl, Python, Ruby, Shell (Bash), C, PHP in CGI mode, and others. Perl dominated the early web era because of its mature text-processing libraries and the CGI.pm module. Python is now equally common and cleaner to read. Shell scripts work for simple form-to-email tasks. The interpreter must be installed on the server and the script must be marked executable.
How do I send form data to a CGI script?
An HTML form with method='POST' and action pointing to your CGI script URL will POST the form body to the script. The server sets CONTENT_LENGTH and makes the data available on standard input. A Perl script using CGI.pm or a Python script using the cgi module can parse the fields with a single call. GET requests pass data in the QUERY_STRING environment variable instead. Always validate and sanitize every field server-side before using it.
What is the correct shebang line for a CGI Perl script?
The shebang line must point to the exact Perl interpreter on the server: #!/usr/bin/perl is correct on most Linux hosts, while some systems use #!/usr/local/bin/perl. Always add 'use strict;' and 'use warnings;' on the next two lines. To help diagnose configuration errors, add 'use CGI::Carp qw(fatalsToBrowser);' during development so error messages appear in the browser rather than the server error log.
Why am I getting a 500 Internal Server Error from my CGI script?
The most common causes are: the script is not marked executable (chmod +x script.cgi), the shebang path is wrong for the server, there is a syntax error in the script, the Content-type header is missing or malformed, or the script is printing output before the header. Check the server's error_log for the exact message. CGI::Carp fatalsToBrowser is useful during development, but remove it in production since it can expose internal paths.
How do I make a CGI file upload script?
In Perl, CGI.pm handles multipart/form-data uploads through its upload() method. In Python, the cgi module's FieldStorage class gives you a file-like object for the uploaded content. The key requirements are: the form must use enctype='multipart/form-data' and method='POST', the script must validate file type and size before processing, and the file must be written to a directory that is not web-accessible. Never trust the filename supplied by the client.
What is a CGI form handler?
A CGI form handler is a server-side script that receives HTML form submissions, validates the input, processes it (typically sending an email or writing to a file), and returns an appropriate HTML response. Classic examples include contact forms, feedback forms, and newsletter signups. The handler reads POST data, validates each field against expected patterns, uses a mail library or sendmail to dispatch the message, then prints a thank-you page or redirects with a Location header.

CustomCGI publishes reference information on CGI programming and server-side web scripting for educational and informational purposes. Code examples are provided as-is for learning; always audit and test scripts in a staging environment before deploying to production. Security vulnerabilities in CGI scripts are a real risk; follow current best practices and review the security guide before deploying any user-facing code.