In short: CGI (Common Gateway Interface) is an old interface in which the web server starts a new program for every request; for PHP, that program is php-cgi. FastCGI is the further development: PHP processes run permanently and accept many requests over a socket. PHP-FPM is the most important FastCGI implementation for PHP. What matters most for security are the cgi.* settings and the rule that a FastCGI endpoint must never be publicly reachable.
What is CGI?
CGI is one of the oldest methods by which web servers generate dynamic content. For the setting cgi.rfc2616_headers, the PHP manual refers to RFC 3875, the specification of the Common Gateway Interface. The beginnings of PHP were also CGI programs: in 1994 Rasmus Lerdorf wrote the first "Personal Home Page Tools" as CGI binaries in C.
The principle: for every request, the web server starts a new process, passes request data via environment variables and standard input, and reads the response from standard output. The process then ends. According to the PHP manual, with CGI and CLI PHP re-reads its php.ini on every call, with server modules only at startup.
This makes CGI robust, because every request begins with a fresh process. But it also makes CGI slow: starting the process, loading the configuration and initialising extensions cost time on every request.
What is FastCGI?
FastCGI solves the performance problem by keeping processes alive. The web server connects via a Unix socket or a TCP port to a running process and sends it the request in the FastCGI protocol. The process handles it and waits for the next one.
| Feature | CGI | FastCGI with php-cgi | FastCGI with PHP-FPM |
|---|---|---|---|
| Process per request | yes | no | no |
| SAPI name | cgi-fcgi |
cgi-fcgi |
fpm-fcgi |
| Pools with their own user | no | no | yes |
| Process control | web server | web server module, e.g. mod_fcgid | own master process |
.user.ini is read |
yes | yes | yes |
According to the manual, PHP-FPM is PHP's primary FastCGI implementation. It adds process management, pools, status pages and a slowlog to the protocol. The details are under PHP-FPM explained.
The cgi settings in php.ini
PHP has its own settings for CGI operation. The following values and descriptions come from the PHP manual:
cgi.force_redirect(default 1,INI_SYSTEM): according to the manual, necessary to run PHP as CGI securely under most web servers. Turn off only "at your own risk"; under IIS it must be off.cgi.fix_pathinfo(default 1,INI_SYSTEM): ensures correctPATH_INFOandPATH_TRANSLATEDvalues. Scripts should useSCRIPT_FILENAMEinstead ofPATH_TRANSLATED.cgi.discard_path(default 0,INI_SYSTEM): allows the CGI binary to be placed safely outside the web directory without.htaccessprotection being bypassed.fastcgi.impersonate(default 0,INI_SYSTEM): relevant only for IIS on Windows.user_ini.filenameanduser_ini.cache_ttl(default.user.iniand 300 seconds): control whether and how often PHP reads.user.inifiles.
With Nginx, a clean handover of the script path is part of this. A readable basic pattern, with no guarantee for every environment:
location ~ \.php$ {
try_files $uri =404; # pass only existing files to PHP
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
The line try_files $uri =404; prevents requests for non-existent .php paths from being passed on to PHP.
Why an open FastCGI endpoint is dangerous
The PHP manual warns explicitly: anyone who can open a FastCGI connection to PHP controls the configuration of the request, for example auto_prepend_file, and can thereby execute arbitrary code. The reason is that web servers may send PHP settings along via FastCGI parameters such as PHP_VALUE and PHP_ADMIN_VALUE.
Clear rules follow:
- Connect PHP-FPM or php-cgi in FastCGI mode only via a Unix socket if the web server runs on the same host.
- With TCP, set
listen.allowed_clientsand block the port in the firewall; notes on this are in the article Firewall for web servers. - Keep socket permissions tight with
listen.owner,listen.groupandlisten.mode.
Use ss -lntp | grep -i php to check whether a PHP process is listening on a TCP address. A binding to 0.0.0.0 or a public address is a case for urgent action.
CGI, FastCGI and PHP2Shell
Both php-cgi and PHP-FPM are affected by PHP2Shell. For both the same applies: update to 8.5.12, 8.4.27, 8.3.36 or 8.2.35, or a confirmed backport, then stop and restart all running PHP processes. In FastCGI setups with php-cgi, processes often keep running unnoticed because no dedicated service manages them. How to find and replace this legacy setup is described under php-cgi: a legacy setup with risk. In Plesk the variants are named differently; Plesk: understanding PHP handlers helps.
How does PHP SOS help?
- Record handlers: We determine whether your websites run via CGI, FastCGI with php-cgi or PHP-FPM.
- Close endpoints: We check sockets, ports and firewall rules so that no FastCGI endpoint is reachable from outside.
- Patch and clean up: We update PHP and end all old processes, including orphaned php-cgi instances.
- Replace: As part of server hardening we replace CGI legacy setups with PHP-FPM with separate pools.
Frequently asked questions
Is FastCGI the same as PHP-FPM?
No. FastCGI is a protocol through which a web server talks to an application process. PHP-FPM is a program that implements this protocol for PHP and manages the processes. php-cgi can also speak FastCGI but offers no pools.
Why is plain CGI considered outdated?
With CGI, the web server starts a new process for every request, and PHP reads its configuration each time. This costs time and resources. FastCGI and PHP-FPM keep processes permanently ready and are therefore significantly more efficient.
What is a .user.ini?
A .user.ini is a small configuration file in a web directory. According to the PHP manual, it is read only by the CGI and FastCGI SAPIs, which includes PHP-FPM. It may only contain settings with the modes INI_PERDIR, INI_USER or INI_ALL.
How do I tell whether php-cgi is running on my server?
Use read-only commands such as ps or pgrep to look for processes named php-cgi, and look in the web server configuration for entries such as mod_fcgid, Action or ScriptAlias with php-cgi. In hosting panels the operating mode is often called CGI or FastCGI application.