最近在使用验证码生成的库 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 库)::
以上错误,就是在调用label:- png:-
的时候产生的。
在 /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 又爆可执行漏洞
看来社区功能在知识链接上的发力真的是可圈可点啊!