开发中php安全性考虑哪些( 二 )

<?php
//用户输入的数据
$name = 'admin';
$pass = '123456';
//首先新建mysqli对象,构造函数参数中包含了数据库相关内容 。
$conn = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT);
//设置sql语句默认编码
$this->mysqli->set_charset("utf8");
//创建一个使用通配符的sql语句
$sql = 'SELECT user_id FROM admin WHERE username=? AND password=?;';
//编译该语句 , 得到一个stmt对象.
$stmt = $conn->prepare($sql);
/********************之后的内容就能重复利用 , 不用再次编译*************************/
//用bind_param方法绑定数据
//大家可以看出来 , 因为我留了两个? , 也就是要向其中绑定两个数据 , 所以第一个参数是绑定的数据的类型(s=string,i=integer) , 第二个以后的参数是要绑定的数据
$stmt->bind_param('ss', $name, $pass);
//调用bind_param方法绑定结果(如果只是检查该用户与密码是否存在 , 或只是一个DML语句的时候 , 不用绑定结果)
//这个结果就是我select到的字段 , 有几个就要绑定几个
$stmt->bind_result($user_id);
//执行该语句
$stmt->execute();
//得到结果
if($stmt->fetch()){
echo '登陆成功';
//一定要注意释放结果资源 , 否则后面会出错
$stmt->free_result();
return $user_id; //返回刚才select到的内容
}else{echo '登录失败';}
?>
3、预防XSS代码 , 如果不需要使用cookie就不使用
在我的网站中并没有使用cookie , 更因为我对权限限制的很死 , 所以对于xss来说危险性比较小 。
对于xss的防御 , 也是一个道理 , 处理好“代码”和“数据”的关系 。当然 , 这里的代码指的就是JAVAscript代码或html代码 。用户能控制的内容 , 我们一定要使用htmlspecialchars等函数来处理用户输入的数据 , 并且在JavaScript中要谨慎把内容输出到页面中 。
4、限制用户权限 , 预防CSRF
现在脚本漏洞比较火的就是越权行为 , 很多重要操作使用GET方式执行 , 或使用POST方式执行而没有核实执行者是否知情 。
CSRF很多同学可能比较陌生 , 其实举一个小例子就行了:
A、B都是某论坛用户 , 该论坛允许用户“赞”某篇文章 , 用户点“赞”其实是访问了这个页面:http://localhost/?act=support&articleid=12 。这个时候 , B如果把这个URL发送给A , A在不知情的情况下打开了它 , 等于说给articleid=12的文章赞了一次 。
所以该论坛换了种方式 , 通过POST方式来赞某篇文章 。
<form action="http://localhost/?act=support" method="POST">
<input type="hidden" value=https://www.isolves.com/it/cxkf/yy/php/2019-09-10/"12" name="articleid">
<input type="submit" value=https://www.isolves.com/it/cxkf/yy/php/2019-09-10/"赞">
</form>
可以看到一个隐藏的input框里含有该文章的ID , 这样就不能通过一个URL让A点击了 。但是B可以做一个“极具诱惑力”的页面 , 其中某个按钮就写成这样一个表单 , 来诱惑A点击 。A一点击 , 依旧还是赞了这篇文章 。
最后 , 该论坛只好把表单中增加了一个验证码 。只有A输入验证码才能点赞 。这样 , 彻底死了B的心 。
但是 , 你见过哪个论坛点“赞”也要输入验证码?
所以吴翰清在白帽子里也推荐了最好的方式 , 就是在表单中加入一个随机字符串token(由php生成 , 并保存在SESSION中) , 如果用户提交的这个随机字符串和SESSION中保存的字符串一致 , 才能赞 。
在B不知道A的随机字符串时 , 就不能越权操作了 。
我在网站中也多次使用了TOKEN , 不管是GET方式还是POST方式 , 通常就能抵御99%的CSRF估计了 。
5、严格控制上传文件类型
上传漏洞是很致命的漏洞 , 只要存在任意文件上传漏洞 , 就能执行任意代码 , 拿到webshell 。
我在上传这部分 , 写了一个php类 , 通过白名单验证 , 来控制用户上传恶意文件 。在客户端 , 我通过javascript先验证了用户选择的文件的类型 , 但这只是善意地提醒用户 , 最终验证部分 , 还是在服务端 。


推荐阅读