Gem 关于 rucaptcha 库验证码显示空白的问题探究及解决

bkbabydp · 2016年09月08日 · 最后由 flowerwrong 回复于 2016年11月07日 · 5615 次阅读
本帖已被管理员设置为精华贴

最近在使用验证码生成的库 huacnlee/rucaptcha 遇到一个问题:

我的机子是 CentOS 7 的,访问验证码页面的,总是空白;查看日志,报错:

Started GET "/rucaptcha/" for ...
Processing by RuCaptcha::CaptchaController#index as HTML ...
  RuCaptcha   RuCaptcha convert: not authorized `-' @ error/constitute.c/ReadImage/454.
                        convert: no images defined `png:-' @ error/convert.c/ConvertImageCommand/3046.

于是经过一番搜索,发现是 ImageMagick 的权限问题,请见社区相关帖子的评论部分:

完美的 Ruby 图形验证码 Gem - RuCaptcha

“你的 ImageMagick 版本可能太老了,请确保 ImageMagick 版本在 6.9 以上”

...

“!--wtf?那我不是要换系统???不干!”

于是死磕,终于解决。

原来 rucaptcha 库生成图片的原理是直接用命令行调用 convert指令(ImageMagick 库)::

huacnlee/rucaptcha 源码

以上错误,就是在调用label:- png:-的时候产生的。

缘起 policy.xml

/etc/ImageMagick/(注:用mac/brew安装的,则为 /usr/local/etc/ImageMagick-6/)下,有一个叫做policy.xml的配置文件,ImageMagick 用它来配置各种指令的权限,该文件默认禁用label png 等指令。

原来在 ImageMagick 通过一个叫做 delegates 的设计,来实现功能的兼容性和快速扩展,例如各种图片格式转换处理、网络访问等。https png 等指令都是通过该功能实现的。该功能的原理是:通过一个叫做 delegates.xml 的配置文件,配置指令所对应的 shell 语句,并传参执行。而该功能存在安全注入漏洞,攻击者可以通过构建恶意 shell 代码,利用 delegates 指令在解析上的疏忽,传递到delegates.xml对应的 shell 语句执行,进行注入攻击:

漏洞详情:ImageMagick Is On Fire — CVE-2016–3714 TL;DR

对此,官网的补救措施是使用 policy.xml 文件来对执行的命令进行权限控制;同时在 7.0.1-9 到 6.9.4-7 版本中对 delegates 参数进行安全过滤:

ImageMagick Security Issue —— from imagemagick.org

因此暂时的解决方案就是,把policy.xml里相关语句进行注销:

...
<policy domain="coder" rights="none" pattern="TEXT" />
<!-- <policy domain="coder" rights="none" pattern="LABEL" /> -->
<policy domain="path" rights="none" pattern="@*" />
...

修改完配置文件,重启服务,一切 ok 了。

待探究的课题

1、如何优化配置ImageMagick才能在易用性或者安全性中寻找一个比较好的平衡——就是rails提倡的最佳实践思想;

2、建议在rucaptcha库里去掉label:-而用-draw ...代替,暂未测试,理论上可行;

3、此类问题通常比较少见并且解决耗时,如何在开发策略上进行设计,使得此类问题的风险和成本尽可能降低。

第一次发帖,多多指教,欢迎探讨。

补充

该发完此贴,就发现ruby-china针对优化配置ImageMagick的问题有过一个相关探讨,参看如下:

大量网站易受 ImageMagick 漏洞影响 ImageMagic 又爆可执行漏洞

看来社区功能在知识链接上的发力真的是可圈可点啊!

huacnlee 将本帖设为了精华贴。 09月08日 11:34

其实我还想用 Go 来写背后的图片生成

https://github.com/dchest/captcha

这样就不用依赖 ImageMagick 了

#2 楼 @huacnlee 很期待!关于 google 的验证码我也是各种吐槽,虽然防破解性提高了,但是那个用户体验,😜 ,我这种眼神不好的就惨了。怎么在用户体验和防破解上寻求平衡,是一个很好玩的点哦。

这里有一篇不错:

http://www.cnblogs.com/chengmo/archive/2010/12/06/1898062.html

可以参考。

试了一下,基于 https://github.com/dchest/captcha 实现了一个简单的二进制文件(绿色的),可以直接代替 ImageMagick,但问题是这个不好包到 Gem 里面,因为二进制文件带有 Go 的虚拟机在里面,5M...

做成 apt-get 的包倒是可以,但链路又长了,还不如 ImageMagick

突然想起几年前 @vincenting 造的一个 go 的验证码 他是中文数字混排简单运算的方式

https://github.com/jianxinio/captcha

抛弃验证码,上两步验证

我也遇到这个问题,没有你研究这么深。只是发现,6.9.x 之间的 ImageMagick 相差一个小版本。一个可以生成 图片,一个不可以。然后,就在那个不可以的 server 上,安装 remi 库,强制将 imagemagick 升级到 7.x。问题就解决了。至今不知为何。

thx, save me a long time.

需要 登录 后方可回复, 如果你还没有账号请 注册新账号