Laravel中whereFullText布尔模式下的客户端查询注入防护问题
解决Laravel whereFullText布尔模式下的SQL注入问题
问题原因
MySQL全文搜索的boolean模式支持特殊操作符(如--、+、-等),其中--会被当作全文查询内的注释起始符。如果用户输入包含这类字符的恶意载荷(比如asd--),会导致后续的全文查询内容被截断,甚至因拼接方式不当引发SQL注入风险。Laravel的whereFullText方法在boolean模式下不会自动转义这些特殊字符,因此需要手动处理。
解决方案
1. 转义布尔模式的特殊字符
编写辅助函数,对输入关键词中的MySQL全文布尔模式特殊字符进行转义,让MySQL将它们视为普通文本而非操作符/注释:
/** * 转义MySQL全文搜索布尔模式的特殊字符 * @param string $query 用户输入的搜索关键词 * @return string 转义后的关键词 */ function escapeFullTextBoolean(string $query): string { // MySQL布尔全文搜索的特殊操作符列表 $specialChars = ['+', '-', '<', '>', '(', ')', '~', '*', '"', '@', '#', '--']; foreach ($specialChars as $char) { // 用反斜杠转义特殊字符,使其成为普通文本 $query = str_replace($char, '\\' . $char, $query); } // 若需保留通配符*的功能,可从数组中移除'*' return $query; }
2. 在查询代码中应用转义
修改现有查询逻辑,先对用户输入的search_key做转义处理:
$search_key = $args['q'] ?? $args['search_key'] ?? NULL; $builder->when($search_key, function (Builder $builder, $search_key) { // 转义布尔模式下的特殊字符,避免注释或操作符干扰 $escapedSearchKey = escapeFullTextBoolean($search_key); $builder->whereFullText(self::fullTextColumns(), $escapedSearchKey . self::WILDCARD, [ 'mode' => 'boolean', ]); });
3. 可选:直接过滤特殊操作符(按需使用)
如果业务场景不需要用户使用布尔模式的高级操作符,可以直接过滤掉这些字符:
function sanitizeFullTextBoolean(string $query): string { // 移除所有布尔模式特殊操作符 return preg_replace('/[\+\-\<\>\(\)\~\*\\"@#\-]+/', '', $query); }
额外说明
- 若不需要布尔模式的高级搜索功能(如强制包含/排除关键词),可切换到
natural模式,该模式下MySQL会自动忽略特殊操作符,不会出现此类问题。 - 无论何时,都要确保用户输入被正确处理,避免直接将未过滤的输入拼接到查询中(即使Laravel做了参数绑定,全文搜索的语法层面仍可能存在逻辑风险)。
内容的提问来源于stack exchange,提问作者arya_la
相关产品推荐
相关产品推荐

