偶然发现博客居然存在SQL注入漏洞?当时就懵逼了,这么久才发现。。。
漏洞发现
在博主随笔处,利用了wp自带的wp_ajax钩子,过滤不严,导致POST提交查询文章内容时,s_id
存在sql注入漏洞。
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: www.mrwu.red
Connection: close
Content-Length: 26
Accept: */*
Origin: https://www.mrwu.red
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: https://www.mrwu.red/sy
Accept-Language: zh-CN,zh;q=0.9
Cookie:action=shuoshuo&s_id=1467
漏洞代码
//ajax shuoshuo function shuoshuo(){ echo popularPosts($num); die(); } add_action('wp_ajax_shuoshuo', 'shuoshuo'); add_action('wp_ajax_nopriv_shuoshuo', 'shuoshuo'); function popularPosts($num) { global $wpdb; $s_id = $_POST['s_id']; $sql="SELECT ID,post_title,post_content FROM wp_posts WHERE post_type='shuoshuo' and post_status = 'publish' and ID = $s_id order by ID desc"; $myrows = $wpdb->get_results($sql); foreach ($myrows as $b) { echo $b->post_content;//这是文章内容 //echo $b->ID." ";//这是文章ID // echo $b->post_title." ";//这是文章标题 }}
可以看到,在$sql
那段,$s_id
直接就被调用了,没有做任何的过滤处理,最终导致了SQL注入漏洞。
漏洞修复
在$s_id
加上单引号即可解决问题。
//ajax shuoshuo function shuoshuo(){ echo popularPosts($num); die(); } add_action('wp_ajax_shuoshuo', 'shuoshuo'); add_action('wp_ajax_nopriv_shuoshuo', 'shuoshuo'); function popularPosts($num) { global $wpdb; $s_id = $_POST['s_id']; $sql="SELECT ID,post_title,post_content FROM wp_posts WHERE post_type='shuoshuo' and post_status = 'publish' and ID = '$s_id' order by ID desc"; $myrows = $wpdb->get_results($sql); foreach ($myrows as $b) { echo $b->post_content;//这是文章内容 //echo $b->ID." ";//这是文章ID // echo $b->post_title." ";//这是文章标题 }}
2018-10-22补充:
从土司大佬那学到了intval()
函数,大致作用就是将值强制转为数字,能有效过滤sql注入,而在我这里这个函数再适合不过,于是就给加上了。
function popularPosts($num) { global $wpdb; $s_id = intval($_POST['s_id']); $sql="SELECT ID,post_title,post_content FROM wp_posts WHERE post_type='shuoshuo' and post_status = 'publish' and ID = '$s_id' order by ID desc"; $myrows = $wpdb->get_results($sql); foreach ($myrows as $b) { echo $b->post_content;//这是文章内容 //echo $b->ID."
";//这是文章ID // echo $b->post_title."
";//这是文章标题 }}
本文作者为Mr.Wu,转载请注明,尊守博主劳动成果!
由于经常折腾代码,可能会导致个别文章内容显示错位或者别的 BUG 影响阅读; 如发现请在该文章下留言告知于我,thank you !
话说为啥加单引号就不会注入了呢
@mr.tcsy得看情况,有时候加单引号带入就能防注入,有时候又可以用汉字双字节编码进行绕过,主要得看代码是怎么写的,像我这里这种加单引号就能防注入,不过保险正规的话还是建议用intval()函数