暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

[ACDU 翻译] MySQL 6.1.6 LOAD DATA LOCAL 的安全注意事项

原创 由迪 2021-08-10
284

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语句(无论客户端程序和库在构建时或运行时如何配置),请以 禁用或启用的方式启动mysqldlocal_infilelocal_infile也可以在运行时设置。

  • 在客户端:

    • CMake的选项控制编译默认的MySQL客户端库能力(参见 第2.9.7“MySQL的源代码,配置选项”)。因此,没有明确安排的客户端 根据 MySQL 构建时指定的设置禁用或启用功能 。 ENABLED_LOCAL_INFILE LOCAL``LOCALENABLED_LOCAL_INFILE

    • 默认情况下,MySQL 二进制发行版中的客户端库在编译时 ENABLED_LOCAL_INFILE 禁用。如果您从源代码编译 MySQL,请ENABLED_LOCAL_INFILE 根据未进行明确安排的客户端是否应 LOCAL禁用或启用功能来将其配置为禁用或启用。

    • 对于使用 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\]选项。

    • 如果 LOAD DATA LOCAL在 Perl 脚本或其他[client]从选项文件中读取组的程序中使用,则可以向该组添加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 的客户端程序可以使用C API 函数的MYSQL_OPT_LOCAL_INFILEMYSQL_OPT_LOAD_DATA_LOCAL_DIR选项 控制允许加载数据加载的文件 mysql_options()(请参阅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值的解释 如下:
    • 如果该值为空指针(默认值),则不命名目录,因此不允许LOCAL加载任何文件。
    • 如果该值为目录路径名, LOCAL则允许加载数据,但仅限于位于指定目录中的文件。无论底层文件系统是否区分大小写,目录路径名和要加载的文件的路径名的比较是区分大小写的。

MySQL 客户端程序使用上述 mysql_options()选项如下:

  • MySQL的客户端有一个 --load-data-local-dir选项,将一个目录路径或一个空字符串。 mysql使用选项值来设置 MYSQL_OPT_LOAD_DATA_LOCAL_DIR选项(使用空字符串将值设置为空指针)。的效果 --load-data-local-dir取决于是否LOCAL启用了数据加载:

    如果--load-data-local-dir 适用,期权价值对在其中本地数据文件必须位于该目录。无论底层文件系统是否区分大小写,目录路径名和要加载的文件的路径名的比较是区分大小写的。如果选项值为空字符串,则不命名目录,因此不允许本地数据加载任何文件。

  • mysqlimportMYSQL_OPT_LOAD_DATA_LOCAL_DIR为其处理的每个文件设置 ,以便包含该文件的目录是允许的本地加载目录。

  • 对于LOAD DATA语句对应的数据加载操作 , mysqlbinlog从二进制日志事件中提取文件,将它们作为临时文件写入本地文件系统,并写入 LOAD DATA LOCAL语句导致文件被加载。默认情况下,mysqlbinlog将这些临时文件写入操作系统特定的目录。该--local-load选项可用于显式指定 mysqlbinlog应准备本地临时文件的目录。

    因为其他进程可以将文件写入默认的系统特定目录,所以建议在 mysqlbinlog中指定--local-load选项 为数据文件指定不同的目录,然后在处理mysqlbinlog的输出时 通过指定mysql的选项来指定同一目录 . --load-data-local-dir

MySQL Shell 和本地数据加载

MySQL Shell 提供了许多实用程序来转储表、模式或服务器实例并将它们加载到其他实例中。当您使用这些实用程序处理数据时,MySQL Shell 提供了额外的功能,例如输入预处理、多线程并行加载、文件压缩和解压缩以及处理对 Oracle Cloud Infrastructure Object Storage 存储桶的访问。要获得最佳功能,请始终使用最新版本的 MySQL Shell 转储和转储加载实用程序。

MySQL Shell 的数据上传实用程序使用 LOAD DATA LOCAL INFILE语句上传数据,因此 local_infile必须ON在目标服务器实例上将系统变量设置为。您可以在上传数据之前执行此操作,然后再将其删除。这些实用程序安全地处理文件传输请求,以处理本主题中讨论的安全注意事项。

MySQL Shell 包括这些转储和转储加载实用程序:

  • 表导出实用程序 util.exportTable()

    将 MySQL 关系表导出为数据文件,该文件可以使用 MySQL Shell 的并行表导入实用程序上传到 MySQL 服务器实例、导入到不同的应用程序或用作逻辑备份。该实用程序具有预设选项和自定义选项以生成不同的输出格式。

  • 并行表导入实用程序 util.importTable()

    将数据文件导入 MySQL 关系表。数据文件可以是 MySQL Shell 的表导出实用程序的输出,也可以是该实用程序的预设和自定义选项支持的其他格式。该实用程序可以在将数据添加到表之前执行输入预处理。它可以接受多个数据文件合并成一个单一的关系表,并自动解压压缩文件。

  • 实例转储实用程序 util.dumpInstance()、模式转储实用程序 util.dumpSchemas()和表转储实用程序util.dumpTables()

    将实例、模式或表导出到一组转储文件,然后可以使用 MySQL Shell 的转储加载实用程序将其上传到 MySQL 实例。这些实用程序提供 Oracle 云基础设施对象存储流、MySQL 数据库服务兼容性检查和修改,以及在继续转储之前执行试运行以识别问题的能力。

  • 转储加载实用程序 util.loadDump()

    将使用 MySQL Shell 的实例、架构或表转储实用程序创建的转储文件导入 MySQL 数据库服务数据库系统或 MySQL 服务器实例。该实用程序管理上传过程并提供来自远程存储的数据流、表或表块的并行加载、进度状态跟踪、恢复和重置功能以及在转储仍在进行时并发加载的选项。MySQL Shell 的并行表导入实用程序可与转储加载实用程序结合使用,以在将数据上传到目标 MySQL 实例之前对其进行修改。

有关实用程序的详细信息,请参阅 MySQL Shell 实用程序

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论