刚才访问博客又出现了 502 超时的错误提示,进后台一看卡的要死,CPU 和内存都爆满,看了下网站日志,原来是有人恶意搜索。无论是想利用搜索提交到搜索引擎还是什么原因,都导致了站点服务器资源的大量占用……看了一下 IP 地域,有全国各地的请求,并且绕过了我在 CDN 中的/?s=的人机匹配规则,那么我就在此基础上,再增加一部分防御,供小伙伴们参考。
相关阅读

考虑到这些恶意搜索的内容都比较长,而我们真实搜索往往字数很少,所以进行了限制搜索内容的长度,同时现在某些人为了绕过某些恶意关键词匹配,又会在词语中加特殊符号对关键词进行分隔,所以将特殊符号也进行拦截。我又将 WordPress 评论里的关键词黑名单词汇进行调用,单反搜索的时候匹配到这些恶意关键词,就返回 404;考虑到每次搜索都要进行关键词匹配,我又使用了 WordPress 自带的对象缓存(Object Cache)解决这个问题,避免 CPU 和数据库的打量占用。
这里还是利用functions.php函数去实现功能
/**
* 限制搜索关键词:拦截特殊符号 + 限制中英文长度 + 拦截评论黑名单(内存缓存优化版)
*/
function limit_search_query_length() {
if ( ! is_search() ) {
return;
}
$search_query = get_search_query();
if ( empty( $search_query ) ) {
return;
}
$has_special_chars = preg_match('/[^\x{4e00}-\x{9fa5}a-zA-Z0-9\s]/u', $search_query);
$chinese_char_count = preg_match_all('/[\x{4e00}-\x{9fa5}]/u', $search_query);
$english_char_count = preg_match_all('/[a-zA-Z]/', $search_query);
$total_length = $chinese_char_count + $english_char_count;
$max_chinese_chars = 6; // 中文最大字数限制
$max_mixed_length = 15; // 中英文混合最大总长度限制
$has_blacklist_word = false;
$blacklist_array = wp_cache_get( 'search_blacklist_array', 'options' );
if ( $blacklist_array === false ) {
$blacklist = get_option( 'disallowed_keys' );
if ( empty( $blacklist ) ) {
$blacklist = get_option( 'blacklist_keys' );
}
if ( ! empty( $blacklist ) ) {
$blacklist_array = array_filter( array_map( 'trim', explode( "\n", $blacklist ) ) );
} else {
$blacklist_array = array();
}
wp_cache_set( 'search_blacklist_array', $blacklist_array, 'options' );
}
if ( ! empty( $blacklist_array ) ) {
$pattern = '/' . implode( '|', array_map( 'preg_quote', $blacklist_array ) ) . '/iu';
if ( preg_match( $pattern, $search_query ) ) {
$has_blacklist_word = true;
}
}
if ( $has_special_chars || $chinese_char_count > $max_chinese_chars || $total_length > $max_mixed_length || $has_blacklist_word ) {
global $wp_query;
$wp_query->set_404();
status_header( 404 );
get_template_part( 404 );
exit();
}
}
add_action( 'template_redirect', 'limit_search_query_length' );
结语
在构思上,构建了三道坚固的防线。
- 首先,它采用严格的“白名单机制”,仅允许用户输入中文、英文、数字和空格,任何包含特殊符号的请求都会被直接拦截。
- 其次,它支持灵活的字数限制,能够独立限制中文字数(如 6 个字)和中英文混合总长度(如 15 个字),有效阻断长串无意义字符的堆砌。
- 最重要的是,我调用了 WordPress 后台的“评论黑名单(disallowed_keys)”作为搜索屏蔽词库,实现了一处配置、全局生效的便捷管理。

在性能优化方面,缙哥哥放弃了传统黑名单匹配带来的数据库和 CPU 负担,它利用了 WordPress 内置的内存缓存 API(wp_cache),将黑名单数据在首次请求时解析并缓存于内存中,避免了重复的数据库查询与字符串分割操作。同时,代码摒弃了低效的循环遍历,采用正则表达式(preg_match)进行批量匹配,借助底层 C 语言引擎实现毫秒级的词汇扫描。此外,代码还加入了短路机制,一旦命中拦截条件便立即终止后续计算。
那么结合缙哥哥之前 CDN 里的搜索请求的人机验证匹配,应该能一定程度上缓解恶意搜索带来的问题,希望我的思路能为你所用!














