日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > php >内容正文

php

PHP安全基础第一章

發布時間:2024/9/19 php 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PHP安全基础第一章 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

PHP已經由一個制作個人網頁的工具發展成為了世界上最流行的網絡編程語言。它保證了許多網絡上最繁忙的站點的運行。這一轉變帶來了亟待關注的問題,那就是性能、可維護性、可測性、可靠性以及最重要的一點—安全性。

?

與語言的一些功能如條件表達式、循環結構等相比,安全性更為抽象。事實上,安全性更像是開發者的特性而不是語言的特性。任何語言都不能防止不安全的代碼,盡管語言的有些特點能對有安全意識的開發人員有作用。

?

本書著眼于PHP語言,向您展示如何通過操縱PHP一些特殊的功能寫出安全的代碼。本書中的概念,適用于任何網絡開發平臺。網絡應用程序的安全是一門年輕的和發展中的學科。本書會從理論出發,教會您一些好的習慣,使您能安枕無憂,從容應對惡意者層出不窮的新的攻擊和技巧。

不過,最聰明的還是時刻緊跟業內的新進展,下面是幾個有用的資源:

?http://phpsecurity.org/

本書的網站

?

http://phpsec.org/

PHP安全協會

?

http://shiflett.org/

本書作者的blog和網站

?

本章是本書的基礎部分。作為學習后續章節的前提,將教給您一些原則和經驗。

1.1.PHP功能

PHP有許多適合于WEB開發的功能。一些在其它語言中很難實現的普通工作在PHP中變得易如反掌,這有好處也有壞處。有一個功能比其它功能來更引人注目,這個功能就是register_globals。

1.1.1.?全局變量注冊

?

如果您還能記起早期WEB應用開發中使用C開發CGI程序的話,一定會對繁瑣的表單處理深有體會。當PHP的register_globals配置選項打開時,復雜的原始表單處理不復存在,公用變量會自動建立。它讓PHP編程變得容易和方便,但同時也帶來了安全隱患。

?

事實上,register_globals是無辜的,它并不會產生漏洞,同時還要開發者犯錯才行。可是,有兩個主要原因導致了您必須在開發和布署應用時關閉register_globals:

?

第一,它會增加安全漏洞的數量;

第二,隱藏了數據的來源,與開發者需要隨時跟蹤數據的責任相違背。

從 PHP4.2.0版本開始,php.ini中的設置選項 register_globals 默認值變成了 off。所以,最好從現在就開始用Off的風格開始編程!

?

?

register_globals的值可以設置為:On或者Off,我們舉一段代碼來分別描述它們的不同。

?

代碼:

<form name="frmTest" id="frmTest" action="URL"><input type="text" name="user_name" id="user_name"><input type="password" name="user_pass" id="user_pass"><input type="submit" value="login"></form>

當register_globals=Off的時候,下一個程序接收的時候應該 用$_GET['user_name']和$_GET['user_pass']來接受傳遞過來的值。(注:當<form>的method屬 性為post的時候應該用$_POST['user_name']和$_POST['user_pass'])

?

當register_globals=On的時候,下一個程序可以直接使用$user_name和$user_pass來接受值。

?

顧名思義,register_globals的意思就是注冊為全局變量,所以當On的時候,傳遞過來的值會被直接的注冊為全局變量直接使用,而Off的時候,我們需要到特定的數組里去得到它。所以,碰到上邊那些無法得到值的問題的朋友應該首先檢查一下你的register_globals的設置和你獲取值的方法是否匹配。(查看可以用phpinfo()函數或者直接查看php.ini)

看看下面的這段PHP腳本,它用來在輸入的用戶名及口令正確時授權訪問一個Web頁面:

<?php// 檢查用戶名及口令if ($username == 'kevin' and $password == 'secret')$authorized = true;?><?php if (!$authorized): ?><!-- 未授權的用戶將在這里給予提示 --><p>Please enter your username and password:</p><form action="<?=$PHP_SELF?>" method="POST"><p>Username: <input type="text" name="username" /><br />Password: <input type="password" name="password" /><br /><input type="submit" /></p></form><?php else: ?><!-- 有安全要求的HTML內容 --><?php endif; ?>

上面的代碼中存在的問題是你可以很容易地獲得訪問的權力,而不需要提供正確的用戶名和口令。只在要你的瀏覽器的地址欄的最后添加?authorized=1。因為PHP會自動地為每一個提交的值創建一個變量 -- 不論是來自動一個提交的表單、URL查詢字符串還是一個cookie -- 這會將$authorized設置為1,這樣一個未授權的用戶也可以突破安全限制。

?本書中所有例子都假定register_globals已被關閉,用超級公用數組如$_GET?和?$_POST取而代之。使用這些數組幾乎與register_globals開啟時的編程方法同樣方便,而其中的些許不便是值得的,因為它提高了程序的安全性。

小提示

?

如果您必須要開發一個在register_globals開啟的環境中布署的應用時,很重要的一點是您必須要初始化所有變量并且把error_reporting?設為?E_ALL(或?E_ALL?|?E_STRICT)以對未初始化變量進行警告。當register_globals開啟時,任何使用未初始化變量的行為幾乎就意味著安全漏洞。

?

1.1.2.?錯誤報告

沒有不會犯錯的開發者,PHP的錯誤報告功能將協助您確認和定位這些錯誤。可以PHP提供的這些詳細描述也可能被惡意攻擊者看到,這就不妙了。使大眾看不到報錯信息,這一點很重要。做到這一點很容易,只要關閉display_errors,當然如果您希望得到出錯信息,可以打開log_errors選項,并在error_log選項中設置出錯日志文件的保存路徑。

?

由于出錯報告的級別設定可以導致有些錯誤無法發現,您至少需要把error_reporting設為E_ALL(E_ALL?|?E_STRICT?是最高的設置,?提供向下兼容的建議,?如不建議使用的提示).

?

所有的出錯報告級別可以在任意級別進行修改,所以您如果使用的是共享的主機,沒有權限對php.ini,?httpd.conf,?或?.htaccess等配置文件進行更改時,您可以在程序中運行出錯報告級別配置語句:

<?phpini_set('error_reporting',?E_ALL?|?E_STRICT);ini_set('display_errors',?'Off');ini_set('log_errors',?'On');ini_set('error_log',?'/usr/local/apache/logs/error_log');?>

小提示

http://php.net/manual/ini.php?對php.ini的選項配置作了詳盡的說明。

?

PHP還允許您通過?set_error_handler(?)?函數指定您自已的出錯處理函數:

<?phpset_error_handler('my_error_handler');?>

?

上面程序指定了您自已的出錯處理函數my_error_handler(?);?下面是一個實際使用的示例:

<?phpfunction?my_error_handler($number,?$string,?$file,?$line,?$context){$error?=?"=?==?==?==?==\nPHP?ERROR\n=?==?==?==?==\n";$error?.=?"Number:?[$number]\n";$error?.=?"String:?[$string]\n";$error?.=?"File:?[$file]\n";$error?.=?"Line:?[$line]\n";$error?.=?"Context:\n"?.?print_r($context,?TRUE)?.?"\n\n";error_log($error,?3,?'/usr/local/apache/logs/error_log');}?>

?小提示

?

PHP 5還允許向set_error_handler( )傳遞第二個參數以限定在什么出錯情況下執行出定義的出錯處理函數。比如,現在建立一個處理告警級別(warning)錯誤的函數:

<?phpset_error_handler('my_warning_handler', E_WARNING);?>

?

PHP5還提供了異常處理機制,詳見http://php.net/exceptions

?1.2.原則

你可以列出一大堆開發安全應用的原則,但在本處我選取了我認為對PHP開發者最重要的幾個原則。

?

這些原則有意的寫得抽象和理論化。這樣做的目的是幫助你從大處著眼,不拘泥于細節。你需要把它們看成是你行動的指南。

?

1.2.1. 深度防范

?

深度防范原則是安全專業人員人人皆知的原則,它說明了冗余安全措施的價值,這是被歷史所證明的。

?

深度防范原則可以延伸到其它領域,不僅僅是局限于編程領域。使用過備用傘的跳傘隊員可以證明有冗余安全措施是多么的有價值,盡管大家永遠不希望主傘失效。一個冗余的安全措施可以在主安全措施失效的潛在的起到重大作用。

?

回到編程領域,堅持深度防范原則要求您時刻有一個備份方案。如果一個安全措施失效了,必須有另外一個提供一些保護。例如,在用戶進行重要操作前進行重新用戶認證就是一個很好的習慣,盡管你的用戶認證邏輯里面沒有已知缺陷。如果一個未認證用戶通過某種方法偽裝成另一個用戶,提示錄入密碼可以潛在地避免未認證(未驗證)用戶進行一些關鍵操作。

盡管深度防范是一個合理的原則,但是過度地增加安全措施只能增加成本和降低價值。

1.2.2. 最小權限

我過去有一輛汽車有一個傭人鑰匙。這個鑰匙只能用來點火,所以它不能打開車門、控制臺、后備箱,它只能用來啟動汽車。我可以把它給泊車員(或把它留在點火器上),我確認這個鑰匙不能用于其它目的。

?

把一個不能打開控制臺或后備箱的鑰匙給泊車員是有道理的,畢竟,你可能想在這些地方保存貴重物品。但我覺得沒有道理的是為什么它不能開車門。當然,這是因為我的觀點是在于權限的收回。我是在想為什么泊車員被取消了開車門的權限。在編程中,這是一個很不好的觀點。相反地,你應該考慮什么權限是必須的,只能給予每個人完成他本職工作所必須的盡量少的權限。

?

一個為什么傭人鑰匙不能打開車門的理由是這個鑰匙可以被復制,而這個復制的鑰匙在將來可能被用于偷車。這個情況聽起來不太可能發生,但這個例子說明了不必要的授權會加大你的風險,即使是增加了很小權限也會如此。風險最小化是安全程序開發的主要組成部分。

?

你無需去考慮一項權限被濫用的所有方法。事實上,你要預測每一個潛在攻擊者的動作是幾乎不可能的。

1.2.3. 簡單就是美

復雜滋生錯誤,錯誤能導致安全漏洞。這個簡單的事實說明了為什么簡單對于一個安全的應用來說是多么重要。沒有必要的復雜與沒有必要的風險一樣糟糕。

?

例如,下面的代碼摘自一個最近的安全漏洞通告:

<?php$search = (isset($_GET['search']) ? $_GET['search'] : '');?>

?

這個流程會混淆$search變量受污染*的事實,特別是對于缺乏經驗的開發者而言。上面語句等價于下面的程序:

<?php$search = '';if (isset($_GET['search'])){$search = $_GET['search'];}?>

?

上面的兩個處理流程是完全相同的。現在請注意一下下面的語句:

?

$search = $_GET['search'];

?

使用這一語句,在不影響流程的情況下,保證了$search變量的狀態維持原樣,同時還可以看出它是否受污染。

?

* 譯注:受污染變量,即在程序執行過程中,該變量的值不是由賦值語句直接指定值,而是來自其它來源,如控制臺錄入、數據庫等。

1.2.4. 暴露最小化

PHP應用程序需要在PHP與外部數據源間進行頻繁通信。主要的外部數據源是客戶端瀏覽器和數據庫。如果你正確的跟蹤數據,你可以確定哪些數據被暴露了。Internet是最主要的暴露源,這是因為它是一個非常公共的網絡,您必須時刻小心防止數據被暴露在Internet上。

?

數據暴露不一定就意味著安全風險。可是數據暴露必須盡量最小化。例如,一個用戶進入支付系統,在向你的服務器傳輸他的信用卡數據時,你應該用SSL去保護它。如果你想要在一個確認頁面上顯示他的信用卡號時,由于該卡號信息是由服務器發向他的客戶端的,你同樣要用SSL去保護它。

?

再談談上一小節的例子,顯示信用卡號顯然增加了暴露的機率。SSL確實可以降低風險,但是最佳的解決方案是通過只顯示最后四位數,從而達到徹底杜絕風險的目的。

?

為了降低對敏感數據的暴露率,你必須確認什么數據是敏感的,同時跟蹤它,并消除所有不必要的數據暴露。在本書中,我會展示一些技巧,用以幫助你實現對很多常見敏感數據的保護。

1.3. 方法

就像上一節中的原則一樣,開發安全應用時,還有很多方法可以使用。下面提到的所有方法同樣是我認為比較重要的。

?

某些方法是抽象的,但每一個都有實例說明如何應用及其目的。

?

1.3.1. 平衡風險與可用性

用戶操作的友好性與安全措施是一對矛盾,在提高安全性的同時,通常會降低可用性。在你為不合邏輯的使用者寫代碼時,必須要考慮到符合邏輯的正常使用者。要達到適當的平衡的確很難,但是你必須去做好它,沒有人能替代你,因為這是你的軟件。

?

盡量使安全措施對用戶透明,使他們感受不到它的存在。如果實在不可能,就盡量采用用戶比較常見和熟悉的方式來進行。例如,在用戶訪問受控信息或服務前讓他們輸入用戶名和密碼就是一種比較好的方式。

?

當你懷疑可能有非法操作時,必須意識到你可能會搞借。例如,在用戶操作時如果系統對用戶身份有疑問時,通常用讓用戶再次錄入密碼。這對于合法用戶來說只是稍有不便,而對于攻擊者來說則是銅墻鐵壁。從技術上來說,這與提示用戶進行重新登錄基本是一樣的,但是在用戶感受上,則有天壤之別。

?

沒有必要將用戶踢出系統并指責他們是所謂的攻擊者。當你犯錯時,這些流程會極大的降低系統的可用性,而錯誤是難免的。

?

在本書中,我著重介紹透明和常用的安全措施,同時我建議大家對疑似攻擊行為做出小心和明智的反應。

?

1.3.2. 跟蹤數據

作為一個有安全意識的開發者,最重要的一件事就是隨時跟蹤數據。不只是要知道它是什么和它在哪里,還要知道它從哪里來,要到哪里去。有時候要做到這些是困難的,特別是當你對WEB的運做原理沒有深入理解時。這也就是為什么盡管有些開發者在其它開發環境中很有經驗,但他對WEB不是很有經驗時,經常會犯錯并制造安全漏洞。

?

大多數人在讀取EMAIL時,一般不會被題為"Re: Hello"之類的垃圾郵件所欺騙,因為他們知道,這個看起來像回復的主題是能被偽造的。因此,這封郵件不一定是對前一封主題為"Hello."的郵件的回復。簡而言之,人們知道不能對這個主題不能太信任。但是很少有人意識到發件人地址也能被偽造,他們錯誤地認為它能可靠地顯示這個EMAIL的來源。

?

Web也非常類似,我想教給大家的其中一點是如何區分可信的和不可信的數據。做到這一點常常是不容易的,盲目的猜測并不是辦法。

?

PHP通過超級全局數組如$_GET, $_POST, 及$_COOKIE清楚地表示了用戶數據的來源。一個嚴格的命名體系能保證你在程序代碼的任何部分知道所有數據的來源,這也是我一直所示范和強調的。

?

知道數據在哪里進入你的程序是極為重要的,同時知道數據在哪里離開你的程序也很重要。例如,當你使用echo指令時,你是在向客戶端發送數據;當你使用mysql_query時,你是在向MySQL數據庫發送數據(盡管你的目的可能是取數據)。

?

在我審核PHP代碼是否有安全漏洞時,我主要檢查代碼中與外部系統交互的部分。這部分代碼很有可能包含安全漏洞,因此,在開發與代碼檢查時必須要加以特別仔細的注意。

1.3.3. 過濾輸入

?

過濾是Web應用安全的基礎。它是你驗證數據合法性的過程。通過在輸入時確認對所有的數據進行過濾,你可以避免被污染(未過濾)數據在你的程序中被誤信及誤用。大多數流行的PHP應用的漏洞最終都是因為沒有對輸入進行恰當過濾造成的。

?

我所指的過濾輸入是指三個不同的步驟:

?

l 識別輸入

l 過濾輸入

l 區分已過濾及被污染數據

?

把識別輸入做為第一步是因為如果你不知道它是什么,你也就不能正確地過濾它。輸入是指所有源自外部的數據。例如,所有發自客戶端的是輸入,但客戶端并不是唯一的外部數據源,其它如數據庫和RSS推送等也是外部數據源。

?

由用戶輸入的數據非常容易識別,PHP用兩個超級公用數組$_GET 和$_POST來存放用戶輸入數據。其它的輸入要難識別得多,例如,$_SERVER數組中的很多元素是由客戶端所操縱的。常常很難確認$_SERVER數組中的哪些元素組成了輸入,所以,最好的方法是把整個數組看成輸入。

?

在某些情況下,你把什么作為輸入取決于你的觀點。例如,session數據被保存在服務器上,你可能不會認為session數據是一個外部數據源。如果你持這種觀點的話,可以把session數據的保存位置是在你的軟件的內部。意識到session的保存位置的安全與軟件的安全是聯系在一起的事實是非常明智的。同樣的觀點可以推及到數據庫,你也可以把它看成你軟件的一部分。

?

一般來說,把session保存位置與數據庫看成是輸入是更為安全的,同時這也是我在所有重要的PHP應用開發中所推薦的方法。

一旦識別了輸入,你就可以過濾它了。過濾是一個有點正式的術語,它在平時表述中有很多同義詞,如驗證、清潔及凈化。盡管這些大家平時所用的術語稍有不同,但它們都是指的同一個處理:防止非法數據進入你的應用。

?

有很多種方法過濾數據,其中有一些安全性較高。最好的方法是把過濾看成是一個檢查的過程。請不要試圖好心地去糾正非法數據,要讓你的用戶按你的規則去做,歷史證明了試圖糾正非法數據往往會導致安全漏洞。例如,考慮一下下面的試圖防止目錄跨越的方法(訪問上層目錄)。

<?php$filename = str_replace('..', '.', $_POST['filename']);?>

?

你能想到$_POST['filename']如何取值以使$filename成為Linux系統中用戶口令文件的路徑../../etc/passwd嗎?

?

答案很簡單:

.../.../etc/passwd

這個特定的錯誤可以通過反復替換直至找不到為止:

<?php$filename = $_POST['filename'];while (strpos($_POST['filename'], '..') != = FALSE){$filename = str_replace('..', '.', $filename);}?>

?

當然,函數basename( )可以替代上面的所有邏輯,同時也能更安全地達到目的。不過重要點是在于任何試圖糾正非法數據的舉動都可能導致潛在錯誤并允許非法數據通過。只做檢查是一個更安全的選擇。

?譯注:這一點深有體會,在實際項目曾經遇到過這樣一件事,是對一個用戶注冊和登錄系統進行更改,客戶希望用戶名前后有空格就不能登錄,結果修改時對用戶登錄程序進行了更改,用trim()函數把輸入的用戶名前后的空格去掉了(典型的好心辦壞事),但是在注冊時居然還是允許前后有空格!結果可想而知。

除了把過濾做為一個檢查過程之外,你還可以在可能時用白名單方法。它是指你需要假定你正在檢查的數據是非法的,除非你能證明它是合法的。換而言之,你寧可在小心上犯錯。使用這個方法,一個錯誤只會導致你把合法的數據當成是非法的。盡管不想犯任何錯誤,但這樣總比把非法數據當成合法數據要安全得多。通過減輕犯錯引起的損失,你可以提高你的應用的安全性。盡管這個想法在理論上是很自然的,但歷史證明,這是一個很有價值的方法。

?

如果你能正確可靠地識別和過濾輸入,你的工作就基本完成了。最后一步是使用一個命名約定或其它可以幫助你正確和可靠地區分已過濾和被污染數據的方法。我推薦一個比較簡單的命名約定,因為它可以同時用在面向過程和面向對象的編程中。我用的命名約定是把所有經過濾的數據放入一個叫$clean的數據中。你需要用兩個重要的步驟來防止被污染數據的注入:

?

l 經常初始化$clean為一個空數組。

l 加入檢查及阻止來自外部數據源的變量命名為clean,

?

實際上,只有初始化是至關緊要的,但是養成這樣一個習慣也是很好的:把所有命名為clean的變量認為是你的已過濾數據數組。這一步驟合理地保證了$clean中只包括你有意保存進去的數據,你所要負責的只是不在$clean存在被污染數據。

<form action="process.php" method="POST">Please select a color:<select name="color"><option value="red">red</option><option value="green">green</option><option value="blue">blue</option></select><input type="submit" /></form>

?

為了鞏固這些概念,考慮下面的表單,它允許用戶選擇三種顏色中的一種;

在處理這個表單的編程邏輯中,非常容易犯的錯誤是認為只能提交三個選擇中的一個。在第二章中你將學到,客戶端能提交任何數據作為$_POST['color']的值。為了正確地過濾數據,你需要用一個switch語句來進行:

<?php$clean = array( );switch($_POST['color']){case 'red':case 'green':case 'blue':$clean['color'] = $_POST['color'];break;}?>

?

本例中首先初始化了$clean為空數組以防止包含被污染的數據。一旦證明$_POST['color']是red, green, 或blue中的一個時,就會保存到$clean['color']變量中。因此,可以確信$clean['color']變量是合法的,從而在代碼的其它部分使用它。當然,你還可以在switch結構中加入一個default分支以處理非法數據的情況。一種可能是再次顯示表單并提示錯誤。特別小心不要試圖為了友好而輸出被污染的數據。

上面的方法對于過濾有一組已知的合法值的數據很有效,但是對于過濾有一組已知合法字符組成的數據時就沒有什么幫助。例如,你可能需要一個用戶名只能由字母及數字組成:

<?php$clean = array( );if (ctype_alnum($_POST['username'])){$clean['username'] = $_POST['username'];}?>

?盡管在這種情況下可以用正則表達式,但使用PHP內置函數是更完美的。這些函數包含錯誤的可能性要比你自已寫的代碼出錯的可能性要低得多,而且在過濾邏輯中的一個錯誤幾乎就意味著一個安全漏洞。

1.3.4. 輸出轉義

另外一個Web應用安全的基礎是對輸出進行轉義或對特殊字符進行編碼,以保證原意不變。例如,O'Reilly在傳送給MySQL數據庫前需要轉義成O\'Reilly。單引號前的反斜杠代表單引號是數據本身的一部分,而不是并不是它的本義。

?

我所指的輸出轉義具體分為三步:

?

l 識別輸出

l 輸出轉義

l 區分已轉義與未轉義數據

?

?

只對已過濾數據進行轉義是很有必要的。盡管轉義能防止很多常見安全漏洞,但它不能替代輸入過濾。被污染數據必須首先過濾然后轉義。

?

在對輸出進行轉義時,你必須先識別輸出。通常,這要比識別輸入簡單得多,因為它依賴于你所進行的動作。例如,識別到客戶端的輸出時,你可以在代碼中查找下列語句:

?

echo

print

printf

<?=

作為一項應用的開發者,你必須知道每一個向外部系統輸出的地方。它們構成了輸出。

?

象過濾一樣,轉義過程在依情形的不同而不同。過濾對于不同類型的數據處理方法也是不同的,轉義也是根據你傳輸信息到不同的系統而采用不同的方法。

?

對于一些常見的輸出目標(包括客戶端、數據庫和URL)的轉義,PHP中有內置函數可用。如果你要寫一個自己算法,做到萬無一失很重要。需要找到在外系統中特殊字符的可靠和完整的列表,以及它們的表示方式,這樣數據是被保留下來而不是轉譯了。

最常見的輸出目標是客戶機,使用htmlentities( )在數據發出前進行轉義是最好的方法。與其它字符串函數一樣,它輸入是一個字符串,對其進行加工后進行輸出。但是使用htmlentities( )函數的最佳方式是指定它的兩個可選參數:引號的轉義方式(第二參數)及字符集(第三參數)。引號的轉義方式應該指定為ENT_QUOTES,它的目的是同時轉義單引號和雙引號,這樣做是最徹底的,字符集參數必須與該頁面所使用的字符集相必配。

?為了區分數據是否已轉義,我還是建議定義一個命名機制。對于輸出到客戶機的轉義數據,我使用$html數組進行存儲,該數據首先初始化成一個空數組,對所有已過濾和已轉義數據進行保存。

<?php$html = array( );$html['username'] = htmlentities($clean['username'], ENT_QUOTES, 'UTF-8');echo "<p>Welcome back, {$html['username']}.</p>";?>

小提示

htmlspecialchars( )函數與htmlentities( )函數基本相同,它們的參數定義完全相同,只不過是htmlentities( )的轉義更為徹底。

通過$html['username']把username輸出到客戶端,你就可以確保其中的特殊字符不會被瀏覽器所錯誤解釋。如果username只包含字母和數字的話,實際上轉義是沒有必要的,但是這體現了深度防范的原則。轉義任何的輸出是一個非常好的習慣,它可以戲劇性地提高你的軟件的安全性。

?

另外一個常見的輸出目標是數據庫。如果可能的話,你需要對SQL語句中的數據使用PHP內建函數進行轉義。對于MySQL用戶,最好的轉義函數是mysql_real_escape_string( )。如果你使用的數據庫沒有PHP內建轉義函數可用的話,addslashes( )是最后的選擇。

下面的例子說明了對于MySQL數據庫的正確的轉義技巧:

<?php$mysql = array( );$mysql['username'] = mysql_real_escape_string($clean['username']);$sql = "SELECT *FROM profileWHERE username = '{$mysql['username']}'";$result = mysql_query($sql);?>?

?

總結

以上是生活随笔為你收集整理的PHP安全基础第一章的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。