Documentation Home
MySQL 5.6 リファレンスマニュアル
Download this Manual
EPUB - 7.5Mb
HTML Download (TGZ) - 7.2Mb
HTML Download (Zip) - 7.2Mb


MySQL 5.6 リファレンスマニュアル  /  ...  /  LOAD DATA LOCAL のセキュリティーの問題

6.1.6 LOAD DATA LOCAL のセキュリティーの問題

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

LOAD DATA ステートメントの LOCAL バージョンのサポートに関しては、セキュリティーについての潜在的な問題が 2 つあります。

  • クライアントホストからサーバーホストへのファイルの送信は、MySQL サーバーによって開始されます。理論的には、パッチ適用済みサーバーを構築して、LOAD DATA ステートメントでクライアントによって指定されたファイルでなく、サーバーが選択するファイルを転送するようサーバーがクライアントプログラムに指示するようにすることができます。そのようなサーバーは、クライアントユーザーが読み取りアクセス権を持つクライアントホスト上のすべてのファイルにアクセスできます。

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

これらの問題に対処するために、MySQL 3.23.49 と MySQL 4.0.2 (Windows では 4.0.13) 以降で LOAD DATA LOCAL の処理方法が変更されました。

  • デフォルトでは、バイナリ配布内のすべての MySQL クライアントおよびライブラリは -DENABLED_LOCAL_INFILE=1 オプションでコンパイルされ、MySQL 3.23.48 以前との互換性が保持されています。

  • MySQL をソースからビルドしたが、-DENABLED_LOCAL_INFILE=1 オプションを指定して CMake を呼び出さない場合、LOAD DATA LOCALmysql_options(... MYSQL_OPT_LOCAL_INFILE, 0) を呼び出すように明示的に記述される場合を除いて、いずれのクライアントからも使用できません。セクション23.8.7.49「mysql_options()」を参照してください。

  • --local-infile=0 オプションを指定して mysqld を起動することによって、サーバー側からのすべての LOAD DATA LOCAL ステートメントを無効にすることができます。

  • mysql コマンド行クライアントの場合、--local-infile[=1] オプションを指定することによって LOAD DATA LOCAL を有効にするか、--local-infile=0 オプションを指定することによってこれを無効にします。mysqlimport の場合、ローカルデータファイルのロードはデフォルトでオフになっており、--local または -L オプションを使用してこれを有効にします。いずれの場合でも、ローカルロード操作を正常に使用するには、サーバーがこの操作を許可していることが必要。

  • オプションファイルから [client] グループを読み取る Perl スクリプトまたはその他のプログラムで LOAD DATA LOCAL を使用する場合、local-infile=1 オプションをそのグループに追加できます。ただし、local-infile を認識しないプログラムで問題が発生しないようにするために、loose- プリフィクスを使用してこれを指定します。

    [client]
    loose-local-infile=1
    
  • サーバーまたはクライアントのいずれかで LOAD DATA LOCAL が無効な場合、そのようなステートメントを発行しようとしたクライアントは次のエラーメッセージを受け取ります。

    ERROR 1148: The used command is not allowed with this MySQL version
    

User Comments
  Posted by on August 21, 2003
This topic often leads to problems in combination with PHP. If you followed one of the many documents which tell you to compile PHP with "--with-mysql", you didn't link against the MySQL libraries, but you're using the internal MySQL client of PHP, which seems to cause trouble, even if the MySQL server is correctly built with "--enable-local-infile".

Recompiling PHP with "--with-mysql=/usr" solved the problem instantly, because it links against the original MySQL libraries with local file handling enabled. No further configuration needed.
  Posted by on October 14, 2003
For use in perl DBI scripts, adding an option at the end of the data source definition for DBI->connect fixes the LOAD DATA LOCAL problem in some situations...

use strict;
use DBI;
my $dsn = "DBI:mysql:mydb;mysql_local_infile=1"; <----
my $user = "me";
my $password = "secret";
my $dbh = DBI->connect($dsn,$user,$password);

Jeff

  Posted by Jimmy Zhang on February 17, 2004
if you are using latest version of phpMyAdmin and have problem uploading CSV, you can go to edit ldi_table.php

you can find "DATA LOCAL" and reach here:
...($local_option_selected ? ' checked="checked" ' : ''); ?>/><label for="radio_local_option_0">...DATA</label><br />
...(!$local_option_selected ? ' checked="checked" ' : ''); ?>/><label for="radio_local_option_1">...DATA LOCAL</label>

you can change them into
...(!$local_option_selected ? ' checked="checked" ' : ''); ?>/><label for="radio_local_option_0">...DATA</label><br />
...($local_option_selected ? ' checked="checked" ' : ''); ?>/><label for="radio_local_option_1">...DATA LOCAL</label>

to make ...DATA default instead of ...DATA LOCAL
in this way, you will be able to upload your CSV files smoothly
  Posted by Rob McMillin on March 13, 2004
I have to agree with the poster upthread. The documentation for this misfeature (which SHOULD BE REMOVED!) is awful. If you're so dense as to be concerned about somebody taking over your server, you have physical security issues and THAT is what needs to be resolved.
  Posted by Douglas Marsh on April 5, 2004
I think the problem is "LOCAL" is sometimes confusing... I'd suggest that the Syntax change to (instead of using or NOT using the word "LOCAL")...

LOAD DATA [SERVER/CLIENT] INFILE 'filename.txt' [... INTO ...];

  Posted by Cory Sytsma on July 15, 2004
If using phpMyAdmin from the same computer as your MySQL instance, you can easily get around this problem by changing the LOAD radio box to ...DATA, when using 'Insert data from a textfile into table' feature off the SQL tab. Modifying ldi_table.php, as mentioned above, will just change the default value selected here.

I don't have a lot of experience with this, but since I'm running phpMyAdmin from the same computer as my MySQL database, I'm assuming that's why this works.
  Posted by Emory Smith on September 26, 2004
for those using php and unable to LOAD DATA INFILE on a remote host (with only ftp access):

first try using phpMyAdmin - you will probably need to customize some variables in the .../phpMyAdmin/config.inc.php file (search repeatedly for "upload" in http://www.phpmyadmin.net/documentation/ to see which ones). i found this to work ok for small files (ie - table exports with no binary data).

attempting to load large files (for instance exporting binary data from a local database to remote one) in this manner proved hopeless in my case due to host provider's upload restrictions, timeouts and other issues mentioned above.

for those in the same boat, here's an alternate solution that i found to be both faster and more reliable than using phpMyAdmin:

1. format your INFILE so that you have one sql statement per line*
2. upload the INFILE to remote server (however you like) and make sure both the file and parent directory are readable by php
3. write a php script that opens a file and repeatedly
- - - a. reads a single line into a string**
- - - b. calls mysql_query($string);
4. upload your script (preferably to passwd protected dir) and invoke it with the path to your INFILE.

* beware -- if you are using OS X along with pre-4.3 version of php, you must convert all end-of-line characters in the INFILE from mac-style to unix style. you can do this with the "tr" command:

% tr '\015' '\012' < mac.txt > unix.txt

for php4.3 and later, line endings are no problem, just call

set_ini('auto-detect-line-endings',1);

as described at http://www.php.net/manual/en/ref.filesystem.php#ini.auto-detect-line-endings

** if youre not sure how you want to do this, try "fgets()" ... see the code example at http://www.php.net/manual/en/function.fgets.php
  Posted by David Weingart on December 23, 2004
You can use LOAD DATA LOCAL with recent versions of PHP without recompiling PHP.

Passing 128 (the value of the CLIENT_LOCAL_FILES constant) as the fifth parameter to mysql_connect () enables LOAD DATA LOCAL on the client side.

Example: $dbh = mysql_connect($server, $user, $pass, false, 128);

For PHP 4.3 and above.

  Posted by Peter Keane on September 12, 2005
Hi,

I was getting "the used command is not allowed with this mysql version". using mysql 4.1.11-standard-log. VB6 and MyODBC 3.51.06 on win2000. For this set up you need to add option 65536 Read parameters from the client and odbc groups from my.cnf.

Check this option in the MyOdbc options or an alternative is just to add this option to the connectionstring e.g. option=65536.

In the file c:\my.cnf (or where ever it is) add the following
[odbc]
local-infile=1

This sorted out the problem for me.

Peter Keane
  Posted by John Nagle on March 26, 2007
The standard configuration for shared and dedicated hosting today with the Plesk server administration system sets
"set-variable=local-infile=0" in "/etc/my.cnf". Thus, LOAD DATA LOCAL is disabled on such servers.

SHOW VARIABLES LIKE "local%";
will display the current setting of "local_infile".

Using the command line "mysql --local-infile=1" does not produce any error message when local_infile is OFF at the server end, even though "local_infile" is not thereby enabled.
  Posted by Geoffrey Transom on September 14, 2007
I agree completely with those who think there has been a 'negative improvement' recently.

My server has local_infile ON, and PHP is compiled with mysql... yet

LOAD DATA LOCAL INFILE [full file path, right from /home/.. ] INTO TABLE `TABLENAME` FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';

now produces different results depending on the client. It does not work in PHP scripts, nor does it work in mySQL Query browser... but it does work in phpMySQLAdmin. The same user/password was used for all attempts to get teh stupid thing to play like it used to.

It used to work just fine, and I have about a dozen scripts that use it. Simply trying to stick a CSV (on my own server) into an existing table (also on my own server) - and use a cron-job PHP script to do so rather than having to plod around doing it by hand in phpMySQLAdmin like a Dark Ages numpty.

Someone tell me what I am missing... tried giving it the relative path to the file, tried to absolute path, but NO JOY.

Cheers,

GT
  Posted by George S on January 14, 2008
I found this solution on another site.. in case the thread gets deleted I'll copy & paste it below.. Here is the original link:
http://forums.westhost.com/showthread.php?t=7010#6

edit my.cnf in /etc/:
----------------------------------------
[mysqld]
...(other stuff)
local-infile=1
[mysql]
...(other stuff)
local-infile=1

then shutdown, then start mysql:
----------------------------------------
shell> mysqladmin shutdown
shell> cd /usr/libexec
shell> mysqld
  Posted by Jorge Albarenque on July 29, 2013
I have some web forms on my intranet which uploaded a file to a database using this function. It broke after upgrading Debian to its Wheezy release.

In order to fix it I had to:
* Add local-infile=1 to the [mysqld] and [mysql] sections of my.cnf (as explained in the comments above)
* Use mysqli_real_connect function (check documentation).

The catch is that with that function you can explicitly enable the support for LOAD DATA LOCAL INFILE. For example (procedural style):

$link = mysqli_init();
mysqli_options($link, MYSQLI_OPT_LOCAL_INFILE, true);
mysqli_real_connect($link, 'localhost', $username, $password, $database);

This did not require any recompiling or anything else, works straigh away on Debian Wheezy. Hope this helps!!
Sign Up Login You must be logged in to post a comment.