用PHP处理GIF动画的最好方法



首先,抱歉我的语法不好。英语不是我的主要语言……

我正在开发一个完全ajax的wordpress主题,其中包含前端线程提交表单,我想添加动画GIF支持。

我写了一个代码PHP代码使用imagick库:

// there is also another function that
checks image's exif, size, width, height, finfo and retuns true if all good.

// first imagick resize is basicly re-coding the image to kill shell/hack codes in the gif.
$imagick =  new Imagick($image['tmp_name']);
$imagick = $imagick->coalesceImages();
foreach($imagick as $frame){
$frame->scaleImage($width, 0);
}
$imagick = $imagick->deconstructImages();
$imagick->writeImages($new_image_name, true);
$imagick->destroy();
// and this one for the thumbnail of the post.
$imagick =  new Imagick($image['tmp_name']);
$imagick = $imagick->coalesceImages();
foreach($imagick as $frame){
$frame->scaleImage(wp_get_registered_image_subsizes()["left-frame-thumbnail"]["width"], 0);
}

$imagick = $imagick->deconstructImages();
$imagick->writeImages($new_image_name, true);
$imagick->destroy();

代码像魅力一样工作,但我注意到这是一个昂贵的代码。我的意思是,如果用户上传一个大的gif文件,在我看来,它会导致CPU峰值。

如果我将GIF大小限制为2MB也没关系,因为其他问题是帧数。正如我们所知,当我们调整GIF大小时,我们会拆分所有帧,调整它们的大小并重新将它们连接在一起。有很多大约300kb的gif,但其中包含50多个帧。所以帧数也是服务器CPU的一个问题。

然后我说;嘿!让我们用Javascript在客户端调整gif的大小!我写了一个代码,在客户端调整gif的大小。这确实非常有效。

我在服务器端写了一个代码来调整2gif文件的大小,并将它们直接保存到服务器(也检查它们的exif,dimensions,finfo)。一切正常,服务器CPU正常。

但是!我注意到第一条规则:"永远不要相信来自客户端的数据。">

如果我在客户端调整它的大小,这是好的。调整大小可以杀死图像中的hack/shell代码。但如果用户发送的假文件看起来像是刚调整过大小,并通过控制台或其他方式来自表单,该怎么办?

在我的ajax提交中已经有一个CSRF令牌,但我确信这还不够。

总结:处理gif动画的最好方法是什么?我做错了什么。

拆分为帧,调整大小并在客户端重新连接所有帧对于非恶意用户来说是一个很好的减少服务器负载的方法。然而,攻击者仍然可以向您的PHP发送任何请求,包括带有大量大帧的巨大gif -他们根本不需要运行您的javascript。所以你完全正确,这是一个潜在的拒绝服务,你应该减轻。用户输入不可信。

我想到了一些想法(注意,我从来没有真正使用过动画gif)。它们都围绕输入验证。

我不确定服务器上到底需要多长时间,但我猜它不是分割图像,更像是调整每帧的大小。由于您的javascript应该在客户端上调整gif的大小,因此接收到的任何gif都应该只包含限制大小的帧。你可以拆分收到的gif并检查第一帧——如果它太大,你可以立即拒绝整个请求,这种情况通常不会发生。(也许你甚至不需要拆分它来判断大小?)

你在客户端上拆分并一个接一个地发送它们的想法很棒,这从服务器上承担了拆分的负载,并且你仍然可以(并且应该)检查服务器上帧的大小。请注意,在这种情况下,不仅第一个可能太大,攻击者可以发送任何东西。

你也可以检查帧数,并设置一个最大值,因为没有这个,这是一个潜在的拒绝服务,因为攻击者可以只发送一个gif,比如10x10像素,但100万帧(我不确定gif格式是否有限制,但你明白这一点)。

另一种旁注是,无论您使用什么库来处理服务器上的gif,都可能容易受到恶意图像的不同攻击。例如Imagemagick在过去就有一些这样的漏洞。为了使其更安全,除了在库的新版本发布时进行明显的升级外,还可以在不同的服务器上运行图像处理,这是一种后台作业处理器。只允许非常有限的访问和访问该服务器并应用通用强化最佳实践可以帮助遏制任何未来的危害,并且还可以限制拒绝服务攻击的影响。

您还应该对这个图像上传端点应用某种速率限制,因为上传1000张100帧的图像甚至比上传1张100000帧的图像还要糟糕。因此,应该限制用户执行此操作的频率(或给定时间范围内的图像数量)。

最新更新