安全策略 • 安全策略示例 • 像素缓存同步策略 • 零配置安全策略 • 其他安全注意事项
在使用 ImageMagick 之前,强烈建议您为本地环境建立合适的安全策略。
默认策略是开放的,这对于在安全环境(例如 Docker 容器或防火墙后面)中运行的 ImageMagick 安装非常有用。
ImageMagick 是一款允许您操作图像的工具。虽然它提供了各种功能和特性,但安全性和便利性之间常常需要权衡。为了确保最佳安全性,您可以限制 ImageMagick 仅读取或写入网络安全图像格式,例如 GIF、JPEG 和 PNG。或者,您可以自定义安全策略以适应本地环境或组织策略的需求。此策略可以包括诸如内存使用限制、允许的读写路径、图像序列数量限制、最大工作流运行时间、图像像素允许的磁盘空间、远程连接的秘密密码以及允许或拒绝哪些编码器的详细信息。通过自定义安全策略,您可以帮助保护您的环境并确保 ImageMagick 是您本地系统中负责任的一员,例如防止被大型图像过载。
务必限制 ImageMagick 的资源使用,以防止潜在的有害情况。例如,如果您不小心从互联网下载了一个经过精心制作以生成非常大的图像(例如 20000 x 20000 像素)的图像,ImageMagick 可能会尝试分配必要的资源(例如内存和磁盘空间),并且您的系统可能会拒绝该请求或导致程序退出。或者,您的计算机可能会暂时变慢或无响应,或者 ImageMagick 可能会被迫中止。为了避免这种情况,您可以在 policy.xml 配置文件中设置限制。
请记住,在一个环境中被认为合理的策略在另一个环境中可能不适用。例如,您可能在一个安全的环境中沙盒化 ImageMagick,而其他人可能使用它在公共访问的网站上处理图像。或者,ImageMagick 可能会在一个具有大量内存的主机上运行,而另一个实例则在一个资源有限的设备上运行。对于具有大量内存的主机,允许大型图像处理可能是有意义的,但在资源有限的设备上则不然。如果您在公共网站上使用 ImageMagick,则可能需要通过禁用某些编码器(例如 MVG 或 HTTPS)来提高安全性。
为了帮助您入门,从 7.1.1-16 版本开始,ImageMagick 提供了您在安装 ImageMagick 时可以选择的安全策略。从以下选项中选择:
- open
- ImageMagick 安装的默认策略是开放安全策略。此策略旨在用于安全设置,例如受防火墙保护或 Docker 容器内的设置。在此框架内,ImageMagick 可以广泛访问资源和功能。此策略为图像操作提供了便捷且灵活的选项。但是,需要注意的是,它在监管较少的条件下可能会存在安全漏洞。因此,组织应根据其特定用例和安全先决条件彻底评估开放策略的适用性。
- limited
- 有限安全策略的主要目标是在便利性和安全性之间找到平衡点。此策略涉及停用潜在的危险功能,例如 SVG 或 HTTP 等特定编码器。此外,它还对资源的使用(如内存、存储和处理持续时间)设置了一些限制,所有这些限制都是可调整的。此策略在需要降低处理可能恶意或要求苛刻的图像的潜在威胁的同时,保留常用图像格式的基本功能的情况下很有优势。
- secure
- 此严格的安全策略优先实施严格的控制和受限的资源利用,以在使用 ImageMagick 时建立一个极其安全的设置。它停用了可能存在危险的功能,包括 SVG 或 HTTP 等特定编码器。该策略促进根据本地环境的要求和组织的指南定制安全措施。此协议包含明确的细节,例如内存消耗限制、允许的读写路径、图像序列限制、工作流的最大允许持续时间、用于图像数据的磁盘空间分配,甚至用于远程连接的未公开密码。通过采用此稳健的策略,实体可以提高其整体安全态势并减轻潜在的漏洞。
- websafe
- 此安全协议专为网络安全使用而设计,专注于 ImageMagick 在公共访问环境(如网站)中应用的情况。它停用读取或写入除网络安全格式(如 GIF、JPEG 和 PNG)以外的任何图像格式的功能。此外,此策略禁止执行图像过滤器和间接读取,从而阻止潜在的安全漏洞。通过实施这些限制,网络安全策略加强了对公众可访问系统的保护,降低了利用 ImageMagick 的功能进行潜在攻击的风险。
在 Linux 下,使用--with-security-policy={open, limited, secure, websafe}
配置脚本选项选择策略。在 Windows 下,在运行配置应用程序时会显示此选择。
我们鼓励您查看 policy.xml
配置文件中的每个规则。根据组织的要求调整参数。您可以修改允许的图像格式、设置特定路径并根据您的安全需求限制某些操作。请记住,自定义安全策略是在功能和安全性之间进行微妙的平衡。过于严格的策略可能会阻碍合法的图像处理任务,而过于宽松的策略可能会引入漏洞。
安全策略示例
这是一个安全策略示例
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policymap [
<!ELEMENT policymap (policy)*>
<!ATTLIST policymap xmlns CDATA #FIXED "">
<!ELEMENT policy EMPTY>
<!ATTLIST policy xmlns CDATA #FIXED "">
<!ATTLIST policy domain NMTOKEN #REQUIRED>
<!ATTLIST policy name NMTOKEN #IMPLIED>
<!ATTLIST policy pattern CDATA #IMPLIED>
<!ATTLIST policy rights NMTOKEN #IMPLIED>
<!ATTLIST policy stealth NMTOKEN #IMPLIED>
<!ATTLIST policy value CDATA #IMPLIED>
]>
<!--
Creating a security policy that fits your specific local environment
before making use of ImageMagick is highly advised. You can find guidance on
setting up this policy at https://imagemagick.org.cn/script/security-policy.php,
and it's important to verify your policy using the validation tool located
at https://imagemagick-secevaluator.doyensec.com/.
Web-safe ImageMagick security policy:
This security protocol designed for web-safe usage focuses on situations
where ImageMagick is applied in publicly accessible contexts, like websites.
It deactivates the capability to read from or write to any image formats
other than web-safe formats like GIF, JPEG, and PNG. Additionally, this
policy prohibits the execution of image filters and indirect reads, thereby
thwarting potential security breaches. By implementing these limitations,
the web-safe policy fortifies the safeguarding of systems accessible to
the public, reducing the risk of exploiting ImageMagick's capabilities
for potential attacks.
-->
<policymap>
<!-- Set maximum parallel threads. -->
<policy domain="resource" name="thread" value="2"/>
<!-- Set maximum time in seconds or neumonics, e.g. "2 minutes". When this
limit is exceeded, an exception is thrown and processing stops. -->
<policy domain="resource" name="time" value="60"/>
<!-- Set maximum number of open pixel cache files. When this limit is
exceeded, any subsequent pixels cached to disk are closed and reopened
on demand. -->
<policy domain="resource" name="file" value="768"/>
<!-- Set maximum amount of memory in bytes to allocate for the pixel cache
from the heap. When this limit is exceeded, the image pixels are cached
to memory-mapped disk. -->
<policy domain="resource" name="memory" value="256MiB"/>
<!-- Set maximum amount of memory map in bytes to allocate for the pixel
cache. When this limit is exceeded, the image pixels are cached to
disk. -->
<policy domain="resource" name="map" value="512MiB"/>
<!-- Set the maximum width * height of an image that can reside in the pixel
cache memory. Images that exceed the area limit are cached to disk. -->
<policy domain="resource" name="area" value="16KP"/>
<!-- Set maximum amount of disk space in bytes permitted for use by the pixel
cache. When this limit is exceeded, the pixel cache is not be created
and an exception is thrown. -->
<policy domain="resource" name="disk" value="1GiB"/>
<!-- Set the maximum length of an image sequence. When this limit is
exceeded, an exception is thrown. -->
<policy domain="resource" name="list-length" value="16"/>
<!-- Set the maximum width of an image. When this limit is exceeded, an
exception is thrown. -->
<policy domain="resource" name="width" value="4KP"/>
<!-- Set the maximum height of an image. When this limit is exceeded, an
exception is thrown. -->
<policy domain="resource" name="height" value="4KP"/>
<!-- Periodically yield the CPU for at least the time specified in
milliseconds. -->
<policy domain="resource" name="throttle" value="2"/>
<!-- Do not create temporary files in the default shared directories, instead
specify a private area to store only ImageMagick temporary files. -->
<!-- -->
<!-- Force memory initialization by memory mapping select memory
allocations. -->
<policy domain="cache" name="memory-map" value="anonymous"/>
<!-- Ensure all image data is fully flushed and synchronized to disk. -->
<policy domain="cache" name="synchronize" value="true"/>
<!-- Replace passphrase for secure distributed processing -->
<!-- -->
<!-- Do not permit any delegates to execute. -->
<policy domain="delegate" rights="none" pattern="*"/>
<!-- Do not permit any image filters to load. -->
<policy domain="filter" rights="none" pattern="*"/>
<!-- Don't read/write from/to stdin/stdout. -->
<policy domain="path" rights="none" pattern="-"/>
<!-- don't read sensitive paths. -->
<policy domain="path" rights="none" pattern="/etc/*"/>
<!-- Indirect reads are not permitted. -->
<policy domain="path" rights="none" pattern="@*"/>
<!-- Deny all image modules and specifically exempt reading or writing
web-safe image formats. -->
<policy domain="module" rights="none" pattern="*" />
<policy domain="module" rights="read | write" pattern="{GIF,JPEG,PNG,WEBP}" />
<!-- This policy sets the number of times to replace content of certain
memory buffers and temporary files before they are freed or deleted. -->
<policy domain="system" name="shred" value="1"/>
<!-- Enable the initialization of buffers with zeros, resulting in a minor
performance penalty but with improved security. -->
<policy domain="system" name="memory-map" value="anonymous"/>
<!-- Set the maximum amount of memory in bytes that is permitted for
allocation requests. -->
<policy domain="system" name="max-memory-request" value="256MiB"/>
</policymap>
为了防止一个会话在同时处理多个会话时消耗所有可用内存,此策略将大型图像缓存到磁盘。如果图像超过像素缓存磁盘限制,程序将退出。此外,还设置了时间限制以防止任何处理任务运行时间过长。如果图像的宽度或高度大于 8192 像素,或者图像序列超过 32 帧,处理将停止并抛出异常。
从 ImageMagick 7.0.1-8 开始,您可以阻止使用任何委托或所有委托(通过将模式设置为“*”)。在这些版本之前,您可以使用coder 的域并将权限设置为 none,并将 glob 模式设置为 HTTPS 以防止委托使用。此外,用户被阻止执行任何图像过滤器和执行间接读取。例如,如果您想从文件(例如caption:@myCaption.txt)中读取文本,则需要禁用此路径策略。
在 ImageMagick 7.1.1-16 之前,策略glob 模式区分大小写。为了获得预期的行为,编码器和模块必须是大写的(例如“EPS”而不是“eps”)或使用不区分大小写的模式,例如[Pp][Nn][Gg]。
例如,当您限制 HTTPS 编码器时,您可以预期以下情况
$ magick https://imagemagick.org.cn/image/wizard.png wizard.jpg convert: attempt to perform an operation not allowed by the security policy `HTTPS' convert: no images defined `wizard.jpg'
从 ImageMagick 7.0.4-7 版本开始,您可以方便地拒绝访问所有委托和编码器,除了少数经过验证的网络安全图像类型。例如,
<policy domain="delegate" rights="none" pattern="*" /> <policy domain="module" rights="none" pattern="*" /> <policy domain="module" rights="read | write" pattern="{GIF,JPEG,PNG,WEBP}" />
模块策略启用或禁用用于读取或写入的完整模块。要仅读取或写入图像格式,请改用编码器策略。例如,我们禁用了读取一些与 Postscript 相关的格式,但是您仍然可以写入它们
<policy domain="coder" rights="write" pattern="{PDF,PS,PS2,PS3,XPS}" />
从 ImageMagick 7.0.7-0 版本开始,您可以使用匿名内存映射而不是堆来分配像素缓存和一些内部缓冲区。结果,像素被初始化为零,从而导致性能略有下降。您还可以对某些内存缓冲区(需要 7.1.0-38 版本)和临时文件的内容进行混淆,然后再释放或删除它们。shred 值是替换内容为随机数据的次数。例如,
<policy domain="system" name="memory-map" value="anonymous"/> <policy domain="cache" name="memory-map" value="anonymous"/> <policy domain="system" name="shred" value="1"/>
出于性能原因,第一次传递速度很快,因为它根据需要重复随机序列以覆盖缓冲区或文件的内容。后续传递的速度慢了一个数量级,但会为缓冲区或文件的长度生成密码学上安全的随机字节。
一些图像处理算法(例如小波变换)可能会消耗大量内存才能完成。ImageMagick 为这些大型资源请求维护一个单独的内存池,并且从 7.0.6-1 开始允许您设置最大请求限制。如果超过限制,则分配将改为内存映射到磁盘。在这里,我们通过策略限制最大内存请求
<policy domain="system" name="max-memory-request" value="256MiB"/>
从 ImageMagick 7.0.4-23 版本开始,您可以限制序列中图像的最大数量。例如,要将图像序列限制为最多 64 帧,请使用
<policy domain="resource" name="list-length" value="64"/>
请注意,策略中的数字值是浮点数,并带有一个可选的 SI 前缀(例如,10MiB)。
有关资源限制和策略配置文件的更多详细信息,请阅读资源 和 体系结构。
从 ImageMagick 7.0.6-0 版本开始,您可以使用 SetMagickSecurityPolicy()(MagickCore)或 MagickSetSecurityPolicy()(MagickWand)以编程方式设置 ImageMagick 安全策略。
从 ImageMagick 7.0.8-11 版本开始,您可以设置module 安全策略。例如,要阻止 Postscript 或 PDF 解释,请使用
<policy domain="module" rights="none" pattern="{ps,pdf,xps}/>
从 ImageMagick 7.0-10-52 版本开始,您可以设置font 策略。指定 ImageMagick 在用户未指定字体首选项时默认使用的 Unicode 字体的路径
<policy domain="system" name="font" value="/usr/share/fonts/arial-unicode.ttf"/>
请注意,在文件路径 glob 模式中,使用反斜杠字符 (\) 来转义否则会被解释为特殊字符的字符。例如
<policy domain="path" rights="none" pattern="c:\\\\*"/>
您可以使用以下命令验证您的策略更改是否生效
$ magick identify -list policy Path: ImageMagick-7/policy.xml Policy: Cache name: memory-map value: anonymous Policy: Cache name: synchronize value: true Policy: Resource name: list-length value: 32 Policy: Resource name: time value: 120 Policy: Resource name: thread value: 2 Policy: Resource name: file value: 768 Policy: Resource name: disk value: 1GiB Policy: Resource name: map value: 512MiB Policy: Resource name: memory value: 256MiB Policy: Resource name: area value: 16KP Policy: Resource name: height value: 8KP Policy: Resource name: width value: 8KP Policy: Resource name: temporary-path value: /opt/tmp Policy: Coder rights: Write pattern: {HTTP,HTTPS,MVG,PS,PDF} Policy: Filter rights: None pattern: * Policy: Path rights: None pattern: @* Policy: System name: font value: ImageMagick-7/arial-unicode.ttf Path: [built-in] Policy: Undefined rights: None
请注意,由于stealth 属性,未列出shared-secret 策略。
Doyensec 提供了一个策略评估工具,可以帮助您设计和审核安全策略。该工具位于 imagemagick-secevaluator.doyensec.com。
像素缓存同步策略
将图像像素写入磁盘时,ImageMagick 首先预分配磁盘文件,这比用零完全填充文件更快。为了进一步提高性能,文件被内存映射到磁盘。这可以使性能提高多达 5 倍,但磁盘文件可能会用完可用空间,因为它是被填充的,导致操作系统 (OS) 抛出一个 SIGBUS 信号,从而阻止 ImageMagick 继续执行。为了防止发生 SIGBUS 信号,请使用此安全策略
<policy domain="cache" name="synchronize" value="True"/>
设置为 True 以确保所有图像数据完全刷新并同步到磁盘。但是,这会带来性能损失,但好处包括在系统崩溃时确保有效的图像文件,以及在图像像素缓存没有足够磁盘空间时尽早报告。
零配置安全策略
ImageMagick 的零配置构建不允许外部配置文件。要定义您的安全策略,您必须编辑 MagickCore/policy-private.h 源模块,添加您的策略语句,然后构建 ImageMagick 发行版。这是一个零配置安全策略示例
static const char *ZeroConfigurationPolicy = \ "<policymap> \ <policy domain=\"coder\" rights=\"none\" pattern=\"MVG\"/> \ </policymap>";
其他安全注意事项
如果您在 ImageMagick 中发现漏洞,首先确定安全策略是否可以缓解该漏洞。默认情况下,ImageMagick 是开放的。使用安全策略添加约束以满足本地安全治理的要求。如果您确信安全策略没有解决该漏洞,请将该漏洞作为 安全公告 发布。大多数漏洞将在 48 小时内得到审查和解决。
有几种方法可以使 ImageMagick 更安全
- 使用网络安全图像格式:将 ImageMagick 限制为仅读取或写入 GIF、JPEG 和 PNG 等网络安全图像格式可以帮助提高安全性。
- 自定义安全策略:您可以自定义安全策略以适应本地环境或组织策略的需求。此策略可以涵盖诸如内存使用、允许的读写路径、序列中允许的图像数量、工作流允许运行的最长时间、图像像素允许的磁盘空间、远程连接的秘密密码以及允许或拒绝哪些编码器等方面。
- 设置资源使用限制:您可以设置资源使用限制,例如内存使用、磁盘空间和工作流运行时间,以防止潜在的有害情况。
- 使用沙盒:沙盒是一种安全技术,允许您在受限环境中运行程序,以防止它访问敏感信息或更改系统。
- 禁用潜在的危险编码器:如果您在公共网站上使用 ImageMagick,则可能需要通过禁用某些编码器(例如 MVG 或 HTTPS)来提高安全性。
- 防止执行图像过滤器和间接读取:您可以防止用户执行图像过滤器和执行间接读取以提高安全性。
- 使用当前版本的 ImageMagick:使用当前版本的 ImageMagick 以利用最新的安全修复和更新非常重要。