ThinkPHP的安全注意事项
发布时间 - 2019-12-16 00:00:00 点击率:次本文主要和大家探讨一下ThinkPHP的安全注意事项,可以作为ThinkPHP建议的安全规范实践。
首先,没有绝对的安全,只要你有足够的安全意识才能尽可能的杜绝安全隐患。规范的使用框架,能让你尽量避免一些看起来比较幼稚的安全问题。本文描述的安全注意事项主要是指生产环境下面的安全策略,本地开发的情况下有时候为了调试的需要安全并不是第一考虑。
ThinkPHP在考虑开发体验的同时,仍然十分重视框架的底层安全,虽然屡有安全漏洞被播报,但官方都是第一时间进行修复处理,而且大部分漏洞只要开发者有一定的安全意识都是可以避免的,今年也和国内的几个安全团队建立了合作关系,有助于提前发现和及时修正框架可能被利用的漏洞或者隐患。
规范部署
这一点很多开发者不是特别重视,安全是一个整体性的问题,任何一个环节出问题,带来的后果都是一样的严重,部署的安全策略是一个基础安全问题。
很多开发者往往不按照官方的部署规范进行部署,请务必把你的WEB根目录指向public目录而不是应用根目录,并且不要随意更改入口文件的位置。public目录下面不要放除了入口文件和资源文件以外的其它应用文件。
关闭调试模式
在部署到生产环境的时候,确保你已经关闭了调试模式,可以通过修改环境变量的方式关闭调试模式。
APP_DEBUG=false
无论是本地开发还是生产环境部署,都不建议直接通过修改配置文件的方式开启/关闭调试模式,而应该使用环境变量(本地开发可以通过定义.env文件)。
关闭调试模式后,系统的健康状态和运行监控主要依靠日志或者你使用的监控服务。所以,要养成定时检查日志和运行状态的习惯。
请求变量过滤
永远不要相信用户的输入,这是一句至理名言。尽可能的过滤请求变量能有效防范大部分的漏洞和隐患。
框架建议的获取请求变量的方法是Request类的param方法(如非必要不要再使用get或者post方法获取,更不要使用原生的$_GET/$_POST等方法获取)。
public function index(Request $request)
{
$name = $request->param('name');
// 在这里可以根据你的业务需求进行更严谨的过滤
// 例如 $name = $request->param('name','','htmlentities,strtolower');
// 或者使用验证器进行专门的验证
}对于有明确类型的请求变量,可以在使用param方法的时候使用类型强制转换,例如:
public function index(Request $request)
{
// 强制转换字符串数据
$name = $request->param('name/s');
// 强制转换整型数据
$name = $request->param('id/d');
// 强制转换浮点型数据
$name = $request->param('score/f');
}或者直接使用方法参数获取请求变量
public function index(string $name)
{
// 在这里可以根据你的业务需求进行更严谨的过滤
// 或者使用验证器进行专门的验证
}如果你需要对所有数据进行处理,可以设置全局的过滤方法。对不同的应用需求设置default_filter过滤规则(默认没有任何过滤规则),常见的安全过滤函数包括stripslash
es、htmlentities、htmlspecialchars和strip_tags等,请根据业务场景选择最合适的过滤方法。
如果需要获取多个数据,建议使用only方法指定需要获取的变量名称,避免有些不怀好意的数据提交导致权限问题。
public function index(Request $request)
{
// 指定表单数据名称
$data = $request->only(['name','title']);
}当你使用数据库或者模型操作写入数据的时候,也可以指定字段,避免非法和不希望的字段写入数据库。
// 模型
User::allowField(['name','title'])
->save($data);
// 数据库
Db::name('user')
->field(['name','title'])
->insert($data);模型还有一个只读字段的功能能避免你的数据受到外部的修改。
上传检测
网站的上传功能也是一个非常容易被攻击的入口,所以对上传功能的安全检查是尤其必要的。
系统的think\File类提供了文件上传的安全支持,包括对文件后缀、文件类型、文件大小以及上传图片文件的合法性检查,确保你已经在上传操作中启用了这些合法性检查,可以参考手册的上传章节。
SQL注入
ThinkPHP的查询统一使用了PDO的prepare预查询和参数绑定机制,能有效的避免SQL注入的发生。但不代表绝对安全,如果你缺乏良好的代码规范,仍然有可能被利用。
一个最简单的原则就是不要让用户决定你的查询条件(或者字段排序)和控制你的查询数据。
对于一些字符串的查询条件(包括原生查询)或者特殊的查询(包括ORDER部分),需要手动进行参数绑定。
// 错误的
Db::query("select * from think_user where id=$id AND status=$statis");
// 正确的
Db::query("select * from think_user where id=? AND status=?", [ $id, $status]);
// 正确的
Db::execute("update think_user set name=:name where status=:status", [
'name' => 'thinkphp',
'status' => 1
]);对于使用了whereExp和whereRaw方式的查询,你也需要使用参数绑定。
Db::name('user')
->whereRaw('id > ? AND status = ?',[10, 1])
->select();使用验证器
对于大量的表单需要验证的情况,建议使用验证器功能统一进行数据的合规验证。验证器的验证操作应该在控制器或者路由阶段使用validate方法进行处理,模型的数据验证功能新版已经取消不再建议使用,模型和数据库操作的时候应该传入经过安全处理过的数据。
XSS攻击
跨站脚本攻击(cross-site scripting,简称 XSS),XSS是一种在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。
在渲染输出的页面中,要对一些数据进行安全处理,防止被恶意利用造成XSS攻击,如果是5.1版本的话,所有的输出都已经经过了htmlentities 转义输出,确保安全。如果是5.0版本的话,你可以自定义一个xss过滤函数,在模板文件中对一些关键内容变量进行函数处理。
CSRF
CSRF 跨站请求伪造是 Web 应用中最常见的安全威胁之一,攻击者伪造目标用户的HTTP请求,然后此请求发送到有CSRF漏洞的网站,网站执行此请求后,引发跨站请求伪造攻击。攻击者利用隐蔽的HTTP连接,让目标用户在不注意的情况下单击这个链接,由于是用户自己点击的,而他又是合法用户拥有合法权限,所以目标用户能够在网站内执行特定的HTTP链接,从而达到攻击者的目的。
开启表单令牌验证,尽量开启强制路由并严格规范每个URL请求,定义单独的MISS路由规则。
遵循请求类型的使用规范并做好权限验证,删除操作必须使用DELETE请求,数据更改操作必须使用POST、PUT 或者 PATCH 请求方法,GET请求不应该更改任何数据。
会话劫持
会话劫持是指攻击者利用各种手段来获取目标用户的session id。一旦获取到session id,那么攻击者可以利用目标用户的身份来登录网站,获取目标用户的操作权限。
有效的防护策略包括:
在每次会话启动的时候,调用regenerate方法。
Session::start(); Session::regenerate(true);
更改session配置参数,开启安全选项:
'use_trans_sid' => 0, 'httponly' => true, 'secure' => true,
升级到安全版本
官方会对一些安全隐患和潜在漏洞进行修复,并且发布一个更为安全的版本。请确认你升级到更安全的版本,确保底层的安全和健壮性。
目前各个版本的建议版本如下:
业务逻辑安全
这个属于应用层面的安全,很多漏洞源于某个业务逻辑自身的安全隐患,包括没有做合理的数据验证和权限检查,尤其是涉及资金及财务层面的,一定要做更多的安全检查,并且开启事务。一个好的建议是更多的对应用进行分层设计,减少每层的复杂性,独立的分层设计便于提高安全性。
服务器安全
最后一点是运维阶段需要特别注意的,及时更新服务器的安全补丁,确保没有可利用的公开系统漏洞,包括你的数据库系统安(尤其是数据备份工作)。
PHP中文网,有大量免费的ThinkPHP入门教程,欢迎大家学习!
本文转自:https://blog.thinkphp.cn/789333
# thinkphp
# 上传
# 都是
# 是一个
# 表单
# 绑定
# 如果你
# 在这里
# 尤其是
# 可以通过
# 你已经
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel如何使用缓存系统提升性能_Laravel缓存驱动和应用优化方案
网易LOFTER官网链接 老福特网页版登录地址
Laravel如何生成和使用数据填充?(Seeder和Factory示例)
如何在阿里云虚拟主机上快速搭建个人网站?
C#如何调用原生C++ COM对象详解
,网页ppt怎么弄成自己的ppt?
利用 Google AI 进行 YouTube 视频 SEO 描述优化
黑客入侵网站服务器的常见手法有哪些?
如何在万网自助建站中设置域名及备案?
JavaScript模板引擎Template.js使用详解
网站制作壁纸教程视频,电脑壁纸网站?
夸克浏览器网页跳转延迟怎么办 夸克浏览器跳转优化
如何在云指建站中生成FTP站点?
Laravel如何实现模型的全局作用域?(Global Scope示例)
Win11怎么设置虚拟桌面 Win11新建多桌面切换操作【技巧】
phpredis提高消息队列的实时性方法(推荐)
Laravel如何使用Gate和Policy进行授权?(权限控制)
如何挑选最适合建站的高性能VPS主机?
Laravel如何实现API资源集合?(Resource Collection教程)
Laravel如何实现邮箱地址验证功能_Laravel邮件验证流程与配置
怎么用AI帮你为初创公司进行市场定位分析?
Gemini怎么用新功能实时问答_Gemini实时问答使用【步骤】
如何确保FTP站点访问权限与数据传输安全?
详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)
Laravel怎么上传文件_Laravel图片上传及存储配置
iOS发送验证码倒计时应用
Laravel如何安装Breeze扩展包_Laravel用户注册登录功能快速实现【流程】
如何制作一个表白网站视频,关于勇敢表白的小标题?
重庆市网站制作公司,重庆招聘网站哪个好?
HTML5建模怎么导出为FBX格式_FBX格式兼容性及导出步骤【指南】
Laravel如何实现用户角色和权限系统_Laravel角色权限管理机制
Android实现代码画虚线边框背景效果
Laravel事件监听器怎么写_Laravel Event和Listener使用教程
Laravel如何实现密码重置功能_Laravel密码找回与重置流程
三星网站视频制作教程下载,三星w23网页如何全屏?
实例解析Array和String方法
JavaScript如何实现音频处理_Web Audio API如何工作?
Laravel Facade的原理是什么_深入理解Laravel门面及其工作机制
Laravel怎么生成URL_Laravel路由命名与URL生成函数详解
Gemini手机端怎么发图片_Gemini手机端发图方法【步骤】
如何在宝塔面板中创建新站点?
php8.4header发送头信息失败怎么办_php8.4header函数问题解决【解答】
免费网站制作appp,免费制作app哪个平台好?
魔方云NAT建站如何实现端口转发?
大连网站制作公司哪家好一点,大连买房网站哪个好?
Laravel如何获取当前用户信息_Laravel Auth门面获取用户ID
如何在万网ECS上快速搭建专属网站?
html5audio标签播放结束怎么触发事件_onended回调方法【教程】
Win11摄像头无法使用怎么办_Win11相机隐私权限开启教程【详解】
Laravel Seeder填充数据教程_Laravel模型工厂Factory使用


es、htmlentities、htmlspecialchars和strip_tags等,请根据业务场景选择最合适的过滤方法。