MySQL 8.0 リファレンスマニュアル


MySQL 8.0 リファレンスマニュアル  /  ...  /  LOAD DATA LOCAL のセキュリティー上の考慮事項

6.1.6 LOAD DATA LOCAL のセキュリティー上の考慮事項

LOAD DATA ステートメントは、データファイルをテーブルにロードします。 このステートメントは、サーバーホスト上のファイル、または LOCAL キーワードが指定されている場合はクライアントホスト上のファイルをロードできます。

LOCAL バージョンの LOAD DATA には、セキュリティ上の潜在的な問題があります:

  • LOAD DATA LOCAL は SQL ステートメントであるため、解析はサーバー側で行われ、クライアントホストからサーバーホストへのファイルの転送は MySQL サーバーによって開始され、クライアントにステートメントで指定されたファイルが通知されます。 理論上、パッチが適用されたサーバーは、ステートメントで指定されたファイルではなく、選択したサーバーのファイルを転送するようにクライアントプログラムに指示できます。 そのようなサーバーは、クライアントユーザーが読み取りアクセス権を持つクライアントホスト上のすべてのファイルにアクセスできます。 (パッチが適用されたサーバーは、実際には LOAD DATA LOCAL だけでなく任意のステートメントへのファイル転送リクエストで応答する可能性があるため、より基本的な問題は、クライアントが信頼できないサーバーに接続しないことです。)

  • クライアントが Web サーバーから接続している Web 環境では、ユーザーは LOAD DATA LOCAL を使用して、Web サーバープロセスが読取りアクセス権を持つファイルを読み取ることができます (ユーザーが SQL サーバーに対して任意のステートメントを実行できると想定しています)。 この環境では、MySQL サーバーに関するクライアントは実際には Web サーバーであり、Web サーバーに接続するユーザーによって実行されるリモートプログラムではありません。

信頼できないサーバーへの接続を回避するために、クライアントはセキュアな接続を確立し、--ssl-mode=VERIFY_IDENTITY オプションと適切な CA 証明書を使用して接続することでサーバー識別情報を確認できます。

LOAD DATA の問題を回避するには、クライアント側で適切な予防措置が講じられていないかぎり、クライアントは LOCAL を使用しないようにしてください。

ローカルデータロードを制御するために、MySQL ではこの機能を有効または無効にできます。 また、MySQL 8.0.21 の時点では、MySQL を使用すると、クライアントはローカルデータロード操作を指定されたディレクトリにあるファイルに制限できます。

ローカルデータロード機能の有効化または無効化

管理者およびアプリケーションは、ローカルデータロードを許可するかどうかを次のように構成できます:

  • サーバー側:

    • local_infile システム変数は、サーバー側の LOCAL 機能を制御します。 local_infile の設定に応じて、サーバーはローカルデータロードをリクエストするクライアントによるローカルデータロードを拒否または許可します。

    • デフォルトでは、local_infile は無効です。 サーバーが LOAD DATA LOCAL ステートメントを明示的に拒否または許可するようにするには (構築時または実行時にクライアントプログラムおよびライブラリがどのように構成されているかに関係なく)、local_infile を無効または有効にして mysqld を起動します。local_infile は実行時に設定することもできます。

  • クライアント側:

    • ENABLED_LOCAL_INFILE CMake オプションは、MySQL クライアントライブラリのコンパイル済みのデフォルトの LOCAL 機能を制御します (セクション2.9.7「MySQL ソース構成オプション」 を参照)。 したがって、明示的な配置を行わないクライアントでは、MySQL ビルド時に指定された ENABLED_LOCAL_INFILE 設定に従って、LOCAL 機能が無効または有効になります。

    • デフォルトでは、MySQL バイナリディストリビューションのクライアントライブラリは、ENABLED_LOCAL_INFILE を無効にしてコンパイルされます。 ソースから MySQL をコンパイルする場合は、明示的な配置を行わないクライアントで LOCAL 機能を無効にするか有効にするかに基づいて、ENABLED_LOCAL_INFILE を無効または有効にして構成します。

    • C API を使用するクライアントプログラムの場合、ローカルデータロード機能は、MySQL クライアントライブラリにコンパイルされるデフォルトで決定されます。 明示的に有効または無効にするには、mysql_options() C API 関数を呼び出して、MYSQL_OPT_LOCAL_INFILE オプションを無効または有効にします。 mysql_options()を参照してください。

    • mysql クライアントの場合、ローカルデータロード機能は、MySQL クライアントライブラリにコンパイルされたデフォルトで決定されます。 明示的に無効または有効にするには、--local-infile=0 または --local-infile[=1]オプションを使用します。

    • mysqlimport クライアントの場合、デフォルトではローカルデータロードは使用されません。 明示的に無効または有効にするには、--local=0 または --local[=1]オプションを使用します。

    • Perl スクリプトまたはオプションファイルから[client]グループを読み取る他のプログラムで LOAD DATA LOCAL を使用する場合は、そのグループに local-infile オプション設定を追加できます。 このオプションを認識しないプログラムの問題を回避するには、loose- 接頭辞を使用して指定します:

      [client]
      loose-local-infile=0

      または

      [client]
      loose-local-infile=1
    • いずれの場合も、クライアントによる LOCAL ロード操作を正常に使用するには、サーバーでローカルロードが許可されている必要があります。

サーバー側またはクライアント側で LOCAL 機能が無効になっている場合、LOAD DATA LOCAL ステートメントを発行しようとするクライアントは次のエラーメッセージを受け取ります:

ERROR 3950 (42000): Loading local data is disabled; this must be
enabled on both the client and server side

ローカルデータロードに許可されるファイルの制限

MySQL 8.0.21 の時点で、MySQL クライアントライブラリを使用すると、クライアントアプリケーションはローカルデータロード操作を指定されたディレクトリにあるファイルに制限できます。 特定の MySQL クライアントプログラムは、この機能を利用します。

C API を使用するクライアントプログラムは、mysql_options() C API 関数の MYSQL_OPT_LOCAL_INFILE および MYSQL_OPT_LOAD_DATA_LOCAL_DIR オプションを使用して、データロードを許可するファイルを制御できます (mysql_options() を参照)。

MYSQL_OPT_LOAD_DATA_LOCAL_DIR の効果は、LOCAL データロードが有効か無効かによって異なります:

  • LOCAL データロードが MySQL クライアントライブラリでデフォルトで有効になっているか、MYSQL_OPT_LOCAL_INFILE を明示的に有効にしても、MYSQL_OPT_LOAD_DATA_LOCAL_DIR オプションは無効です。

  • LOCAL データロードが無効になっている場合は、デフォルトで MySQL クライアントライブラリで無効になっているか、MYSQL_OPT_LOCAL_INFILE を明示的に無効にすることによって、MYSQL_OPT_LOAD_DATA_LOCAL_DIR オプションを使用して、ローカルにロードされるファイルに許可されるディレクトリを指定できます。 この場合、LOCAL データのロードは許可されますが、指定されたディレクトリにあるファイルに制限されます。 MYSQL_OPT_LOAD_DATA_LOCAL_DIR 値の解釈は次のとおりです:

    • 値が NULL ポインタ (デフォルト) の場合、ディレクトリ名は指定されず、LOCAL データのロードにファイルは許可されません。

    • 値がディレクトリパス名の場合、LOCAL データのロードは許可されますが、指定されたディレクトリにあるファイルに制限されます。 ディレクトリパス名とロードされるファイルのパス名の比較では、基礎となるファイルシステムの大/小文字の区別に関係なく、大/小文字が区別されます。

MySQL クライアントプログラムでは、前述の mysql_options() オプションを次のように使用します:

  • mysql クライアントには、ディレクトリパスまたは空の文字列を取る --load-data-local-dir オプションがあります。mysql は、オプション値を使用して MYSQL_OPT_LOAD_DATA_LOCAL_DIR オプションを設定します (値を NULL ポインタに設定する空の文字列を使用)。 --load-data-local-dir の効果は、LOCAL データロードが有効かどうかによって異なります:

    • LOCAL データロードが MySQL クライアントライブラリでデフォルトで有効になっている場合、または --local-infile[=1]を指定して有効になっている場合、--load-data-local-dir オプションは無視されます。

    • LOCAL のデータロードが無効になっている場合は、MySQL クライアントライブラリでデフォルトで無効になっているか、--local-infile=0 を指定すると、--load-data-local-dir オプションが適用されます。

    --load-data-local-dir が適用される場合、オプション値は、ローカルデータファイルを配置する必要があるディレクトリを指定します。 ディレクトリパス名とロードされるファイルのパス名の比較では、基礎となるファイルシステムの大/小文字の区別に関係なく、大/小文字が区別されます。 オプション値が空の文字列の場合、ディレクトリ名は指定されず、ローカルデータのロードにファイルは許可されません。

  • mysqlimport は、ファイルを含むディレクトリが許可されたローカルロードディレクトリになるように、処理するファイルごとに MYSQL_OPT_LOAD_DATA_LOCAL_DIR を設定します。

  • LOAD DATA ステートメントに対応するデータロード操作の場合、mysqlbinlog はバイナリログイベントからファイルを抽出し、一時的なファイルとしてローカルファイルシステムに書き込み、LOAD DATA LOCAL ステートメントを書き込んでファイルをロードします。 デフォルトでは、mysqlbinlog はこれらの一時ファイルをオペレーティングシステム固有のディレクトリに書き込みます。 --local-load オプションを使用すると、mysqlbinlog がローカル一時ファイルを準備するディレクトリを明示的に指定できます。

    他のプロセスはデフォルトのシステム固有のディレクトリにファイルを書き込むことができるため、mysqlbinlog--local-load オプションを指定してデータファイルに別のディレクトリを指定し、mysqlbinlog からの出力を処理するときに mysql--load-data-local-dir オプションを指定して同じディレクトリを指定することをお薦めします。


関連キーワード:  LOCAL, サーバー, local, DATA, ロード, ディレクトリ, LOAD, 認証, ローカルデータロード, 許可