CGI (Common Gateway Interface) について
概要
CGI(Common Gateway Interface)は、Webサーバーと外部プログラムを接続する仕組みで、ユーザーからのリクエストに応じて動的なコンテンツを生成するために使用されます。CGIプログラムは、PerlやPython、C、PHPなどの多くのプログラミング言語で書くことができ、フォーム入力などを処理し結果をWebページに反映させることが可能です。
CGIの仕組み
CGIは以下の流れで動作します:
- リクエストの受け取り:ユーザーがブラウザでリクエストを送信。
- WebサーバーからCGIプログラムへの呼び出し:WebサーバーがCGIプログラムを実行。
- CGIプログラムによる処理:リクエスト内容に基づいてデータの処理や計算を行う。
- レスポンスの返却:CGIプログラムが結果をHTML形式で生成し、Webサーバーを介してユーザーに返す。
CGIプログラムの例
Perlスクリプト例
次の例では、Perlスクリプトを使って「Hello, World!」を表示します。
#!/usr/bin/perl
print "Content-Type: text/html\n\n";
print "<html><body>";
print "<h1>Hello, World!</h1>";
print "</body></html>";
このスクリプトでは、Content-Type: text/html
で出力がHTMLであることをサーバーに伝え、ブラウザに表示します。
Pythonスクリプト例
PythonでもCGIプログラムを作成できます。次の例では、「Hello, World!」を表示します。
#!/usr/bin/python3
print("Content-Type: text/html")
print()
print("<html><body>")
print("<h1>Hello, World!</h1>")
print("</body></html>")
このスクリプトも同様に、HTML形式で出力されます。
PHPスクリプト例
PHPを使ったCGIプログラムの例です。以下のスクリプトは、ユーザーの名前を受け取って表示します。
<?php
$name = htmlspecialchars($_GET['name']);
echo "Content-Type: text/html\n\n";
echo "<html><body>";
echo "<h1>Hello, $name!</h1>";
echo "</body></html>";
?>
この例では、$_GET['name']
でURLパラメータから名前を取得し、htmlspecialchars()
関数でXSS攻撃を防ぎます。
CGIと環境変数
CGIプログラムは、以下の環境変数を使ってリクエスト情報を取得できます:
-
QUERY_STRING
:URLクエリパラメータ(例:?name=John&age=30
)。 -
REQUEST_METHOD
:リクエストのHTTPメソッド(GET、POSTなど)。 -
CONTENT_TYPE
:リクエストされたデータの形式(例:application/x-www-form-urlencoded
)。 -
REMOTE_ADDR
:リクエスト元のIPアドレス。
環境変数を使った例
次に、PythonでQUERY_STRING
を使用してリクエストパラメータを取得する例です。
#!/usr/bin/python3
import cgi
form = cgi.FieldStorage()
name = form.getvalue("name", "World")
print("Content-Type: text/html")
print()
print("<html><body>")
print(f"<h1>Hello, {name}!</h1>")
print("</body></html>")
この例では、URLに?name=Alice
と指定すると、「Hello, Alice!」と表示されます。
CGIの脆弱性とセキュリティ
CGIは、ユーザー入力に基づいて動作するため、不適切な処理を行うと脆弱性が発生しやすくなります。以下に代表的な脆弱性とその例を紹介します。
1. コマンドインジェクション
ユーザー入力を適切にフィルタリングしないと、シェルコマンドを注入される危険性があります。次の例では、悪意あるユーザーがname
パラメータにシェルコマンドを入れることでシステムが攻撃される可能性があります。
脆弱な例
#!/usr/bin/perl
my $name = $ENV{'QUERY_STRING'};
system("echo Hello, $name");
このスクリプトは、name
に; rm -rf /
のようなコマンドが含まれていると、サーバーがそのコマンドを実行してしまい、致命的な被害を引き起こす可能性があります。
2. クロスサイトスクリプティング(XSS)
CGIプログラムの出力にユーザー入力をそのまま反映すると、XSS攻撃を受ける可能性があります。ユーザーがスクリプトを仕込むと、他のユーザーのブラウザ上で悪意あるコードが実行される危険があります。
脆弱な例
#!/usr/bin/perl
use CGI;
my $query = CGI->new;
my $message = $query->param('message');
print "Content-Type: text/html\n\n";
print "<html><body>";
print "<p>$message</p>"; # 危険な出力
print "</body></html>";
このスクリプトでは、message
に<script>alert('XSS');</script>
を含めると、他のユーザーがこのページを開いた際にスクリプトが実行されてしまいます。
セキュリティ対策
- 入力値のフィルタリング:特殊文字やコマンドをエスケープ処理し、不正な入力が実行されないようにします。
- 出力のエスケープ:HTMLやJavaScriptに直接挿入する前にエスケープし、XSSを防ぎます。
- 使用する言語・ライブラリの更新:最新バージョンを使用し、脆弱性を減らします。
まとめ
CGIは、Webサーバーと外部プログラムをつなぎ、動的なコンテンツ生成を可能にする便利な技術ですが、適切なセキュリティ対策を行わないと、脆弱性を悪用される危険があります。コマンドインジェクションやXSSなどの代表的な脆弱性を防ぐためには、入力値のフィルタリングと出力のエスケープ処理が必須です。これらを意識して、安心してCGIを活用しましょう。