旗下导航:搜·么
当前位置:网站首页 > PHP教程 > 正文

php安全问题思索【php教程】

作者:搜搜PHP网发布时间:2019-11-26分类:PHP教程浏览:122


导读:用户提交过来的数据都是不可托的,所以,在查库或入库前须要对提交过来的数据举行过滤或字符的转换处置惩罚,以防备SQL注入或xss进击等题目。引荐:【PHP教程】一、防备S...
用户提交过来的数据都是不可托的,所以,在查库或入库前须要对提交过来的数据举行过滤或字符的转换处置惩罚,以防备SQL注入或xss进击等题目。

引荐:【PHP教程】

一、防备SQL注入

什么是SQL注入进击?

所谓SQL注入,就是经由过程把SQL敕令插进去到Web表单提交或输入域名或页面要求的查询字符串,终究到达诳骗服务器实行歹意的SQL敕令。

寻觅SQL注入的要领:

1.经由过程get要求

2.经由过程post要求

3.其他http要求,如cookie

罕见的SQL注入题目:

数据库查询参数的范例转换处置惩罚

1. 转义字符处置惩罚不当

Talk is cheap,Show me the code.

多说无益,代码亮出来吧!

// 构造动态SQL语句
  $sql = "select * from tbl where field = '$_GET['input']'";
  // 实行SQL语句
  $res = mysql_query($sql);

测试:

在下边的网址后边加一个单引号,就会报数据库毛病

http://testphp.vulnweb.com/ar...

2. 范例处置惩罚不当

// 构造动态SQL语句
$sql = "select * from tbl where field = $_GET['user_id']";
// 实行SQL语句
 $res = mysql_query($sql);

Mysql内置了一个敕令,可以读取文件

Union all select load_file('/etc/passwd')--
select * from tbl where userid = 1 union all select load_file('etc/passwd')--

该敕令会猎取数据库管理员的暗码。

处置惩罚要领:

须要将客户端传过来的数据举行范例强迫转换,然后再查询

$user_id = (int)$_GET['user_id'];
"select * from tbl where userid = {$user_id}";

3. 查询语句构造不当

user.php?table=user&

4. 毛病处置惩罚不当

行将站点的毛病信息暴漏给用户,如许异常风险。

// 构造动态查询语句
$getid = "select * from tbl where userid > 1";
// 实行SQL语句
$res = mysql_query($getid) or die('<pre>'.mysql_error().'</pre>');
5. 多个提交处置惩罚不当
// 参数是不是是一个字符串
if(is_string($_GET["param"])){}

数据入库时将转换单引号、双引号、反斜杠为实体

在入库的时刻假如不过滤 ' ""如许的东西,如许会使数据库报错,或许注入等题目。

先将字符串用htmlspecialchars()转换为实体后存储到数据库,然后从数据库读出来时htmlspecialchars_decode()转为HTML标签。

htmlspecialchars() 函数把一些预定义的字符转换为 HTML 实体。

函数原型:

htmlspecialchars(string,quotestyle,character-set)

预定义的字符是:

& (和号)    成为 &amp;
” (双引号)  成为 &quot;
‘ (单引号)  成为 &#039;
< (小于)    成为 &lt;
> (大于)    成为 &gt;

htmlspecialchars_decode() 函数把一些预定义的 HTML 实体转换为字符(和htmlspecialchars相反)。

函数原型:

htmlspecialchars_decode(string,quotestyle)

二、防备xss进击

什么是xss进击?

和上边的sql注入差别的是,xss进击是正当的字符串,如经由htmlspecialchars()要领实体化后,可以保存在数据库中,然则,当接见含有该字符串的内容页面时,就会出现题目,如字符串里边另有JavaScript,frame代码,本来的页面就会被改动。

比方你写个留言本,有人去留言写<script src="xx"></script><iframe>,这个被显出来轻易挂病毒都很轻易,和数据库无关。

XSS观点

XSS又称CSS,全称Cross SiteScript(跨站剧本进击), XSS进击相似于SQL注入进击,是Web顺序中罕见的破绽,XSS属于被动式且用于客户端的进击体式格局,所以轻易被疏忽其伤害性。其道理是进击者向有XSS破绽的网站中输入(传入)歹意的HTML代码,当用户阅读该网站时,这段HTML代码会自动实行,从而到达进击的目标。如,偷取用户Cookie信息、损坏页面构造、重定向到别的网站等。

理论上,只需存在能供应输入的表单而且没做平安过滤或过滤不完全,都有可以存在XSS破绽。

下面是一些最简朴而且比较罕见的歹意字符XSS输入:

1.XSS 输入平常包括 JavaScript 剧本,如弹出歹意正告框:<script>alert("XSS");</script>

2.XSS 输入也多是 HTML 代码段,比如:

(1).网页不停地革新 <meta http-equiv="refresh" content="0;">

(2).嵌入别的网站的链接 <iframe src=http://xxxx width=250 height=250></iframe>

除了经由过程平常门路输入XSS进击字符外,还可以绕过JavaScript校验,经由过程修正要求到达XSS进击的目标,以下图:

相识到XSS进击的道理和伤害后,实在要防备也不难,下面供应一个简朴的PHP防备XSS进击的函数:

除了经由过程平常门路输入XSS进击字符外,还可以绕过JavaScript校验,经由过程修正要求到达XSS进击的目标。

相识到XSS进击的道理和伤害后,实在要防备也不难,下面供应一个简朴的PHP防备XSS进击的函数:

<?PHP
/**
 * @blog http://www.digtime.cn
 * @param $string
 * @param $low 平安别级低
 */
function clean_xss(&$string, $low = False)
{
    if (! is_array ( $string ))
    {
        $string = trim ( $string );
        $string = strip_tags ( $string );
        $string = htmlspecialchars ( $string );
        if ($low)
        {
            return True;
        }
        $string = str_replace ( array ('"', "\\", "'", "/", "..", "../", "./", "//" ), '', $string );
        $no = '/%0[0-8bcef]/';
        $string = preg_replace ( $no, '', $string );
        $no = '/%1[0-9a-f]/';
        $string = preg_replace ( $no, '', $string );
        $no = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S';
        $string = preg_replace ( $no, '', $string );
        return True;
    }
    $keys = array_keys ( $string );
    foreach ( $keys as $key )
    {
        clean_xss ( $string [$key] );
    }
}
//just a test
$str = 'codetc.com<meta http-equiv="refresh" content="0;">';
clean_xss($str); //假如你把这个解释掉,你就晓得xss进击的厉害了
echo $str;
?>

防止被XSS:

1.给用户开放的编辑器只管过滤掉风险的代码

假如是html编辑器,平常的做法是保存大部份代码,过滤部份可以存在风险的代码,如script, iframe等等

三、PHP MySQL 预处置惩罚语句

预处置惩罚语句关于防备 MySQL 注入是异常有效的。

预处置惩罚语句及绑定参数

预处置惩罚语句用于实行多个雷同的 SQL 语句,而且实行效力更高。

预处置惩罚语句的事情道理以下:

预处置惩罚:建立 SQL 语句模板并发送到数据库。预留的值运用参数 "?" 标记 。比方:

INSERT 
    INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?)

数据库剖析,编译,对SQL语句模板实行查询优化,并存储效果不输出。

实行:末了,将运用绑定的值通报给参数("?" 标记),数据库实行语句。运用可以屡次实行语句,假如参数的值不一样。

比拟于直接实行SQL语句,预处置惩罚语句有两个重要长处:

预处置惩罚语句大大减少了剖析时候,只做了一次查询(虽然语句屡次实行)。

绑定参数减少了服务器带宽,你只须要发送查询的参数,而不是悉数语句。

预处置惩罚语句针对SQL注入是异常有效的,由于参数值发送后运用差别的协定,保证了数据的正当性。

PDO预处置惩罚机制

可以运用多种体式格局完成预处置惩罚:指的是在绑定数据举行实行的时刻,可以有多种体式格局。

预处置惩罚语句中为变量

运用数组指定预处置惩罚变量

  1、预备预处置惩罚语句(发送给服务器,让服务器预备预处置惩罚语句)

PDOStatement PDO::prepare:相似exec将一条SQL语句发送给Mysql服务器  
    //PDO::prepare 可以自动的预备一个预处置惩罚语句,用户须要预备的只是预处置惩罚所要实行的语句
    //需求:往门生内外轮回插进去10条纪录
    //PDO的预处置惩罚可以自动的将对应的以:最先的变量给纪录下来,现实发送给服务器的是“?”
    $sql1 = "insert into pro_student values(null,:s_name,:s_num,:s_gender,:s_age,:c_id)";

  2、发送预处置惩罚语句

$stmt = $pdo->prepare($sql1);

  3、给预处置惩罚绑定数据

$arr = array(
      ':s_name' => '房祖名',
      ':s_num' => 'itcast0013',
      ':s_gender' => 0,
      ':s_age' => 28,
      ':c_id' => 2
    );

  4、实行预处置惩罚:将要操纵的数据发送给预处置惩罚语句,再实行预处置惩罚语句

PDOStatement::execute([$array]):数组用来通报对应的参数
    $stmt->execute($arr); //实行预处置惩罚

PDO预处置惩罚道理

PDO的防备sql注入的机制也是相似于运用mysql_real_escape_string 举行转义,PDO 有两种转义的机制,第一种是当地转义,这类转义的体式格局是运用单字节字符集(PHP < 5.3.6)来转义的(单字节与多字节),来对输入举行转义,然则这类转义体式格局有一些隐患。隐患重如果:在PHP版本小于5.3.6的时刻,当地转义只能转换单字节的字符集,大于 5.3.6 的版本会依据 PDO 衔接中指定的 charset 来转义。

第二种体式格局是PDO,起首将 sql 语句模板发送给Mysql Server,随后将绑定的字符变量再发送给Mysql server,这里的转义是在Mysql Server做的,它是依据你在衔接PDO的时刻,在charset里指定的编码花样来转换的。如许的转义体式格局更健全,同时还可以在又屡次反复查询的营业场景下,经由过程复用模板,来进步顺序的机能。假如要设置Mysql Server 来转义的话,就要起首实行:

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

原始链接要领:

<?php  
// PDO的运用
// http://blog.csdn.net/qq635785620/article/details/11284591
$dbh = new PDO('mysql:host=127.0.0.1:3306;dbname=mysql_safe', 'root', '518666'); 
 
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);    
$dbh->exec('set names utf8');   
$title    = "我们的恋爱";
$content  = '你是/谁啊,大几\都"老梁"做做&>women<a>没' . " 测试打印号'我是单引号'哈哈";
$user_id  = 174742;
$add_time = date("Y-m-d H:i:s");
$insert_sql = "insert into post_tbl (title, content, user_id, add_time) values (:x_title, :x_content, :x_user_id, :x_add_time)";
$stmt = $dbh->prepare($insert_sql); 
$stmt->execute(array('x_title'=>$title,':x_content'=> $content, ':x_user_id' => $user_id, ':x_add_time' => $add_time));    
echo $dbh->lastinsertid();


可见此次PHP是将SQL模板和变量是分两次发送给MySQL的,由MySQL完成变量的转义处置惩罚,既然变量和SQL模板是分两次发送的,那末就不存在SQL注入的题目了,但须要在DSN中指定charset属性,如:

$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root');

示例:

/**
*  插进去用户的Token
*/
function photo_save_token($user_id, $token)
{
    // 参数推断
    $user_id = (int)$user_id;
    $token = trim($token);
  
    if(empty($token) || empty($user_id)) return false;
    $sql = "replace into token_db.app_token_tbl
( user_id, token, t_date, last_open_time)
values
( :x_user_id, :x_token, :x_t_date, :x_last_open_time)";
    sqlSetParam($sql,"x_user_id",$user_id);
    sqlSetParam($sql,"x_token",$token);
    sqlSetParam($sql,"x_t_date",date('Y-m-d H:i:s'));
    sqlSetParam($sql,"x_last_open_time", time());
    return mysql_query($sql);
}

总结: 当挪用 prepare() 时,查询语句已发送给了数据库服务器,此时只要占位符 ? 发送过去,没有效户提交的数据;当挪用到 execute()时,用户提交过来的值才会传送给数据库,他们是离开传送的,二者自力的,SQL进击者没有一点时机。

小结

①、关于sql注入可以运用htmlspecialchars()或addslashes()要领,假如衔接mysql,可以用mysql_real_escape_string(),另有在php.ini中设置magic_quotes_gpc开启自动转义的扩大。

PHP环境翻开自动转义,PHP.INI中检察

当magic_quotes_gpc=on 时将自动举行转义(默许是on),可在顺序顶用get_magic_quotes_gpc()搜检他的状况

顺序为:

if (get_magic_quotes_gpc()==1){
     $name=stripcslashes($_POST["name"]);       
}else{
     $name=$_POST["name"];
}

②、关于xss进击可以写一个行止script,frame等代码的要领:

直接用这个函数editor_safe_replace替代htmlspecialchars,既保证平安又能用大部份html代码

function editor_safe_replace($content)
{
   $content = trim($content);
    $tags = array(
        "'<iframe[^>]*?>.*?</iframe>'is",
        "'<frame[^>]*?>.*?</frame>'is",
        "'<script[^>]*?>.*?</script>'is",
        "'<head[^>]*?>.*?</head>'is",
        "'<title[^>]*?>.*?</title>'is",
        "'<meta[^>]*?>'is",
        "'<link[^>]*?>'is",
    );
   
    
    // 1.先过滤掉含有xss进击的代码
    $content = preg_replace($tags, "", $content);
    
     // strip_tags过滤掉悉数HTML标签(script,iframe,head,a 等标签)和上边的正则要领相似
     // $content = strip_tags($content);
    
    // 2.入库时,防备sql注入,转为HTML实体保存在数据库,单双引号都转
     $content = htmlspecialchars($content, ENT_QUOTES);
     
    // 3.替代反斜杠
    $content = preg_replace("/\\\/", "&#092;", $content);
    // 4.替代斜杠
    $content = preg_replace("/\//", "&#47;", $content);
     
     return $content;
}

所以,关于PHP的平安而言,肯定要对用户提交的数据举行过滤校验处置惩罚,即先防备SQL注入,后再举行XSS过滤,这两个都须要两手一同抓,且两手都要硬,不然,你的网站将会存在很大的平安风险。

以上就是php平安题目思索的细致内容,更多请关注ki4网别的相干文章!

标签:php