CGIスクリプト言語とは?仕組み・主要環境変数・性能・セキュリティ対策をわかりやすく解説

CGIスクリプト言語とは — 概要

CGI(Common Gateway Interface)は、Webサーバーと外部プログラム(スクリプトやバイナリ)を連携させ、動的なWebコンテンツを生成するための「インターフェース仕様」です。したがって「CGIスクリプト言語」と言う場合は厳密には一つの言語を指すのではなく、CGIの仕様に従って書かれたスクリプトを実行するために用いられる言語全般(Perl、Python、Ruby、C、シェルスクリプト、PHPなど)を指すことが多いです。

CGIの基本動作原理

CGIの基本は単純です。WebサーバーがHTTPリクエストを受け取ると、事前に設定されたCGIディレクトリ(例:/cgi-bin/)や拡張子に応じて外部プログラムを起動し、そのプログラムに対して環境変数と標準入力(stdin)を通じてリクエスト情報を渡します。プログラムは標準出力(stdout)にHTTPヘッダと生成するコンテンツを書き込み、サーバーはそれをクライアントに返します。

  • 入力:QUERY_STRING(GETパラメータ)、標準入力(POSTデータ)、環境変数(REQUEST_METHOD、CONTENT_LENGTH、CONTENT_TYPE、SERVER_NAME、SCRIPT_NAME、PATH_INFO、HTTP_* など)
  • 出力:HTTPレスポンスヘッダ+本文を標準出力へ書き出す(例:Content-Type: text/html <html>...)
  • エラーハンドリング:標準エラー出力はサーバーによってログにリダイレクトされることが多い

代表的な環境変数(よく使うもの)

  • REQUEST_METHOD:GET/POSTなどのHTTPメソッド
  • QUERY_STRING:URLの?以降(GETパラメータ)
  • CONTENT_LENGTH:POSTデータの長さ(バイナリ含む)
  • CONTENT_TYPE:POSTデータのMIMEタイプ(例:application/x-www-form-urlencoded、multipart/form-data)
  • SCRIPT_NAME、PATH_INFO:呼び出されたスクリプト名やパス情報
  • HTTP_USER_AGENT、HTTP_REFERER など:クライアントの送信したヘッダはHTTP_接頭辞で参照可能

CGIの具体例(簡単なスクリプト)

以下はCGIの動作イメージを示す簡単な例です。WordPress等に貼る際は<pre><code>で囲むと見やすくなります。

# Perl の例(先頭行にシェバン)
#!/usr/bin/perl
use strict;
use warnings;
print "Content-Type: text/html; charset=utf-8\n\n";
print "<html><body><h1>Hello CGI</h1></body></html>";
# Python の例(簡易)
#!/usr/bin/env python3
import os,sys
print("Content-Type: text/html; charset=utf-8")
print()
print("<html><body><h1>Hello CGI</h1></body></html>")

CGIは言語ではない — 重要なポイント

繰り返しになりますが、CGIは「外部プログラムとWebサーバーのやり取りの約束事(プロトコル)」であり、どの言語でもこの約束を満たせばCGIプログラムになります。Perlが歴史的に多用されたため「CGI=Perl」と誤解されがちですが、実際には多くの言語でCGIは実装可能です。

性能面・運用上の特徴と課題

  • プロセス生成コスト:多くの実装ではリクエストごとに新しいプロセスが生成される(fork/exec)。これが高負荷下でのボトルネックになる。
  • スケーラビリティ:短時間に多数のリクエストが来るとプロセス生成・終了でCPUやメモリを圧迫する。
  • 状態管理:CGI自体はステートレス。セッション等は外部に(DBやファイル、キャッシュ)管理する必要がある。
  • 並列処理:マルチスレッドで動くサーバと比べ、プロセス単位の扱いはメモリ効率が悪くなる場合がある。

これらの課題を解決するために、FastCGI やアプリケーションサーバー、言語固有のインターフェース(WSGI、PSGI、Rackなど)が普及しています。

代表的な代替技術・派生

  • FastCGI:プロセスを常駐させてソケット経由でサーバーと通信することでプロセス生成コストを削減する。
  • WSGI(Python):WebサーバーとPythonアプリケーションのための標準インターフェース(PEP 3333)。
  • PSGI/Plack(Perl)、Rack(Ruby):同様に言語固有のアダプタ層を提供。
  • mod_php / PHP-FPM:PHPはモジュールとして組み込むか、FastCGI(PHP-FPM)で高速化するのが一般的。
  • サーバー側フレームワーク(例:Django、Rails、Express、など):アプリケーションサーバーを前提にした設計で、直接CGIを使うことは少ない。
  • サーバーレス(FaaS):関数単位での実行管理をクラウドが行い、CGI的な直接管理から解放される選択肢。

セキュリティの注意点

  • 入力の検証:GET/POST、HTTPヘッダはすべて信用しない。SQLインジェクション、コマンドインジェクション、パス操作などに注意。
  • ヘッダインジェクション:出力するヘッダに改行を不適切に含めるとレスポンス分割攻撃が起きる。
  • ファイルの権限:CGIスクリプトが実行できる権限や配置ディレクトリのパーミッション管理。
  • 環境変数の露出:サーバー環境やシークレットが環境変数として露出しないように注意。
  • アップロードの扱い:multipart/form-data の処理で一時ファイルやサイズチェックを適切に行う。

運用・設定上の実務ポイント

  • シェバン(#!)行の正確さ:実行パスが環境に合っているかを確認する(例:/usr/bin/perl や /usr/bin/env python3)。
  • 実行権限:スクリプトに実行フラグ(chmod +x)を付与する。
  • サーバー設定:Apacheのmod_cgiやmod_cgid、Nginxでは直接CGIを持たないためFastCGI等を経由する構成が一般的。
  • ログ管理:標準エラーやサーバーログの出力を適切に設定し、監視する。

現代の位置づけ

CGIはWeb初期からの重要な仕組みであり、動的コンテンツの基礎を形作ってきました。しかし、パフォーマンスやスケーラビリティの観点から、現代の大規模なWebアプリケーションでは直接CGIを用いることは少なく、FastCGI、言語特化のインターフェース、アプリケーションサーバー、サーバーレスなどに置き換えられることが多いです。とはいえ、単純なユーティリティや軽量なスクリプト、小規模な管理画面などの用途では、いまでもCGIは有効かつ使いやすい選択肢です。

まとめ

CGIスクリプト言語という呼び方は便宜上のものであり、正確には「CGIインターフェースに従って書かれたスクリプト」を指します。CGIの仕組みを理解することで、HTTPの仕組み、入力・出力の扱い、環境変数の意味、そして性能・セキュリティ面での課題とその対策がわかります。モダンなWebアーキテクチャではより効率的な代替が使われることが多いですが、基礎知識としてCGIの理解は今なお有用です。

参考文献