php安全问题思考-php教程

资源魔 22 0
用户提交过去的数据都是不成信的,以是,正在查库或入库前需求对提交过去的数据进行过滤或字符的转换解决,以避免SQL注入或xss攻打等成绩。

保举:【PHP教程】

1、避免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...

f8306d0f95b46d4dbd10f1cdb1adb27.png

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;
‘ (单引号)  成为 '
< (小于)    成为 &lt;
> (年夜于)    成为 &gt;

htmlspecialchars_decode() 函数把一些预约义的 HTML 实体转换为字符(以及htmlspecialchars相同)。

函数原型:

htmlspecialchars_decode(string,quotestyle)

2、避免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等等

3、PHP MySQL 预解决语句

预解决语句关于避免 MySQL 注入长短常有用的。

预解决语句及绑定参数

预解决语句用于执行多个相反的 SQL 语句,而且执行效率更高。

预解决语句的工作原理以下:

预解决:创立 SQL 语句模板并发送到数据库。预留的值应用参数 "?" 标志 。例如:

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

数据库解析,编译,对SQL语句模板执行查问优化,并存储后果没有输入。

执行:最初,将使用绑定的值通报给参数("?" 标志),数据库执行语句。使用能够屡次执行语句,假如参数的值纷歧样。

相比于间接执行SQL语句,预解决语句有两个次要优点:

预解决语句年夜年夜缩小了剖析工夫,只做了一次查问(尽管语句屡次执行)。

绑定参数缩小了效劳器带宽,你只要要发送查问的参数,而没有是整个语句。

预解决语句针对SQL注入长短常有用的,由于参数值发送后应用没有同的协定,保障了数据的非法性。

PDO预解决机制

能够应用多种形式完成预解决:指的是正在绑定命据进行执行的时分,能够有多种形式。

预解决语句中为变量

应用数组指定预解决变量

  一、预备预解决语句(发送给效劳器,让效劳器预备预解决语句)

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)";

  二、发送预解决语句

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

  三、给预解决绑定命据

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

  四、执行预解决:将要操作的数据发送给预解决语句,再执行预解决语句

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();


f3f6719c36c752ee64951e0bf6ef1fe.png

可见此次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("/\\\/", "\", $content);
    // 4.交换斜杠
    $content = preg_replace("/\//", "/", $content);
     
     return $content;
}

以是,关于PHP的平安而言,肯定要对用户提交的数据进行过滤校验解决,即先避免SQL注入,后再进行XSS过滤,这两个都需求两手一同抓,且两手都要硬,不然,你的网站将会存正在很年夜的平安危险。

以上就是php平安成绩考虑的具体内容,更多请存眷资源魔其它相干文章!

标签: php php开发教程 php开发资料 php开发自学

抱歉,评论功能暂时关闭!