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
オプションを指定して同じディレクトリを指定することをお薦めします。