このセクションには、ソース コード以外のものでも、作成中の製品のセキュリティにとって重要なものがすべて含まれています。この分野が対象とする問題は、ソース コードに直接関係しないため、この分野の他の部分と分けました。
{}
を security
定義に含めることでセキュリティをオプションにします。これは、グローバルに定義されたセキュリティ要件をオーバーライドし、createUsers
操作を許可および認証されていないアクセスに対して脆弱にします。
{
"openapi": "3.0.0",
"info": {
...
},
"paths": {
"/users": {
"post": {
"security": [
{},
{
"my_auth": [
"write:users"
]
}
],
"summary": "Create a user",
"operationId": "createUsers",
...
}
...
}
}
{}
を security
定義に含めることでセキュリティをオプションにします。これは、グローバルに定義されたセキュリティ要件をオーバーライドし、createUsers
操作を許可および認証されていないアクセスに対して脆弱にします。
openapi: 3.0.0
info:
...
paths:
/users:
post:
operationId: createUsers
security:
- {}
- oauth_auth:
- write:users
- read:users
responses:
'201':
...
allow_url_fopen
オプションが有効に設定されていると、ファイル名を受け入れる PHP 関数が HTTP または FTP URL を使用してリモートファイルを操作できるようになります。PHP 4.0.4 で導入されたこのオプションはデフォルトで有効に設定されており、攻撃者が悪意あるコンテンツをアプリケーションに持ち込める可能性があるという点で危険です。最も被害が小さい場合でも、リモートファイルの操作により、アプリケーションはリモートファイルを改変して悪意あるコンテンツを追加する攻撃の危険にさらされます。最も被害が大きい場合、攻撃者がアプリケーションによって操作される URL を制御できると、その攻撃者はリモートサーバーに URL を指定することで任意の悪意あるコンテンツをアプリケーションに挿入できます。 $file
の値はリクエストパラメーターで制御されているため、攻撃者はリモートファイルに URL を指定することによってプログラマの想定外の事態を引き起こすことができます。
<?php
$file = fopen ($_GET["file"], "r");
if (!$file) {
// handle errors
}
while (!feof ($file)) {
$line = fgets ($file, 1024);
// operate on file content
}
fclose($file);
?>
allow_url_include
オプションが有効に設定されていると、現在のページに追加するファイルを指定する PHP 関数 (include()
や require()
など) が、リモートファイルに HTTP または FTP URL を受け入れられるようになります。PHP 5.2.0 で導入されたこのオプションはデフォルトで無効に設定されており、攻撃者が悪意あるコンテンツをアプリケーションに持ち込める可能性があるという点で危険です。最も被害が小さい場合でも、リモートファイルを追加すると、アプリケーションはリモートファイルを改変して悪意あるコンテンツを追加する攻撃の危険にさらされます。最も被害が大きい場合、アプリケーションが追加するリモートファイルを指定するために使用する URL を攻撃者が制御できると、その攻撃者はリモートサーバーに URL を指定することで任意の悪意あるコンテンツをアプリケーションに挿入できます。cgi.force_redirect
が無効である場合、/cgi-bin/php へのアクセス権を持つ攻撃者は、PHP インタプリタの権限を使用して任意の Web ドキュメントにアクセスできます。そのため、サーバーで実行されるすべての Access Control チェックを回避できます。open_basedir
の制限を回避するため、dl
を使用した動的ローディングを使用できます。enable_dl
設定により、ライブラリの動的ローディングが可能になります。その結果、攻撃者が open_basedir で設定された制限を回避し、システム上のファイルにアクセスできてしまう可能性があります。enable_dl
を有効にすると、他の脆弱性が攻撃者によって悪用されやすくなります。file_uploads
が有効に設定されていると、PHP ユーザーは任意のファイルをサーバーにアップロードできるようになります。ユーザーによるファイルのアップロードを許可すること自体は、セキュリティ上の脆弱性を示すものではありません。ただし、この機能により、サーバー環境にデータを持ち込むための手段が悪意あるユーザーに提供されるため、さまざまな攻撃が可能となります。
<?php
$udir = 'upload/'; // Relative path under Web root
$ufile = $udir . basename($_FILES['userfile']['name']);
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $ufile)) {
echo "Valid upload received\n";
} else {
echo "Invalid upload rejected\n";
} ?>
open_basedir
設定オプション (ある場合) は、php.ini で指定されたディレクトリ ツリー外のファイルで PHP プログラムが動作しないようにします。open_basedir
オプションを使用してディレクトリが指定されていない場合、PHP で実行されているプログラムには、ローカル ファイル システム上の任意のファイルへのフル アクセスが許可されるため、本来アクセスすべきでないファイルへの読み取り、書き込み、または作成を攻撃者に許可することになります。open_basedir
を使用して制限付きのディレクトリ セットを指定しないと、他の脆弱性が攻撃者によって悪用されやすくなります。open_basedir
オプションは、セキュリティ対策としては一般的なメリットがありますが、実装すると競合状態が生まれ、攻撃者が特定の状況で制限を回避できてしまう場合があります [2]。TOCTOU (Time-of-Check、Time-of-Use) の競合状態は、PHP がアクセス許可チェックを実行してからファイルが開かれるまでの間に発生します。他の言語でのファイル システムの競合状態と同じく、この競合状態により、攻撃者は、アクセス制御チェックに合格したファイルへのシンボリック リンクを、同様のテストを受ければ不合格になる別のファイルに置き換え、保護されたファイルにアクセスできます。safe_mode
が有効に設定されていると、PHP safe_mode_exec_dir
オプションによって PHP は指定されているディレクトリからのみコマンドを実行できるように制限されます。safe_mode_exec_dir
エントリが欠如していてもセキュリティ上の脆弱性が発生する訳ではありませんが、制限が緩くなるため、攻撃者がほかの脆弱性と組み合わせてより危険な悪用方法を生み出す可能性があります。open_basedir
構成では、変更可能な作業ディレクトリを指定します。open_basedir
設定オプションが有効に設定されていると、php.ini で指定されているディレクトリツリー以外の場所にあるファイルを PHP プログラムが操作できないようにします。作業ディレクトリが .
で指定されている場合、攻撃者が chdir()
を使用して変更する可能性があります。open_basedir
オプションはセキュリティにとって全面的に好ましいものではありますが、その実装においては、状況次第で攻撃者が制限を回避できてしまう Race Condition が悩みの種となります [2]。TOCTOU (time-of-check, time-of-use) Race Condition は、PHP によってアクセス許可がチェックされるタイミングとファイルが開かれるタイミングの間で発生します。他の言語における File System の Race Condition の場合と同様で、この Race Condition により、攻撃者が Access Control チェックに合格するファイルへのシムリンクの代わりに本来であればそのチェックで不合格となる別のシムリンクを配置して、保護されているファイルにアクセスする可能性があります。register_globals
オプションが有効に設定されていると、PHP によってすべての EGPCS (環境、GET、POST、cookie、サーバー) 変数がグローバルに登録されるため、任意の PHP プログラムの任意のスコープにおいてこれらの変数にアクセスできます。このオプションを使用すると、プログラマは依存している値の出所を知らないままプログラムを記述してしまいやすくなります。その結果、悪意のない環境においては予期せぬ動作を引き起こす可能性があります。また、悪意のある環境においては攻撃者に攻撃の機会を与えてしまう可能性があります。register_globals
がもたらす可能性のあるセキュリティ上の脅威を受け、このオプションは PHP 4.2.0 ではデフォルトで無効に設定されています。また、PHP 6 では廃止予定であるか削除済みです。$username
の値はサーバーで制御されているセッションに由来していると想定しますが、攻撃者は代わりにリクエスト パラメーターとして $username
に悪意ある値を指定できます。register_globals
が有効に設定されている場合、攻撃者が送信した悪意ある値はこのコードによって生成された動的な HTML コンテンツに含められます。
<?php
if (isset($username)) {
echo "Hello <b>$username</b>";
} else {
echo "Hello <b>Guest</b><br />";
echo "Would you like to login?";
}
?>
safe_mode
オプションは、PHP の最も重要なセキュリティ機能の 1 つです。safe_mode
が無効に設定されている場合、PHP は呼び出しを実行したユーザー (通常は権限を持つユーザー) の権限でファイルを操作します。PHP で safe_mode
を無効に設定してもセキュリティ上の脆弱性は発生しませんが、制限が緩くなるため、攻撃者がほかの脆弱性と組み合わせてより危険な悪用方法を生み出す可能性があります。session.use_trans_sid
が有効に設定されていると、PHP は URL でセッション ID を渡すようになるため、攻撃者がアクティブセッションを乗っ取ったり、すでに攻撃者に制御されている既存のセッションをユーザーが使用するように仕組んだりすることが非常に容易になります。 open_basedir
設定オプションには、ファイルアクセス Race Condition に対して脆弱になる設計上の不備が含まれているため、攻撃者が File System における Access Control チェックを回避する可能性があります。open_basedir
設定オプションが設定されている場合、php.ini で指定されているディレクトリツリー以外の場所にあるファイルが PHP プログラムによって操作されないようにします。open_basedir
オプションはセキュリティにとって全面的に好ましいものではありますが、その実装においては、状況次第で攻撃者が制限を回避できてしまう Race Condition が悩みの種となります [2]。TOCTOU (time-of-check, time-of-use) Race Condition は、PHP によってアクセス許可がチェックされるタイミングとファイルが開かれるタイミングの間で発生します。他の言語における File System の Race Condition の場合と同様で、この脆弱性により、攻撃者が Access Control チェックに合格するファイルへのシムリンクの代わりに本来であればそのチェックで不合格となる別のシムリンクを配置して、保護されているファイルにアクセスする可能性があります。form-bean
エントリが複数存在します。form-bean
の名前の重複は、デバッグ コードが残っているか、誤植を示していることがよくあります。form-bean
の名前の重複には意味がありません。複数の <form-bean>
タグで同じ名前が使用されていても、最後のエントリのみが登録されるためです。form-bean
エントリが 2 つあります。
<form-beans>
<form-bean name="loginForm" type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="name" type="java.lang.String" />
<form-property name="password" type="java.lang.String" />
</form-bean>
<form-bean name="loginForm" type="org.apache.struts.validator.DynaActionForm">
<form-property name="favoriteColor" type="java.lang.String" />
</form-bean>
</form-beans>
path
属性を使用して、リクエストの処理に必要なリソースを見つけます。パスはモジュールと関連する場所であるため、"/" 文字で始まらない場合はエラーになります。例 2: 次の設定は、"/" 文字で始まらないパスを使用しています。
<global-exceptions>
<exception key="global.error.invalidLogin" path="" scope="request" type="InvalidLoginException" />
</global-exceptions>
<global-forwards>
<forward name="login" path="Login.jsp" />
</global-forwards>
input
属性を省略するのは間違いで、検証エラーが返される場合があります。input
属性が求められます [2]。input
属性は、検証エラーが発生した場合のエラー メッセージの表示に使用するページを指定します。input
属性は指定していません。
<action-mappings>
<action path="/Login"
type="com.LoginAction"
name="LoginForm"
scope="request"
validate="true" />
</action-mappings>
type
属性を含まない <exception>
タグは使用されません。<exception>
タグには、例外タイプを定義する必要があります。type
属性がない、または空の場合は、不適切な例外ハンドラーか、誤って削除したことを意味します。開発者が、例外を処理するつもりだったものの例外タイプの定義を忘れた場合、アプリケーションからシステムに関する機密情報が漏洩する可能性があります。<exception>
タグからタイプを省略しています。
<global-exceptions>
<exception
key="error.key"
handler="com.mybank.ExceptionHandler"/>
</global-exceptions>