DedeCMS 后台评论管理存储型XSS漏洞修复教程

一、漏洞说明

该漏洞属于后台中危存储型XSS漏洞,影响DedeCMS全版本,攻击者登录后台后,可利用评论管理功能,在评论内容中植入XSS恶意脚本,脚本被存储到数据库中,当管理员查看评论列表时,恶意脚本被执行,导致管理员Cookie被劫持、后台操作被篡改,甚至被获取后台控制权。

  • 漏洞类型:存储型XSS
  • 危害等级:中危
  • 影响版本:DedeCMS 全版本(含V5.7 SP2 ~ 5.7.118及衍生版本)
  • 漏洞文件:/dede/feedback_main.php
  • 漏洞场景:后台评论编辑、新增功能中,程序未对评论内容、评论者名称等参数进行过滤,直接将内容存储到数据库,当管理员查看评论时,未对存储的内容进行转义,导致XSS脚本执行。

二、代码分析

漏洞核心原因:feedback_main.php 文件中,后台评论管理功能(新增、编辑)未对评论内容、评论者名称等用户提交的参数进行过滤,直接存储到数据库;查看评论时,未对数据库中存储的内容进行转义处理,导致存储型XSS漏洞,恶意脚本被执行。

关键漏洞代码(原文件片段):

<?php
// 原漏洞代码(后台评论编辑/新增逻辑,存在存储型XSS漏洞)
require_once(dirname(__FILE__)."/config.php");
$action = $_POST['action'];
$id = $_POST['id'];
$username = $_POST['username'];
$content = $_POST['content'];

// 未过滤参数,直接存储到数据库
if($action == 'edit'){
    $sql = "UPDATE `#@__feedback` SET username='$username', content='$content' WHERE id=$id";
    $dsql->ExecuteNoneQuery($sql);
    echo '评论编辑成功';
}elseif($action == 'add'){
    $sql = "INSERT INTO `#@__feedback` (username, content, dtime) VALUES ('$username', '$content', ".time().")";
    $dsql->ExecuteNoneQuery($sql);
    echo '评论新增成功';
}

// 查看评论时,未转义内容,直接输出
$sql = "SELECT * FROM `#@__feedback` WHERE id=$id";
$row = $dsql->GetOne($sql);
echo "评论者:{$row['username']}<br/>评论内容:{$row['content']}";
?>

代码问题分析:

  1. 参数未过滤:username、content参数直接从POST请求中获取,未进行任何XSS过滤处理,允许传入恶意脚本;
  2. 存储未处理:未对参数进行转义,直接将含恶意脚本的内容存储到数据库,形成存储型XSS;
  3. 输出未转义:查看评论时,直接从数据库中读取内容并输出,未进行html转义,导致恶意脚本执行;
  4. 无权限校验:未对评论管理权限进行细分,普通管理员也可新增、编辑评论,扩大漏洞利用范围;
  5. 无内容校验:未校验评论内容的合法性,允许写入任意长度、任意类型的恶意内容。

漏洞利用示例(仅用于学习,请勿非法测试):

// 1. 普通管理员登录后台,访问评论管理页面,点击新增评论;

// 2. 评论者名称输入:<script>alert(document.cookie)</script>,评论内容输入任意内容;

// 3. 保存评论后,管理员查看该评论时,恶意脚本执行,弹出管理员Cookie信息;

// 4. 构造恶意脚本(如劫持Cookie、跳转恶意页面),可获取管理员后台控制权。

三、修复方法(原位修复,不升级、不影响模板)

本修复方案无需升级DedeCMS版本,仅修改feedback_main.php文件,通过过滤参数、存储转义、输出转义,封堵存储型XSS漏洞,不影响正常评论管理功能,步骤如下:

步骤1:备份漏洞文件

备份 /dede/feedback_main.php 文件,备份路径示例:/dede/feedback_main.php.bak,避免修改错误导致后台评论管理功能异常,便于后续回滚操作。

步骤2:核心修复(过滤+转义+权限校验)

打开 /dede/feedback_main.php 文件,替换为以下修复后的代码,核心是过滤恶意脚本、存储和输出转义、添加权限校验:

<?php
require_once(dirname(__FILE__)."/config.php");
// 修复1:添加权限校验,仅允许指定权限管理员操作评论
if($cuserLogin->getUserType() > 2){
    exit('无权限操作,请联系管理员');
}

// 修复2:过滤和转义参数,防止存储型XSS
$action = addslashes($_POST['action']);
$id = intval($_POST['id']);
// 过滤XSS恶意脚本,转义特殊字符
$username = htmlspecialchars(addslashes($_POST['username']), ENT_QUOTES);
$content = htmlspecialchars(addslashes($_POST['content']), ENT_QUOTES);

// 修复3:校验参数合法性,禁止空内容提交
if(empty($username) || empty($content)){
    exit('评论者名称和评论内容不能为空');
}

// 修复4:获取当前登录管理员信息,用于日志记录
$currentAdmin = $cuserLogin->getUserInfo();
$adminName = $currentAdmin['adminname'];

if($action == 'edit'){
    // 校验评论ID是否存在
    $row = $dsql->GetOne("SELECT id FROM `#@__feedback` WHERE id=$id");
    if(empty($row)){
        exit('评论ID不存在,禁止编辑');
    }
    // 转义后存储,无XSS风险
    $sql = "UPDATE `#@__feedback` SET username='$username', content='$content' WHERE id=$id";
    $dsql->ExecuteNoneQuery($sql);
    // 修复5:添加操作日志
    $logContent = "管理员【$adminName】于".date('Y-m-d H:i:s')."编辑评论,评论ID:$id,评论者:$username";
    $dsql->ExecuteNoneQuery("INSERT INTO `#@__admin_log` (adminname, action, logtime, content) VALUES ('$adminName', 'feedback_edit', ".time().", '$logContent')");
    echo '评论编辑成功';
}elseif($action == 'add'){
    // 转义后存储,无XSS风险
    $sql = "INSERT INTO `#@__feedback` (username, content, dtime) VALUES ('$username', '$content', ".time().")";
    $dsql->ExecuteNoneQuery($sql);
    // 修复5:添加操作日志
    $logContent = "管理员【$adminName】于".date('Y-m-d H:i:s')."新增评论,评论者:$username";
    $dsql->ExecuteNoneQuery("INSERT INTO `#@__admin_log` (adminname, action, logtime, content) VALUES ('$adminName', 'feedback_add', ".time().", '$logContent')");
    echo '评论新增成功';
}

// 修复6:查看评论时,再次转义输出,双重防护
if(!empty($id)){
    $sql = "SELECT * FROM `#@__feedback` WHERE id=$id";
    $row = $dsql->GetOne($sql);
    if(!empty($row)){
        // 输出时转义,防止XSS脚本执行
        $showUsername = htmlspecialchars($row['username'], ENT_QUOTES);
        $showContent = htmlspecialchars($row['content'], ENT_QUOTES);
        echo "评论者:{$showUsername}<br/>评论内容:{$showContent}";
    }
}
?>

步骤3:额外加固(可选,提升安全性)

1.限制评论内容长度:设置评论内容最大长度(如500字符),禁止输入过长的恶意脚本;
2.过滤危险标签:添加自定义XSS过滤函数,过滤<script>、<iframe>等危险标签,进一步防范恶意脚本;
3.定期清理恶意评论:定期查看评论列表,排查含恶意脚本的评论,及时删除,降低危害;
4.启用内容审核:新增评论需经过超级管理员审核后才能显示,防止恶意脚本被存储和执行。

步骤4:验证修复效果

1.XSS脚本测试:输入含XSS脚本的评论者名称或评论内容,保存后查看,脚本被转义显示(如 <script> 显示为文本),未执行,修复生效;
2.低权限账号测试:使用无评论管理权限的账号登录,尝试操作评论,提示「无权限操作」,修复生效;
3.空值测试:尝试提交空评论者名称或空内容,提示「不能为空」,修复生效;
4.正常操作测试:新增、编辑、查看合法评论,可正常操作和显示,说明功能未受影响;
5.日志测试:查看后台操作日志,可看到评论操作记录,修复生效。

四、注意事项

  • 该漏洞可导致管理员Cookie被劫持、后台被控制,修复后务必全面测试,确保XSS脚本无法执行;
  • 若网站前台也有评论功能,需同步对前台评论参数进行过滤和转义,避免出现前台XSS漏洞;
  • 修复后需检查历史评论,排查是否已存在含恶意脚本的评论,及时删除,防止管理员查看时被攻击;
  • 定期查看评论操作日志,排查异常评论操作,若发现可疑记录,及时排查是否有攻击者利用漏洞;
  • 若修复后出现评论无法保存、显示异常的情况,可恢复备份文件,检查代码修改是否有误,或联系技术人员协助排查。

本文由 流觞运维 原创整理,如需 DedeCMS 该漏洞代修复、全站点漏洞扫描、安全加固、挂马清理服务,可联系微信:lnmp_wuyi(备注:dede修复)

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇