如何高效过滤织梦搜索字符串?

99ANYc3cd6
预计阅读时长 24 分钟
位置: 首页 织梦建站 正文

核心方法:使用 dede_filterSearch() 函数

织梦CMS在处理搜索时,已经内置了一个核心的安全过滤函数 dede_filterSearch(),这个函数位于 /include/arc.searchview.class.php 文件中,是所有搜索操作的第一道防线。

织梦 过滤搜索字符串
(图片来源网络,侵删)

函数定义:

function dede_filterSearch($keyword)
{
    $keyword = preg_replace("#\"#", "", $keyword);
    $keyword = htmlspecialchars($keyword);
    return $keyword;
}

分析这个函数做了什么:

  1. preg_replace("#\"#", "", $keyword);:移除搜索关键词中的双引号 (),双引号在某些数据库查询中可能会被用来闭合引号,是SQL注入的常见手段。
  2. htmlspecialchars($keyword);:将特殊字符转换为HTML实体。
    • & -> &
    • -> "
    • -> '
    • < -> &lt;
    • > -> &gt;
    • 这一步是防止XSS攻击的关键,确保用户输入的脚本代码不会被浏览器执行。

如何应用: 你不需要手动调用这个函数,织梦的搜索模块在处理关键词时,会自动调用它,但如果你要开发自己的搜索功能或修改搜索逻辑,就应该在获取关键词后立即调用它。

// 假设 $keyword 是从 $_GET['q'] 获取的用户输入
$keyword = isset($_GET['q']) ? trim($_GET['q']) : '';
// 使用织梦内置函数进行过滤
$filtered_keyword = dede_filterSearch($keyword);
// 现在可以使用 $filtered_keyword 进行安全的数据库查询或其他操作

高级过滤与自定义规则

dede_filterSearch() 函数虽然基础,但可能无法满足所有场景,你可能需要:

织梦 过滤搜索字符串
(图片来源网络,侵删)
  • 过滤掉一些特定的非法词语。
  • 限制关键词的长度。
  • 防止SQL注入的更高级形式。

你可以通过以下两种方式实现更高级的过滤。

方法1:修改 dede_filterSearch() 函数(不推荐,但有效)

直接编辑 /include/arc.searchview.class.php 文件,修改 dede_filterSearch() 函数,添加你自己的过滤规则。

示例:添加非法词过滤和长度限制

// 在 /include/arc.searchview.class.php 中找到这个函数并替换
function dede_filterSearch($keyword)
{
    // 1. 原始过滤
    $keyword = preg_replace("#\"#", "", $keyword);
    $keyword = htmlspecialchars($keyword);
    // 2. 自定义过滤:定义非法词列表
    $banned_words = array('垃圾', '广告词', '违规内容');
    foreach ($banned_words as $word) {
        $keyword = str_replace($word, '***', $keyword);
    }
    // 3. 自定义过滤:限制关键词长度
    if (mb_strlen($keyword, 'UTF-8') > 20) {
        $keyword = mb_substr($keyword, 0, 20, 'UTF-8');
        // 可以在这里记录日志,提示用户关键词过长
        // showMsg('搜索关键词过长,已自动截取', '-1');
        // exit();
    }
    return $keyword;
}

⚠️ 注意:

织梦 过滤搜索字符串
(图片来源网络,侵删)
  • 直接修改核心文件在织梦升级后会被覆盖,需要重新修改。
  • 修改前务必备份原文件。

方法2:在搜索处理文件中添加自定义过滤(推荐)

这是更安全、更灵活的方法,织梦的搜索请求通常由 plus/search.php 处理,你可以在这里添加自己的过滤逻辑,然后再调用织梦的核心搜索功能。

步骤:

  1. 打开搜索处理文件/plus/search.php
  2. 找到关键词获取位置:在文件中找到类似 $q = trim($_GET['q']); 的代码。
  3. 添加自定义过滤逻辑:在获取关键词后,添加你自己的过滤代码。

示例:在 plus/search.php 中添加高级过滤

<?php
require_once(dirname(__FILE__)."/../include/config_base.php");
require_once(DEDEINC.'/arc.search.class.php');
// 1. 获取用户输入的关键词
$q = isset($_GET['q']) ? trim($_GET['q']) : '';
// 2. 【自定义】开始进行高级过滤
if (!empty($q)) {
    // a. 非法词过滤
    $banned_words = array('垃圾', '广告词', '违规内容');
    foreach ($banned_words as $word) {
        if (strpos($q, $word) !== false) {
            die('搜索内容包含非法词语,已被系统拦截!');
        }
    }
    // b. 长度限制
    if (mb_strlen($q, 'UTF-8') > 20) {
        $q = mb_substr($q, 0, 20, 'UTF-8');
        // 也可以选择跳转到错误页面
        // ShowMsg('搜索关键词过长,已自动截取', 'javascript:history.go(-1);');
        // exit();
    }
    // c. 更严格的正则表达式过滤(防止SQL注入和特殊字符)
    // 只允许中文字符、英文字母、数字和常见符号
    if (!preg_match("/^[\x{4e00}-\x{9fa5}a-zA-Z0-9\s\.\+\-\*\(\)\[\]\{\}\?\!\@\#\$\%\^\&\_\~\|]+$/u", $q)) {
        die('搜索内容包含非法字符,请重新输入!');
    }
}
// 【自定义】过滤结束
// 3. 调用织梦内置的过滤函数(双重保险)
$q = dede_filterSearch($q);
// ... 后续代码保持不变,将过滤后的 $q 传给搜索类 ...
$typeid = isset($typeid) && is_numeric($typeid) ? $typeid : 0;
$mid = isset($mid) && is_numeric($mid) ? $mid : 0;
$mobile = isset($mobile) ? $mobile : '';
$searchtype = isset($searchtype) ? $searchtype : 'titlekeyword';
$channelid = empty($channelid) ? 0 : intval($channelid);
// 实例化搜索类
$sp = new Search($q, $typeid, $searchtype, $channelid, $mid, $mobile);
$sp->IsError = true;
$sp->PageSize = 10;
// 获得搜索结果的HTML代码
$artlist = $sp->GetResultlist('artlist');
// ... 后续代码 ...

完整实例:创建一个安全的搜索页面

假设你想创建一个自定义的搜索页面,而不是使用默认的 plus/search.php

  1. 创建模板文件 templets/default/mysearch.htm

    <form action="/mysearch.php" method="get">
        <input type="text" name="q" placeholder="请输入搜索关键词">
        <button type="submit">搜索</button>
    </form>
  2. 创建处理文件 mysearch.php (放在网站根目录)

    <?php
    require_once('include/config_base.php'); // 引入织梦基础配置
    require_once(DEDEINC.'/arc.search.class.php');
    // 1. 获取并过滤关键词
    $keyword = isset($_GET['q']) ? trim($_GET['q']) : '';
    // 如果关键词为空,可以跳转到首页或显示提示
    if (empty($keyword)) {
        ShowMsg('请输入搜索关键词', '/');
        exit();
    }
    // 2. 【核心安全过滤】使用织梦内置函数
    $safe_keyword = dede_filterSearch($keyword);
    // 3. 【可选】自定义额外过滤
    // 过滤掉SQL关键字
    $sql_keywords = array('select', 'insert', 'update', 'delete', 'union', 'script', 'iframe');
    foreach ($sql_keywords as $sql_word) {
        if (stripos($safe_keyword, $sql_word) !== false) {
            die('您的输入可能包含不安全内容,搜索已终止。');
        }
    }
    // 4. 使用过滤后的关键词进行搜索
    $typeid = 0; // 所有栏目
    $searchtype = 'titlekeyword'; // �标题和关键词搜索
    $channelid = 0; // 所有模型
    $mid = 0; // 所有会员
    $mobile = '';
    // 实例化搜索类
    $search = new Search($safe_keyword, $typeid, $searchtype, $channelid, $mid, $mobile);
    $search->PageSize = 10; // 每页显示10条
    $search->IsError = true; // 开启错误提示
    // 获取分页和结果列表
    $geturl = "mysearch.php?q=".urlencode($safe_keyword); // 搜索页URL
    $pagelist = $search->GetPageList($geturl);
    $artlist = $search->GetResultlist('artlist'); // 使用默认的搜索结果列表模板
    // 5. 输出结果
    $dtp = new DedeTagParse();
    $dtp->LoadTemplate($templet);
    $dtp->Assign('artlist', $artlist);
    $dtp->Assign('pagecount', $search->GetPageCount());
    $dtp->Assign('pagelist', $pagelist);
    $dtp->Display();
    ?>
方法 优点 缺点 适用场景
dede_filterSearch() 官方内置,基础安全,无需修改 功能单一,无法满足复杂需求 默认搜索,或对安全要求不高的场景。
修改核心函数 能统一处理所有搜索请求 升级后会被覆盖,维护成本高 有特殊且固定的过滤需求,且不介意修改核心文件。
在处理文件中自定义 灵活、安全、可维护,不影响核心文件 需要手动在特定文件中添加代码 强烈推荐,无论是修改默认搜索还是开发新搜索功能,都应采用此方法。

最佳实践建议:

  1. 始终使用 dede_filterSearch() 作为基础过滤。
  2. 在搜索请求的入口文件(如 plus/search.php 或你自定义的处理文件中)添加自定义的过滤规则,如非法词、长度限制、正则表达式等。
  3. 对所有来自用户输入的数据($_GET, $_POST, $_REQUEST)保持警惕,不要直接用于数据库查询。

通过以上组合,你可以为你的织梦网站构建一个既安全又灵活的搜索系统。

-- 展开阅读全文 --
头像
织梦账户密码怎么修改?
« 上一篇 今天
织梦友情链接图片文字如何设置?
下一篇 » 今天

相关文章

取消
微信二维码
支付宝二维码

目录[+]