保举:【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...
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)
预约义的字符是:
& (以及号) 成为 & ” (双引号) 成为 " ‘ (单引号) 成为 ' < (小于) 成为 < > (年夜于) 成为 >
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();
可见此次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开发自学
抱歉,评论功能暂时关闭!