上次講到控制器怎麼樣將數據傳遞到視圖,今天我就主要說一下在程序中怎麼讓代碼更「安全」,以後就轉到講模型,再講怎麼作視圖,最後再講控制器的功能強化。 php
我再聲明一下,我寫這個文章只是讓你們對PHP的框架編寫有一個基本的瞭解,因爲本人技術有限,這個文章是給PHP初學者學習的,因此高手勿噴,還有就是我如今時間也有限,因此每次可能須要兩三天才能寫一篇,每篇我寫的時間也要控制在一個小時之內,因爲邊寫這個文章邊編代碼,因此代碼中可能會存在不少BUG,見諒!! mysql
若是你是一個PHP愛好者,請在文章後面積極回覆一下,這種交流不只可使個人PHP技術提升,也鼓勵了我繼續寫下去的勇氣,謝謝!! linux
不少人編寫PHP代碼什麼都不注意,遇到不少警告,就直接經過error_reporting屏蔽掉,這樣作我以爲問題是很是大的,好比: sql
<?php $a = $_GET['a'];
echo $a;若是經過GET方式傳遞的參數有a,那麼程序很是正常,可是若是沒有傳遞呢,那就會拋出一個警告!!
個人做法是首先將error_reporting設置爲E_STRICT,不容許程序出現警告!! 數據庫
剛纔這段代碼可能就須要修改爲: 編程
<?php $a = isset($_GET['a']) ? $_GET['a'] : '';
echo $a;除了這種問題,還有就是PHP特有的 @符號 ,不少人都喜歡用這個來屏蔽錯誤,可是我以爲使用這個弊大於利,由於當項目很大的時候,出現一個錯誤,因爲這個錯誤又被屏蔽,要找到這個錯誤的位置真心的很難!!
關於異常的處理,雖然try catch會帶來很大的開銷,我我的以爲爲了程序的健壯性,必要的try catch仍是須要的。 安全
好吧,雜七雜八的說了這麼多,貌似這個和安全不太沾得上邊,但對於我來講,它們也是「安全」的一部分。 服務器
如今假設你花費了十天時間編寫了一個簡單的博客系統,購買了萬網的虛擬主機或VPS,申請域名,網站備案,而後部署代碼,這一切的一切都搞定了,而後用戶就能夠經過好比www.test.com這樣一個域名來訪問你的博客系統,你這套博客系統很受歡迎,短期內就積累了大量的人氣,可是忽然有一天,你發現你的網站忽然出故障了,你怎麼辦? session
在線上將PHP的配置文件中的error_reporting打開,而後線上調試? 框架
說實話,我以前也在個人博客系統上面線上調試過,和上述狀況不同的一點是,個人博客訪問量很低,由於我這我的太懶了,不太喜歡去管理個人博客。
若是你的網站擁有很大的訪問量,你在線上作調試想一想也是不可能的事情,那怎麼作呢?
記Log,若是你的網站在發生故障以前你就有寫Log,那麼程序出現故障以後你只須要打開日誌文件,而後就能夠看到故障出現的位置,而後修復掉,這樣就OK了!!
好了,現假設我是你的同窗,而且也參與了你的博客系統的開發,可是我和你前一陣鬧了一點矛盾,我懷恨在心,想把你的博客系統破壞掉,怎麼破壞呢?
首先假設你的數據庫名爲Test,這個數據庫中存在一個user表,user表存放着20000個會員信息,我知道你的博客註冊系統的代碼是以下:
<?php $username = $_POST['username']; $password = $_POST['password']; if(empty($username) || empty($password)) { //跳轉到註冊界面並提示用戶名或密碼未填寫 exit(); } //鏈接數據庫 //假設DB類封裝了不少SQL操做,析構的時候自動關閉數據庫鏈接,具體過程不寫了 //$db是一個數據庫DB類的實例,存在兩個方法 //$db->isUsernameExists斷定是否用戶名是否存在 //$db->query 執行一條SQL語句 if(!$db->isUsernameExists($username)) { $db->query("insert into user (username,password) values ('" . $username . "','" . $password . "')"); //設置session並跳轉 exit(); } else { //跳轉到註冊界面並提示用戶名已存在 exit(); }
這段代碼有問題嗎,我相信不少PHP Coder都會很鄙視的說到「你不就是想說SQL注入嘛」。
的確,這個就是一個SQL注入的問題,這個問題已經很古老了,好像你們都知道,爲何我還要講呢?
這是由於我以前在學校看到過幾個由學弟編寫的PHP項目,他們就基本上沒有考慮過這個問題,不少代碼就直接這麼寫,固然,你若是按照網上SQL注入的方式去試,會發現你根本注入不了,貌似PHP已經自動幫你解決掉這個問題了,怎麼解決的呢,實際上就是對特殊字符前加上反斜線。
首先說一下爲何SQL注入失敗呢?若是你的php.ini中配置了自動轉義,PHP會在你將數據插入到DB以前對數據進行轉義。
貌似這樣咱們就不用考慮這個問題了,可是實際上PHP幫咱們作了這些才讓事情更可怕,若是你將你的程序轉移到另一臺linux服務器, 這臺服務器上面php.ini配置文件中配置了不自動進行轉義,那麼你的程序一會兒問題就大了,咱們不該該將咱們代碼的安全性依賴於服務器的配置。那麼怎麼搞定這個事情呢?
幸虧,PHP中已經有了addslashes函數,它會對特殊字符進行轉義,可是很遺憾,經過查看PHP手冊發現:
默認狀況下,PHP 指令 magic_quotes_gpc 爲 on,它主要是對全部的 GET、POST 和 COOKIE 數據自動運行 addslashes()。不要對已經被 magic_quotes_gpc 轉義過的字符串使用 addslashes(),由於這樣會致使雙層轉義。遇到這種狀況時可使用函數 get_magic_quotes_gpc() 進行檢測
那怎麼作呢,幸虧PHP已經提供了一個get_magic_quotes_gpc函數能夠來斷定是否已經開啓了magic_quotes_gpc,因此咱們能夠自定義一個addslashes函數,如:
<?php function myAddslashes($str) { if(get_magic_quotes_gpc()){ return addslashes($str); } }其實還有另外的方法解決這個問題:
1. 使用PDO來訪問DB,PDO中可使用PDOStatement->bindParam,這樣,PDO會自動幫你作好這一切,而且我我的以爲PDO頗有前途!!
2. 若是get_magic_quotes_gpc爲on,首先調用stripslashes去除轉義字符,而後在插入數據庫以前使用mysql_real_escape_string,我我的以爲這種方式比第一種方式靠譜!!
固然,說了這麼多,有可能還有童鞋不知道什麼是SQL注入,我就簡略的講一下SQL注入的過程啊,熟悉SQL注入的人直接pass掉這一段。
按照上面的例子,假設用戶在password這個字段輸入的值爲a');drop table user;...,那麼執行SQL的時候SQL語句就會變成:
insert into user (username,password) values ('用戶名','a');drop table user;...')
這個SQL首先會向user表插入一條記錄,而後刪除整個表,而後。。。。SQL出錯了。
不過無論SQL是否出錯,user表已經沒有了,對於一個會員10000的博客,用戶表沒有了,我以爲損失仍是蠻大的,固然,你也能夠將鏈接數據庫的用戶的權限下降,沒有刪除表的權限,可是這樣也不是一個治本的方法,仍是解決掉SQL注入漏洞比較靠譜。
好,解決掉SQL注入,我再說一下XSS(跨站腳本漏洞)的問題。
現有一段PHP的腳本:
<?php echo $_GET['a'];我纔講到這個的代碼是有問題的,上面說的是有時候會拋出警告,可是若是傳遞參數的時候被不法分子利用,這個問題就大多了。
如今假設訪問這個腳本的URL是:http://localhost/test.php?a=a,我將參數a的值設爲a,傳遞過去一點問題都沒有吧,可是如今假設我值換一下,URL變成了:
http://localhost/test.php?a=<script>location.href="http://www.tmall.com"</script>,那麼執行腳本的時候就會跳轉到天貓首頁,這樣恐怖吧!!
若是這個不是跳轉到天貓,而是跳轉到某一個黑客設好的網址,他就可能將你的Cookie信息弄到,而後就能夠僞造Cookie,用你的身份登陸博客系統,而後。。。。你懂的。
解決這個問題的方法也很簡單,就是字符串轉義就OK,實際上就能夠經過咱們自定義的這個myAddslashes方法來作,調用了這個方法以後,腳本沒法執行了,可是有時候咱們又須要執行腳本,那怎麼作呢,咱們能夠對輸入的字符串按照必定的規則過濾,具體怎麼使用的能夠參照手冊。
解決掉這個問題以後,我再說另一個問題,這個問題就是CSRF(跨站點請求僞造漏洞),這是個什麼東東!!!
現假設你有一個留言的系統,留言的內容是富文本的,用戶能夠添加表情等等,表情的HTML代碼是<img src = "XXX" />,假設用戶填寫的表情是經過你提供的富文本編輯器來作的,沒有任何問題,可是若是他不使用這個,而是利用img標籤作了另一個事情呢?
怎麼作呢?很簡單的,就是改變img標籤的src屬性:
<img src = "http://www.tmall.com" />
提交留言以後發現這個圖片沒法顯示,爲何沒法顯示其實也很簡單,根本不是一個合法的圖片連接,可是當一個不知情的用戶A查看留言的時候,會發生什麼狀況,每次用戶打開這個留言的頁面,實際上就會訪問www.tmall.com一次,若是將這個網址改爲黑客的網址,那麼結果,仍是你懂的。。。
其實除了這些,還有上傳文件的漏洞等等,因爲時間有限,就不說了。
我講這些實際上就是爲了說明,安全問題實際上很重要,咱們在編程序的時候要考慮的東西其實是不少的。
原本今天還要講怎麼在框架中怎麼去解決這些問題,可是又超出我預計的一個小時的時間了,那就下次再說了。
SQL注入和XSS實際上我已經講了怎麼防止,可是CSRF怎麼防止呢?