安全测试(sql注入、xss、csrf)

本文详细介绍了PHP安全配置、数据验证的重要性以及如何防范SQL注入、XSS攻击和CSRF。建议关闭PHP错误显示、禁用魔法引号和全局变量,严格进行数据验证,并提供了防注入的函数和方法。同时,文章还讨论了防止XSS攻击的策略,强调了防止CSRF攻击的必要性,以及防盗链和防止CC攻击的方法。
摘要由CSDN通过智能技术生成
浅谈Php安全和防Sql注入,防止Xss攻击,防盗链,防CSRF
前言:
首先,笔者不是web安全的专家,所以这不是web安全方面专家级文章,而是学习笔记、细心总结文章,里面有些是我们phper不易发现或者说不重视的东西。所以笔者写下来方便以后查阅。在大公司肯定有专门的web安全测试员,安全方面不是phper考虑的范围。但是作为一个phper对于安全知识是:“知道有这么一回事,编程时自然有所注意”。
目录:
 
1、php一些安全配置
(1)关闭php提示错误功能
(2)关闭一些“坏功能”
(3)严格配置文件权限。
2、严格的数据验证,你的用户不全是“好”人
2.1为了确保程序的安全性,健壮性,数据验证应该包括内容。
2.2程序员容易漏掉point或者说需要注意的事项
3、防注入
    3.1简单判断是否有注入漏洞以及原理
    3.2常见的mysql注入语句
        (1)不用用户名和密码
        (2)在不输入密码的情况下,利用某用户
        (3)猜解某用户密码
(4)插入数据时提权
(5)更新提权和插入提权同理
(6)恶意更新和删除
(7)union、join等
(8)通配符号%、_
(9)还有很多猜测表信息的注入sql
    33防注入的一些方法
        2.3.1 php可用于防注入的一些函数和注意事项。
        2.3.2防注入字符优先级。
2.3.3防注入代码
     (1)参数是数字直接用 intval ()函数
     (2)对于非文本参数的过滤
(3)文本数据防注入代码。
(4)当然还有其他与 addslashes 、mysql_escape_string结合的代码。
4、防止xss攻击
4.1Xss攻击过程
4.2常见xss攻击地方
4.3防XSS方法
5、CSRF
5.1简单说明CSRF原理
5.2防范方法
6、防盗链
7、防拒CC攻击
1、php一些安全配置
 
(1)关闭php提示错误功能
在php.ini 中把display_errors改成
复制代码 代码如下:
display_errors = OFF
 
或在php文件前加入
复制代码 代码如下:
error_reporting (0)
1)使用 error_reporting (0);失败的例子:
A文件代码:
复制代码 代码如下:
<? 
error_reporting (0); 
echo  555 
echo  444; 
?>
 
错误:
复制代码 代码如下:
Parse error: parse error, expecting ` ',' ' or `' ; ''  in E:\webphp\2.php on line 4
 
2)使用 error_reporting (0);成功的例子:
a文件代码:
复制代码 代码如下:
 
<?php 
error_reporting (0); 
include ( "b.php" ); 
?>
 
b文件代码:
复制代码 代码如下:
 
<?php 
echo  555 
echo  444; 
?>
 
这是很多phper说用 error_reporting (0)不起作用。第一个例子A.php里面有致命错误,导致不能执行,不能执行服务器则不知有这个功能,所以一样报错。
第二个例子中a.php成功执行,那么服务器知道有抑制错误功能,所以就算b.php有错误也抑制了。
ps:抑制不了mysql错误。
(2)关闭一些“坏功能”
1)关闭magic quotes功能
 
在php.ini 把magic_quotes_gpc = OFF
避免和 addslashes 等重复转义
2)关闭register_globals = Off
在php.ini 把register_globals = OFF
在register_globals = ON的情况下
地址栏目:http: //www.jb51.net?bloger=benwin
复制代码 代码如下:
 
<?php 
//$bloger = $_GET['bloger']   //因为register_globals = ON 所以这步不用了直接可以用$bloger
   echo  $bloger
?>
这种情况下会导致一些未初始化的变量很容易被修改,这也许是致命的。所以把register_globals = OFF关掉
(3)严格配置文件权限。
为相应文件夹分配权限,比如包含上传图片的文件不能有执行权限,只能读取
2、严格的数据验证,你的用户不全是“好”人。
记得笔者和一个朋友在讨论数据验证的时候,他说了一句话:你不要把你用户个个都想得那么坏!但笔者想说的这个问题不该出现在我们开发情景中,我们要做的是严格验证控制数据流,哪怕10000万用户中有一个是坏用户也足以致命,再说好的用户也有时在数据input框无意输入中文的时,他已经不经意变“坏”了。
2.1为了确保程序的安全性,健壮性,数据验证应该包括
(1)     关键数据是否存在。如删除数据id是否存在
(2)     数据类型是否正确。如删除数据id是否是整数
(3)     数据长度。如字段是char(10)类型则要 strlen 判断数据长度
(4)     数据是否有危险字符
数据验证有些人主张是把功能完成后再慢慢去写安全验证,也有些是边开发边写验证。笔者偏向后者,这两种笔者都试过,然后发现后者写的验证相对健壮些,主要原因是刚开发时想到的安全问题比较齐全,等开发完功能再写时有两个问题,一个phper急于完成指标草草完事,二是确实漏掉某些point。
2.2程序员容易漏掉point或者说需要注意的事项:
(1)     进库数据一定要安全验证,笔者在广州某家公司参与一个公司内部系统开发的时候,见过直接把 $_POST 数据传给类函数classFunctionName( $_POST ),理由竟然是公司内部使用的,不用那么严格。暂且不说逻辑操作与数据操控耦合高低问题,连判断都没判断的操作是致命的。安全验证必须,没任何理由推脱。
(2)     数据长度问题,如数据库建表字段char(25),大多phper考虑到是否为空、数据类型是否正确,却忽略字符长度,忽略还好更多是懒于再去判断长度。(这个更多出现在新手当中,笔者曾经也有这样的思想)
(3)     以为前端用js判断验证过了,后台不需要判断验证。这也是致命,要知道伪造一个表单就几分钟的事,js判断只是为了减少用户提交次数从而提高用户体验、减少http请求减少服务器压力,在安全情况下不能防“小人”,当然如果合法用户在js验证控制下是完美的,但作为phper我们不能只有js验证而抛弃再一次安全验证。
(4)     缺少对表单某些属性比如select、checkbox、radio、button等的验证,这些属性在web页面上开发者已经设置定其值和值域(白名单值),这些属性值在js验证方面一般不会验证,因为合法用户只有选择权没修改权,然后phper就在后端接受数据处理验证数据的时候不会验证这些数据,这是一个惯性思维,安全问题也就有了,小人一个伪表单。
(5)     表单相应元素name和数据表的字段名一致,如用户表用户名的字段是user_name,然后表单中的用户名输入框也是user_name,这和暴库没什么区别。
(6)     过滤危险字符方面如防注入下面会独立讲解。
3、防注入
3.1简单判断是否有注入漏洞以及原理。
网址:http: //www.jb51.net/benwin.php?id=1 运行正常,sql语句如:select  *  from phpben where id = 1
(1) 网址:http: //www.jb51.net/benwin.php?id=1'   sql语句如:select  *  from phpben where id = 1'  然后运行异常 这能说明benwin.php文件没有对id的值进行“'” 过滤和intval()整形转换,当然想知道有没有对其他字符如“%”,“/*”等都可以用类似的方法穷举测试(很多测试软件使用)
(2)网址:http: //www.jb51.net/benwin.php?id=1 and 1=1  则sql语句可能是 select  *  from phpben where id = 1 and 1=1,运行正常且结果和http://www.jb51.net/benwin.php?id=1结果一样,则说明benwin.php可能没有对空格“ ”、和“and”过滤(这里是可能,所以要看下一点)
(3)网址:http: //www.jb51.net/benwin.php?id=1 and 1=2则sql语句可能是 select  *  from phpben where id = 1 and 1=2 如果运行结果异常说明sql语句中“and 1=2”起作用,所以能3个条件都满足都则很确定的benwin.php存在注入漏洞。
ps:这里用get方法验证,post也可以,只要把值按上面的输入,可以一一验证。
3.2常见的mysql注入语句。
(1)不用用户名和密码
复制代码 代码如下:
 
//正常语句 
$sql  = "select * from phpben where user_name='admin' and pwd ='123'"
//在用户名框输入'or'='or'或 'or 1='1 然后sql如下 
$sql  = "select * from phpben where user_name=' 'or'='or'' and pwd ='' "
$sql  = "select * from phpben where user_name=' 'or 1='1' and pwd ='' " ;
 
这样不用输入密码。话说笔者见到登录框都有尝试的冲动。
(2)在不输入密码的情况下,利用某用户。
复制代码 代码如下:
 
//正常语句 
$sql  = "select * from phpben where user_name='$username' and pwd ='$pwd'"
//利用的用户名是benwin 则用户名框输入benwin'#  密码有无都可,则$sql变成 
$sql  = "select * from phpben where user_name=' benwin'#' and pwd ='$pwd'" ;
 
这是因为mysql中其中的一个注悉是“#”,上面语句中#已经把后面的内容给注悉掉,所以密码可以不输入或任意输入。网上有些人介绍说用“/*”来注悉,笔者想提的是只有开始注悉没结束注悉“*/”时,mysql会报错,也不是说“ /**/ ”不能注悉,而是这里很难添加上“*/”来结束注悉,还有“– ”也是可以注悉mysql 但要注意“–”后至少有一个空格也就是“– ”,当然防注入代码要把三种都考虑进来,值得一提的是很多防注入代码中没把“– ”考虑进防注入范围。
(3)猜解某用户密码
复制代码 代码如下:
 
//正常语句 
$sql  = "select * from phpben.com where user_name='$username' and pwd ='$pwd'"
//在密码输入框中输入“benwin' and left(pwd,1)='p'#”,则$sql是 
$sql  = "select * from phpben.com where user_name=' benwin' and left(pwd,1)='p'#' and pwd ='$pwd'" ;
 
如果运行正常则密码的密码第一个字符是p,同理猜解剩下字符。
(4)插入数据时提权
复制代码 代码如下:
 
//正常语句,等级为1 
$sql  "insert into phpben.com (`user_name`,`pwd`,`level`) values(‘benwin','iampwd',1) "
//通过修改密码字符串把语句变成 
$sql  "insert into phpben.com (`user_name`,`pwd`,`level`) values(‘benwin','iampwd',5)#',1) "
$sql  "insert into phpben.com (`user_name`,`pwd`,`level`) values(‘benwin','iampwd',5)--  ',1) " ;这样就把一个权限为1的用户提权到等级5
 
 
(5)更新提权和插入提权同理
复制代码 代码如下:
 
//正常语句 
$sql  "update phpben set  `user_name` ='benwin', level=1"
//通过输入用户名值最终得到的$sql 
$sql  "update phpben set  `user_name` ='benwin',level=5#', level=1"
$sql  "update phpben set  `user_name` ='benwin',level=5--  ', level=1"
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值