缘起
近些日子,发现了 360 网站安全检测这个玩意儿,兴致勃勃地填入自己的网站开始了检测之旅。
悲剧的是,360 居然告诉我,我的网站有漏洞。知名的 WordPress 开源程序居然有漏洞?令我有所疑惑,仔细一查,原来这个漏洞不是 WordPress 弄出来的,而是我们自己的失误而造成的。
漏洞的详细信息是这样的:
为了防止有人看不清楚,我把文字也发上来:
漏洞上线时间:2011-07-02
漏洞名称:跨站脚本攻击漏洞
漏洞类型:跨站脚本攻击(XSS)
所属服务器类型:通用
漏洞风险:
- 存在 “网站用户资料泄露” 风险
- 安全性降低40%
- 全国 32% 网站有此漏洞, 520个站长进行了讨论
检测时间:2014-02-04 01:31:27
漏洞证据:
<script>alert(42873)</script>
解决方案:
方案一:避免XSS的方法之一主要是将用户所提供的内容输入输出进行过滤,许多语言都有提供对HTML的过滤:
可以利用下面这些函数对出现xss漏洞的参数进行过滤
PHP的
htmlentities()
或是htmlspecialchars()
。Python的
cgi.escape()
。ASP的
Server.HTMLEncode()
。ASP.NET的
Server.HtmlEncode()
或功能更强的 Microsoft Anti-Cross Site Scripting LibraryJava的 xssprotect(Open Source Library)。
Node.js的 node-validator。
方案二:使用开源的漏洞修复插件。( 需要站长懂得编程并且能够修改服务器代码 )
分析
其实这个问题在于我们制作主题的时候,忘记了做一件事——对搜索参数进行过滤。
大家可以查一查自己的主题,看看是否有类似 echo $_GET['s'];
这样的语句(多在 header.php 或 searchform.php),这多么危险啊,如果恶意对这个参数进行注入,危害可不是一点点。
解决
傻瓜化的解决方法是对它加一个过滤,即修改成 echo esc_attr($_GET['s']);
如果你不放心,还可以修改成 echo esc_attr(esc_html($_GET['s']));
这是最保险的过滤方法了。
如果你实在找不到类似语句,理论上你也可以在 functions.php 加上(没试过,你也可以试试):
<?php if (isset($_GET['s'])) { // $_GET['s'] = esc_attr($_GET['s']); $_GET['s'] = esc_attr(esc_html($_GET['s'])); } ?>
那么,WordPress 有没有想到这一点,翻翻 WordPress Codex,其实富有远见的 WordPress 早就为我们想到了这一点,本来人家就没有让我们用 echo $_GET['s'];
那样简单的方法去显示搜索的内容。其实是有那么一个函数来显示搜索内容的,WordPress 提供了两个函数来让我们获取搜索内容,一个是 the_search_query()
一个是 get_search_query()
。
the_search_query()
主要是让我们直接显示搜索内容,并且已经帮我们过滤好了;get_search_query()
是获取搜索内容,并且可以选择是否过滤(get_search_query(true)
或者 get_search_query(false)
),所以,最好的解决方案是改用 the_search_query()
和 get_search_query()
来获取和显示搜索内容。
修复好的童鞋们,360 应该 100 分了吧?