PHP过滤HTML字符串与防止SQL注入的方法
在PHP Web开发中,直接操作用户输入数据容易引发XSS或SQL注入攻击。文章详细解析了如何编写自定义函数对GET/POST数据进行递归转义,以及如何通过字符串替换机制清洗HTML标签和SQL关键字,为构建安全的输入过滤层提供参考。
目标与准备
在处理Web请求时,服务器接收到的数据通常经过 addslashes 或魔术引号(已废弃)处理,残留反斜杠可能导致数据解析错误。同时,直接渲染用户提交的HTML内容存在XSS风险,而包含敏感SQL关键字的字符串若未经验证直接拼接到查询语句中,则可能导致SQL注入。我们需要实现两个核心功能:一是清理数组数据中的多余转义字符,二是过滤危险的HTML结构和SQL指令。
递归清理数组数据
为了统一处理GET、POST及Cookie等超全局变量中的数据,可以使用递归函数遍历数组并去除其中的反斜杠。这解决了当魔术引号开启或手动添加转义后,数据中包含"\"字符导致的问题。
第1步:定义递归过滤函数
目的:自动识别数组结构,对非系统保留键名的字符串元素执行 stripslashes 操作。
代码实现:
function stripslashes_array(&$array) {
while(list($key,$var) = each($array)) {
// 排除 argc, argv 等内部变量,且避免数字索引被误判
if ($key != 'argc' && $key != 'argv' && (strtoupper($key) != $key || ''.intval($key) == "$key")) {
if (is_string($var)) {
$array[$key] = stripslashes($var);
}
if (is_array($var)) {
$array[$key] = stripslashes_array($var);
}
}
}
return $array;
}
完成状态:调用该函数并将 $_GET 或 $_POST 传入后,嵌套数组中的字符串将不再包含多余的转义符。
第2步:应用数据清洗
入口:脚本起始位置,接收HTTP请求后。
动作:立即对请求数据源进行清洗。
$_GET = stripslashes_array($_GET);
$_POST = stripslashes_array($_POST);
深度过滤HTML与SQL关键字
除了基础的转义清理,还需要对字符串内容进行更严格的过滤,特别是针对试图闭合HTML标签、引入Script代码或嵌入SQL命令的行为。此函数旨在通过替换机制移除或编码这些潜在危险字符。
第1步:构建过滤逻辑
目的:将HTML实体、特殊符号及部分SQL关键字进行替换或清除。
注意事项:原逻辑中使用 `str_replace` 替换SQL关键字为空或自身是一种简单的策略,但在复杂场景下可能误伤正常业务数据(如用户名包含“select”),建议后续结合参数化查询使用。
function lib_replace_end_tag($str)
{
if (empty($str)) return false;
// 基础HTML实体转换
$str = htmlspecialchars($str);
// 清除特定符号和标签
$str = str_replace( '/', "", $str);
$str = str_replace("\\", "", $str);
$str = str_replace(">", "", $str);
$str = str_replace("<", "", $str);
// 清除Script标签(含大小写混合情况)
$str = str_replace("<SCRIPT>", "", $str);
$str = str_replace("</SCRIPT>", "", $str);
$str = str_replace("<script>", "", $str);
$str = str_replace("</script>", "", $str);
// SQL关键字过滤策略:此处示例为替换为空或保持原样(视具体需求而定,原文逻辑较为混杂)
$sql_keywords = array('select','join','union','where','insert','delete','update',
'like','drop','create','modify','rename','alter','cast');
foreach ($sql_keywords as $kw) {
$str=str_replace($kw,$kw,$str); // 注意:原文此处逻辑为保留,实际防注入需更严格匹配上下文或使用参数化
}
// 特殊字符与换行符处理
$str=str_replace("&","&",$str);
$str=str_replace(">",">",$str);
$str=str_replace("<","<",$str);
$str=str_replace(" ",chr(32),$str);
$str=str_replace(" ",chr(9),$str);
$str=str_replace(" ",chr(9),$str);
$str=str_replace("&",chr(34),$str);
$str=str_replace("'",chr(39),$str);
$str=str_replace("<br />",chr(13),$str);
$str=str_replace("''","'",$str);
// 其他杂项清理
$str=str_replace("css","'",$str);
$str=str_replace("CSS","'",$str);
return $str;
}
重要参数:输入字符串 $str。
可观察的完成状态:返回处理后的字符串,其中部分HTML实体已被转义,特定尖括号内的内容被移除。
第2步:集成使用
操作:在展示用户提交的内容前,先调用此函数进行处理。
$clean_input = lib_replace_end_tag($_POST['user_content']);
echo $clean_input;
排错与注意事项
- SQL注入的根本解决:上述代码仅提供了视图层的过滤思路。最核心的防SQL注入手段是使用PDO或mysqli的预处理语句(Prepared Statements),而非依赖字符串替换。因为正则或replace极易被绕过(如大小写变换、双写绕过等)。
- XSS防护:虽然使用了 htmlspecialchars,但如果数据后续会被JavaScript解析或写入 innerHTML,仍需考虑 CSP (Content Security Policy) 和更全面的输出编码库(如 OWASP Java Encoder 的 PHP 对应方案)。
- 函数性能:大量的 str_replace 连续调用会对性能产生一定影响,对于长文本可以考虑 preg_replace 批量替换以提升效率。
总结
通过编写递归数组清洗函数 stripslashes_array 和针对性的字符串过滤函数 lib_replace_end_tag,可以在PHP应用中建立起一道基础的数据输入防线。前者确保了数据结构的纯净性,后者剔除了明显的恶意HTML标签和潜在的危险字面量。然而,开发者应明确认识到,这些方法属于辅助性防御,在生产环境中务必结合参数化查询和现代Web安全框架的最佳实践来保障数据安全。
以上就是PHP过滤HTML字符串、防止SQL注入方法的详细内容,更多关于PHP开发安全的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









