不谈具体的代码,php站点安全防护心得

不谈具体的代码,php站点安全防护心得

首先,php本身有漏洞不在这篇文章的讨论范围之内,具体问题自行解决,这里要说的,是假如代码就是有漏洞,但是漏洞又找不到的情况下,如何去做。此文章仅针对小站点,大站点请忽略。

常见的漏洞有三个,通过XSS进入了后台,上传木马,sql注入。sql注入百度搜下很多,我的办法比较笨,过滤的严格一点,特殊地方不能过滤的,再特殊对待

实验环境

centos7 php7.1 nginx

防御XSS:

后台一般都有个后台目录,给该目录加上目录保护(浏览器打开目录,会提示输入账号密码),这样即便被拿到了后台的cookie和地址,也进入不了。下面是通过宝塔面板的设置截图。
按照提示填写即可,注意名称虽然可以用中文,但是感觉尽量还是用英文吧在这里插入图片描述
然后就有个小坑,实际应用在网站上不好用,于是去找nginx的相关配置文件,宝塔的nginx配置文件路径为(/www/server/panel/vhost/nginx/dir_auth/)。

location ~* ^/laozhang/* {
    #AUTH_START
    auth_basic "Authorization";
    auth_basic_user_file /www/server/pass/xiaozhu.5mai.net/test.pass;
    include enable-php-71.conf;
    #AUTH_END
}

如果没有伪静态,这样是没问题的,但是有了伪静态,得这样配置

location ~* ^/laozhang/* {
    #AUTH_START
    auth_basic "Authorization";
    auth_basic_user_file /www/server/pass/ytsn.5mai.net/a.pass;
    error_page 404 = @admin;
    error_page 405 = @admin;
    include enable-php-71.conf;
    #AUTH_END
}

location @admin {
    rewrite  ^(.*)$  /index.php?s=$1  last;   break;
}

#如果nginx是通过反向代理的形式对接的(比如swoole),那么就这么写
location @admin {
    proxy_pass http://127.0.0.1:20199;
    proxy_http_version 1.1;
    proxy_read_timeout 360s;   
    proxy_redirect off; 
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header REMOTE-HOST $remote_addr;

    add_header X-Cache $upstream_cache_status;

    #Set Nginx Cache

    add_header Cache-Control no-cache;
    expires 12h;
}

后半部分是具体的伪静态规则,我这个是tp的。如果有put或者delete,还想要对405再特殊处理下

加了这个后,如果后台是用vue做的,接口不同,用vue的代理模式就好了

上传漏洞

这个方案的思想来自java,都说java比php安全,但是语言本身哪有什么谁比谁安全的说法,不过仔细想一下,不是java安全,是java的形式无意中成就了他的安全。

我们都知道java是达成jar包或者war包放在服务器上(jsp就不说了),也就是说即便被上传了木马文件,也运行不了,jar包本身又不能被修改,所以自然也就没有了上传漏洞。

按照此思路去改造php的站点,首先,找到你的网站的入口文件,以tp为例,是public/index.php,在nginx的站点配置文件上设置,如果是php文件,只允许index.php访问,其他访问都是404

set $flag 0;
if ($uri ~* /.*\.php) {
    set $flag "${flag}1";
}
if ($uri != "/index.php") {
    set $flag "${flag}2";
}
# fastadmin系统会有个随机的php文件作为后台入口,注意此时不能用=,因为$uri是会包含 /a.php/user/index 的,所以要用~检索是否包含
if ($uri !~ "/345DFGii41.php") {
    set $flag "${flag}3";
}
if ($flag = "0123") {  #注意,如果加了345DFGii41.php的判断,这里的012要改成0123,也就是加几个这里就加多少数字
    return 404;
}

1,尽量放在站点配置文件比较考上的位置,如果写在下面,容易被别的规则先运行,就执行不到它了
2,如果你的入口文件有多个,那么久按照这个套路一直写(我水平有限,只能这样,希望有大神指点)

这样即便被上传了木马,也运行不了。

然后设置除了上传目录外,所有目录权限都为555(不可写),因为虽然木马文件传了没用,但是万一代码漏洞能造成index.php被改了怎么办。

然后就发现一个很讨厌的问题,设置555后,ftp也不能上传了,因为ftp也是www权限,自然也就上传不了了。

此时如果你是用jenkins或者跳板机这种比较高端的途径,那可以忽略,这里直说我们这种低端玩家。

用root权限肯定还是能传的,传完了后再改成555和www权限,这样是可以的。但是平常小站点开发,有点小问题IDE改完了直接快捷键ftp提交,省时省力,不想用root这种方式。

这个解决思路来源于宝塔,发现用面板还是可以改文件,并且改完了还是www用户。猜测宝塔应该是用一个更高级的权限去修改文件,然后再重新改权限为www。所以想到这么个办法。

ftp设置一个新目录,增加一个目录监控,ftp上传上文件后,再用root命令把那个新目录的文件同步到网站目录,并且重置权限。

目录监控软件【inotifywait】,安装:yum install inotify-tools -y

编写监控脚本

#!/bin/bash
#date:20200126
#explain:监控目录是否发生变化

CHECKDIR="/www/wwwroot/bpc_ftp/"    #监控目录路径
PHPFILE="/www/wwwroot/inotifywait/bpc.php"    #发送脚本路径


function CheckDir {
    inotifywait -mqr --timefmt '%y-%m-%d %H:%M:%S'  --format '%w %T %f %e' -e 'delete,close,create,moved_from' $CHECKDIR|while read event;
    do
    echo $event
	php $PHPFILE $event
    done
}

CheckDir



脚本具体什么意思大家自行百度,都说的很详细。这里说一下我自己遇到的坑。

首先是–format后面的参数设置,百度搜到的别人写的,都没有%w,这样就造成监听到的只有文件,没有文件所在的目录。最开始试了各种方法都不行,最后还是得靠仔细看参数说明。

然后是-e后面的,这个是要监听的动作,这里有个大坑,我是好一会才绕过来。

按照一般的想法,要监听创建,覆盖,删除这3个动作,软件没有覆盖这个动作,有个修改(modify)。这里就要理解一下文件传输的基本逻辑,首先传输一个文件,显示创建一个文件,然后是不断往这个文件加内容,最后是关闭文件。如果你传一个10M的文件,那么这个加内容的动作,会触发N多次的modify,服务器就挂了。所以要监听文件被关闭的动作。

脚本首先是要启动inotifywait,然后把监听到的内容发给php脚本,让php去复制文件(写shell确实比较蛋疼,这里用python也比较好,不过既然是php站,就尽量少引用别的东西了)

启动脚本并且后台运行【nohup bash /tmp/test/inot.sh >> outhup.log 2>&1 &】
查看是否运行【ps -eo pid,etime,cmd|grep “inot”| grep -v grep】
关闭脚本【ps -ef |grep inot |awk ‘{print $2}’|xargs kill -9】

下面是PHP脚本

<?php
function Directory($dir){
    return  is_dir ( $dir ) or Directory(dirname( $dir )) and  mkdir ( $dir , 0555) and chown($dir,"www") and chgrp($dir,"www");
}

$file_path='/www/wwwroot/bpc_ftp/';  //ftp的上传目录
$www_path='/www/wwwroot/bpc.yataisannong.com/';    //网站文件的目录

$argv=$_SERVER['argv'];
if(!$argv){
	exit;	
}

file_put_contents(__DIR__."/log.txt",var_export($argv,1)."\r\n",FILE_APPEND);

$action=$argv[5];
$path=$argv[1];
$file=$argv[4];

//网站对应目录
$_path=str_replace($file_path,$www_path,$path);
if($action=='CLOSE_NOWRITE,CLOSE'){
	Directory($_path);
	copy($path.$file,$_path.$file);
	chmod($_path.$file,0555);
	chown($_path.$file,"www");
	chgrp($_path.$file,"www");
}elseif($action=='CREATE,ISDIR'){
	Directory($_path.$file);
}elseif($action=='DELETE' || $action=='MOVED_FROM'){
	if(is_file($_path.$file)){
		unlink($_path.$file);
	}
}elseif($action=='DELETE,ISDIR'){
	if(is_dir($_path.$file)){
		rmdir($_path.$file);
	}
}

php要开启chmod和chgrp这两个函数

总结

平民方案,大神直接绕过即可

感谢这篇文章对我的初始帮助
https://www.cnblogs.com/yanjieli/p/10370503.html

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值