web安全建议
以下是将 HTML 内容完整转换为 Markdown 的结果,已按照规范调整格式并确保结构正确:
一、开始前的一些建议
- 不要相信任何用户输入或第三方数据来源,包括
$_GET、$_POST($_FILES)、$_COOKIE、$_SERVER的部分参数等。 - HTML、PHP、MYSQL等使用统一的UTF-8编码。
- 数据库SQL构造时尽量使用’包裹参数。
- 参数对比时正确使用
===和==。 - 尽量选择白名单而非黑名单式过滤。
二、关于SQL注入
1.SQL注入的产生原因
SQL注入的产生在于外界的输入改变了原本定义的SQL语意,譬如:
原本定义的SQL语意:
$_GET['name'] = 'abc';
$name = $_GET['name'];
SELECT * FROM admin where user_name = '$name';
最终生成的SQL为:
SELECT * FROM admin where user_name = 'abc';
外界输入改变后的语意:
$_GET['name'] = 'abc\' or \'a\'=\'a';
$name = $_GET['name'];
SELECT * FROM admin where user_name = '$name';
最终生成的SQL为:
SELECT * FROM admin where user_name = 'abc' or 'a'='a';
此时SQL的语意多加了原定之外的 or 'a'='a',于是注入产生。
2.SQL注入的防御
(1)使用PDO或mysqli预编译处理SQL
使用预处理语句时,PHP请求MySQL将SQL进行预编译,然后再发送参数,因此无论参数是何内容MySQL均将参数当作普通的字符串(或整型、浮点型)处理。
例如上一例子最终生成的SQL为:
SELECT * FROM admin where user_name = 'abc\' or \'a\'=\'a';
此时无法发生SQL语意的改变,故能防止SQL注入。
注意:PDO兼容大部分数据库,但需要PHP版本5.0+;mysqli只支持MySQL数据库并且需要MySQL数据库版本4.1.13+(服务端版本5.0.7+)。
(2)无法使用预编译时的替代方案
使用 addslashes 而非 mysql_real_escape_string 作为临时安全过滤函数,对于参数类型为整型时使用 intval 将变量转换成整型。
特殊场景:在GBK字符集环境下,
0xbf27经过addslashes转义后得到0xbf5c27,数据库将0xbf5c当作单字节字符而剩余的27则被当作'解析,故而仍能造成SQL注入。
版本差异:旧版PHP中
mysql_real_escape_string必须在数据库连接后使用;新版PHP虽不再强制要求,但会抛出警告。
三、关于XSS
1.XSS产生的原因
正如《白帽子讲web安全》中所说:XSS本质是“HTML注入”,用户的数据被当成了HTML代码的一部分来执行。例如:
原始逻辑:
$_GET['page'] = 1;
$page = $_GET['page'];
<a href="http://www.xxx.com/?page=$page">xss</a>
最终生成:
<a href="http://www.xxx.com/?page=1">xss</a>
攻击输入:
$_GET['page'] = '1" onclick="alert(1)">';
$page = $_GET['page'];
<a href="http://www.xxx.com/?page=$page">xss</a>
最终生成:
<a href="http://www.xxx.com/?page=1" onclick="alert(1)">xss</a>
2.XSS的防御
(1)普通HTML输出
使用 htmlspecialchars 进行安全过滤。
(2)链接类型输出
- 使用
htmlspecialchars; - 检查URL是否以
http或https开头,避免伪协议攻击(如:data:text/html;base64,...)。
注意:
htmlentities仅在使用ASCII/LATIN-1编码时需要,它会过度转义安全字符。htmlspecialchars不会转义\',因此属性值需用双引号包裹。
(3)富文本处理
采用白名单模式放行安全标签及属性,针对性过滤高危标签。
四、关于CSRF
1.CSRF产生的原因
攻击源以用户身份伪造请求,例如:
<img src="http://b.com?action=del&id=1">
用户访问a.com时,浏览器会携带b.com的Cookie发起删除请求,完成非用户主动操作的敏感行为。
2.CSRF的防御
(1)Anti CSRF Token
对敏感操作(增删改查)使用随机Token验证。
注意事项:
- Token必须足够随机;
- 验证后立即删除Token;
- 优先通过POST提交Token以避免泄露。
五、关于文件上传
1.漏洞原因
用户上传了Web容器可解析的非允许类型文件(如PHP脚本),导致远程代码执行。
2.防御措施
(1)严格白名单验证
- 结合MIME Type和文件后缀检查;
- 不可信来源:
$_FILES['file']['type']可被客户端篡改。
(2)安全文件名处理
- 使用随机文件名;
- 避免空字符截断(如
xxx.php\0.jpg在低版本PHP中被保存为xxx.php)。
六、关于代码执行漏洞
1.漏洞原因
危险函数(如 eval)执行了用户可控的代码。例如:
$_GET['test'] = 'phpinfo()';
eval($test); // 直接执行phpinfo()
2.防御措施
(1)白名单限制
对用户输入严格校验,禁用动态代码执行函数。
(2)正则表达式安全
- 用
preg_replace_callback替代/e模式; - 严格控制正则匹配内容。
注意:
eval是Zend函数,无法通过disable_functions禁用,需使用第三方插件。
七、关于重放攻击
1.攻击原理
攻击者重复发送合法请求以欺骗服务器,例如:
http://www.abc.com/index.php?action=alterPassword&uid=123456&token=123
目标服务器仅验证Token有效性,导致密码被重复修改。
2.防御措施
(1)请求签名与时间戳
- 对所有参数进行签名防止篡改;
- 添加时间戳判断请求是否过期。
以上内容已完整转换为Markdown格式,保留了代码块、注意事项和层级结构。