簡介
要提供互聯(lián)網(wǎng)服務(wù),當(dāng)你在開發(fā)代碼的時候必須時刻保持安全意識??赡艽蟛糠?PHP 腳本都對安全問題都不在意,這很大程度上是因為有大量的無經(jīng)驗程序員在使用這門語言。但是,沒有理由讓你因為對你的代碼的不確定性而導(dǎo)致不一致的安全策略。當(dāng)你在服務(wù)器上放任何涉及到錢的東西時,就有可能會有人嘗試破解它。創(chuàng)建一個論壇程序或者任何形式的購物車,被攻擊的可能性就上升到了無窮大。
背景
為了確保你的 web 內(nèi)容安全,這里有一些常規(guī)的安全準(zhǔn)則:
別相信表單
攻擊表單很簡單。通過使用一個簡單的 JavaScript 技巧,你可以限制你的表單只允許在評分域中填寫 1 到 5 的數(shù)字。如果有人關(guān)閉了他們?yōu)g覽器的 JavaScript 功能或者提交自定義的表單數(shù)據(jù),你客戶端的驗證就失敗了。
用戶主要通過表單參數(shù)和你的腳本交互,因此他們是最大的安全風(fēng)險。你應(yīng)該學(xué)到什么呢?在 PHP 腳本中,總是要驗證 傳遞給任何 PHP 腳本的數(shù)據(jù)。在本文中,我們向你演示了如何分析和防范跨站腳本(XSS)攻擊,它可能會劫持用戶憑據(jù)(甚至更嚴(yán)重)。你也會看到如何防止會玷污或毀壞你數(shù)據(jù)的 MySQL 注入攻擊。
別相信用戶
假定你網(wǎng)站獲取的每一份數(shù)據(jù)都充滿了有害的代碼。清理每一部分,即便你相信沒有人會嘗試攻擊你的站點。
關(guān)閉全局變量
你可能會有的最大安全漏洞是啟用了 register_globals 配置參數(shù)。幸運的是,PHP 4.2 及以后版本默認(rèn)關(guān)閉了這個配置。如果打開了 register_globals,你可以在你的 php.ini 文件中通過改變 register_globals 變量為 Off 關(guān)閉該功能:
register_globals = Off
新手程序員覺得注冊全局變量很方便,但他們不會意識到這個設(shè)置有多么危險。一個啟用了全局變量的服務(wù)器會自動為全局變量賦任何形式的參數(shù)。為了了解它如何工作以及為什么有危險,讓我們來看一個例子。
假設(shè)你有一個稱為 process.php 的腳本,它會向你的數(shù)據(jù)庫插入表單數(shù)據(jù)。初始的表單像下面這樣:
<input name="username" type="text" size="15" maxlength="64">
運行 process.php 的時候,啟用了注冊全局變量的 PHP 會將該參數(shù)賦值到 $username 變量。這會比通過 $_POST['username'] 或 $_GET['username'] 訪問它節(jié)省擊鍵次數(shù)。不幸的是,這也會給你留下安全問題,因為 PHP 會設(shè)置該變量的值為通過 GET 或 POST 的參數(shù)發(fā)送到腳本的任何值,如果你沒有顯示地初始化該變量并且你不希望任何人去操作它,這就會有一個大問題。
看下面的腳本,假如 $authorized 變量的值為 true,它會給用戶顯示通過驗證的數(shù)據(jù)。正常情況下,只有當(dāng)用戶正確通過了這個假想的 authenticated_user() 函數(shù)驗證,$authorized 變量的值才會被設(shè)置為真。但是如果你啟用了 register_globals,任何人都可以發(fā)送一個 GET 參數(shù),例如 authorized=1 去覆蓋它:
<?php// Define $authorized = true only if user is authenticatedif (authenticated_user()) { $authorized = true;}?>
這個故事的寓意是,你應(yīng)該從預(yù)定義的服務(wù)器變量中獲取表單數(shù)據(jù)。所有通過 post 表單傳遞到你 web 頁面的數(shù)據(jù)都會自動保存到一個稱為 $_POST 的大數(shù)組中,所有的 GET 數(shù)據(jù)都保存在 $_GET 大數(shù)組中。文件上傳信息保存在一個稱為 $_FILES 的特殊數(shù)據(jù)中。另外,還有一個稱為 $_REQUEST 的復(fù)合變量。
要從一個 POST 方法表單中訪問 username 字段,可以使用 $_POST['username']。如果 username 在 URL 中就使用 $_GET['username']。如果你不確定值來自哪里,用 $_REQUEST['username']。
<?php$post_value = $_POST['post_value'];$get_value = $_GET['get_value'];$some_variable = $_REQUEST['some_value']; ?>
$_REQUEST 是 $_GET、$_POST、和 $_COOKIE 數(shù)組的結(jié)合。如果你有兩個或多個值有相同的參數(shù)名稱,注意 PHP 會使用哪個。默認(rèn)的順序是 cookie、POST、然后是 GET。
推薦安全配置選項
這里有幾個會影響安全功能的 PHP 配置設(shè)置。下面是一些顯然應(yīng)該用于生產(chǎn)服務(wù)器的:
- register_globals 設(shè)置為 off
- safe_mode 設(shè)置為 off
- error_reporting 設(shè)置為 off。如果出現(xiàn)錯誤了,這會向用戶瀏覽器發(fā)送可見的錯誤報告信息。對于生產(chǎn)服務(wù)器,使用錯誤日志代替。開發(fā)服務(wù)器如果在防火墻后面就可以啟用錯誤日志。(LCTT 譯注:此處據(jù)原文邏輯和常識,應(yīng)該是“開發(fā)服務(wù)器如果在防火墻后面就可以啟用錯誤報告,即 on?!保?
- 停用這些函數(shù):system()、exec()、passthru()、shell_exec()、proc_open()、和 popen()。
- open_basedir 為 /tmp(以便保存會話信息)目錄和 web 根目錄,以便腳本不能訪問這些選定區(qū)域外的文件。
- expose_php 設(shè)置為 off。該功能會向 Apache 頭添加包含版本號的 PHP 簽名。
- allow_url_fopen 設(shè)置為 off。如果你能夠注意你代碼中訪問文件的方式-也就是你驗證所有輸入?yún)?shù),這并不嚴(yán)格需要。
- allow_url_include 設(shè)置為 off。對于任何人來說,實在沒有明智的理由會想要訪問通過 HTTP 包含的文件。
一般來說,如果你發(fā)現(xiàn)想要使用這些功能的代碼,你就不應(yīng)該相信它。尤其要小心會使用類似 system() 函數(shù)的代碼-它幾乎肯定有缺陷。
啟用了這些設(shè)置后,讓我們來看看一些特定的攻擊以及能幫助你保護(hù)你服務(wù)器的方法。
SQL 注入攻擊
由于 PHP 傳遞到 MySQL 數(shù)據(jù)庫的查詢語句是用強(qiáng)大的 SQL 編程語言編寫的,就有了某些人通過在 web 查詢參數(shù)中使用 MySQL 語句嘗試 SQL 注入攻擊的風(fēng)險。通過在參數(shù)中插入有害的 SQL 代碼片段,攻擊者會嘗試進(jìn)入(或破壞)你的服務(wù)器。
假如說你有一個最終會放入變量 $product 的表單參數(shù),你使用了類似下面的 SQL 語句:
$sql = "select * from pinfo where product = '$product'";
如果參數(shù)是直接從表單中獲得的,應(yīng)該使用 PHP 自帶的數(shù)據(jù)庫特定轉(zhuǎn)義函數(shù),類似:
$sql = 'Select * from pinfo where product = '"' mysql_real_escape_string($product) . '"';
如果不這樣做的話,有人也許會把下面的代碼段放到表單參數(shù)中:
39'; DROP pinfo; SELECT 'FOO
那么 $sql 的結(jié)果就是:
select product from pinfo where product = '39'; DROP pinfo; SELECT 'FOO'
由于分號是 MySQL 的語句分隔符,數(shù)據(jù)庫會運行下面三條語句:
select * from pinfo where product = '39'DROP pinfoSELECT 'FOO'
好了,你丟失了你的表。
注意實際上 PHP 和 MySQL 不會運行這種特殊語法,因為 mysql_query() 函數(shù)只允許每個請求處理一個語句。但是,一個子查詢?nèi)匀粫А?
要防止 SQL 注入攻擊,做這兩件事:
- 總是驗證所有參數(shù)。例如,如果需要一個數(shù)字,就要確保它是一個數(shù)字。
- 總是對數(shù)據(jù)使用 mysql_real_escape_string() 函數(shù)轉(zhuǎn)義數(shù)據(jù)中的任何引號和雙引號。
注意:要自動轉(zhuǎn)義任何表單數(shù)據(jù),可以啟用魔術(shù)引號(Magic Quotes)。
一些 MySQL 破壞可以通過限制 MySQL 用戶權(quán)限避免。任何 MySQL 賬戶可以限制為只允許對選定的表進(jìn)行特定類型的查詢。例如,你可以創(chuàng)建只能選擇行的 MySQL 用戶。但是,這對于動態(tài)數(shù)據(jù)并不十分有用,另外,如果你有敏感的用戶信息,可能某些人能訪問其中一些數(shù)據(jù),但你并不希望如此。例如,一個訪問賬戶數(shù)據(jù)的用戶可能會嘗試注入訪問另一個人的賬戶號碼的代碼,而不是為當(dāng)前會話指定的號碼。
防止基本的 XSS 攻擊
XSS 表示跨站腳本。不像大部分攻擊,該漏洞發(fā)生在客戶端。XSS 最常見的基本形式是在用戶提交的內(nèi)容中放入 JavaScript 以便偷取用戶 cookie 中的數(shù)據(jù)。由于大部分站點使用 cookie 和 session 驗證訪客,偷取的數(shù)據(jù)可用于模擬該用戶-如果是一個常見的用戶賬戶就會深受麻煩,如果是管理員賬戶甚至是徹底的慘敗。如果你不在站點中使用 cookie 和 session ID,你的用戶就不容易被攻擊,但你仍然應(yīng)該明白這種攻擊是如何工作的。
不像 MySQL 注入攻擊,XSS 攻擊很難預(yù)防。Yahoo、eBay、Apple、以及 Microsoft 都曾經(jīng)受 XSS 影響。盡管攻擊不包含 PHP,但你可以使用 PHP 來剝離用戶數(shù)據(jù)以防止攻擊。為了防止 XSS 攻擊,你應(yīng)該限制和過濾用戶提交給你站點的數(shù)據(jù)。正是因為這個原因,大部分在線公告板都不允許在提交的數(shù)據(jù)中使用 HTML 標(biāo)簽,而是用自定義的標(biāo)簽格式代替,例如 [b] 和 [linkto]。
讓我們來看一個如何防止這類攻擊的簡單腳本。對于更完善的解決辦法,可以使用 SafeHTML,本文的后面部分會討論到。
function transform_HTML($string, $length = null) {// Helps prevent XSS attacks // Remove dead space. $string = trim($string); // Prevent potential Unicode codec problems. $string = utf8_decode($string); // HTMLize HTML-specific characters. $string = htmlentities($string, ENT_NOQUOTES); $string = str_replace("#", "#", $string); $string = str_replace("%", "%", $string); $length = intval($length); if ($length > 0) { $string = substr($string, 0, $length); } return $string;}
這個函數(shù)將 HTML 特定的字符轉(zhuǎn)換為 HTML 字面字符。一個瀏覽器對任何通過這個腳本的 HTML 以非標(biāo)記的文本呈現(xiàn)。例如,考慮下面的 HTML 字符串:
<STRONG>Bold Text</STRONG>
一般情況下,HTML 會顯示為:Bold Text
但是,通過 transform_HTML() 后,它就像原始輸入一樣呈現(xiàn)。原因是處理的字符串中的標(biāo)簽字符串轉(zhuǎn)換為 HTML 實體。transform_HTML() 的結(jié)果字符串的純文本看起來像下面這樣:
<STRONG>Bold Text</STRONG>
該函數(shù)的實質(zhì)是 htmlentities() 函數(shù)調(diào)用,它會將 <、>、和 & 轉(zhuǎn)換為 <、>、和 &。盡管這會處理大部分的普通攻擊,但有經(jīng)驗的 XSS 攻擊者有另一種把戲:用十六進(jìn)制或 UTF-8 編碼惡意腳本,而不是采用普通的 ASCII 文本,從而希望能繞過你的過濾器。他們可以在 URL 的 GET 變量中發(fā)送代碼,告訴瀏覽器,“這是十六進(jìn)制代碼,你能幫我運行嗎?” 一個十六進(jìn)制例子看起來像這樣:
<a href="http://host/a.php?variable=%22%3e %3c%53%43%52%49%50%54%3e%44%6f%73%6f%6d%65%74%68%69%6e%67%6d%61%6c%69%63%69%6f%75%73%3c%2f%53%43%52%49%50%54%3e">
瀏覽器渲染這個信息的時候,結(jié)果就是:
<a href="http://host/a.php?variable="> <SCRIPT>Dosomethingmalicious</SCRIPT>
為了防止這種情況,transform_HTML() 采用額外的步驟把 # 和 % 符號轉(zhuǎn)換為它們的實體,從而避免十六進(jìn)制攻擊,并轉(zhuǎn)換 UTF-8 編碼的數(shù)據(jù)。
最后,為了防止某些人用很長的輸入超載字符串從而導(dǎo)致某些東西崩潰,你可以添加一個可選的 $length 參數(shù)來截取你指定最大長度的字符串。
使用 SafeHTML
之前腳本的問題比較簡單,它不允許任何類型的用戶標(biāo)記。不幸的是,這里有上百種方法能使 JavaScript 跳過用戶的過濾器,并且要從用戶輸入中剝離全部 HTML,還沒有方法可以防止這種情況。
當(dāng)前,沒有任何一個腳本能保證無法被破解,盡管有一些確實比大部分要好。有白名單和黑名單兩種方法加固安全,白名單比較簡單而且更加有效。
一個白名單解決方案是 PixelApes 的 SafeHTML 反跨站腳本解析器。
SafeHTML 能識別有效 HTML,能追蹤并剝離任何危險標(biāo)簽。它用另一個稱為 HTMLSax 的軟件包進(jìn)行解析。
按照下面步驟安裝和使用 SafeHTML:
這是一個完整的例子:
<?php/* If you're storing the HTMLSax3.php in the /classes directory, along with the safehtml.php script, define XML_HTMLSAX3 as a null string. */define(XML_HTMLSAX3, '');// Include the class file.require_once('classes/safehtml.php');// Define some sample bad code.$data = "This data would raise an alert <script>alert('XSS Attack')</script>";// Create a safehtml object.$safehtml = new safehtml();// Parse and sanitize the data.$safe_data = $safehtml->parse($data);// Display result.echo 'The sanitized data is <br />' . $safe_data;?>
如果你想清理腳本中的任何其它數(shù)據(jù),你不需要創(chuàng)建一個新的對象;在你的整個腳本中只需要使用 $safehtml->parse() 方法。
什么可能會出現(xiàn)問題?
你可能犯的最大錯誤是假設(shè)這個類能完全避免 XSS 攻擊。SafeHTML 是一個相當(dāng)復(fù)雜的腳本,幾乎能檢查所有事情,但沒有什么是能保證的。你仍然需要對你的站點做參數(shù)驗證。例如,該類不能檢查給定變量的長度以確保能適應(yīng)數(shù)據(jù)庫的字段。它也不檢查緩沖溢出問題。
XSS 攻擊者很有創(chuàng)造力,他們使用各種各樣的方法來嘗試達(dá)到他們的目標(biāo)??梢蚤喿x RSnake 的 XSS 教程http://ha.ckers.org/xss.html ,看一下這里有多少種方法嘗試使代碼跳過過濾器。SafeHTML 項目有很好的程序員一直在嘗試阻止 XSS 攻擊,但無法保證某些人不會想起一些奇怪和新奇的方法來跳過過濾器。
注意:XSS 攻擊嚴(yán)重影響的一個例子 http://namb.la/popular/tech.html,其中顯示了如何一步一步創(chuàng)建一個讓 MySpace 服務(wù)器過載的 JavaScript XSS 蠕蟲。
用單向哈希保護(hù)數(shù)據(jù)
該腳本對輸入的數(shù)據(jù)進(jìn)行單向轉(zhuǎn)換,換句話說,它能對某人的密碼產(chǎn)生哈希簽名,但不能解碼獲得原始密碼。為什么你希望這樣呢?應(yīng)用程序會存儲密碼。一個管理員不需要知道用戶的密碼,事實上,只有用戶知道他/她自己的密碼是個好主意。系統(tǒng)(也僅有系統(tǒng))應(yīng)該能識別一個正確的密碼;這是 Unix 多年來的密碼安全模型。單向密碼安全按照下面的方式工作:
主機(jī)系統(tǒng)完成這些并不需要知道原始密碼;事實上,原始密碼完全無所謂。一個副作用是,如果某人侵入系統(tǒng)并盜取了密碼數(shù)據(jù)庫,入侵者會獲得很多哈希后的密碼,但無法把它們反向轉(zhuǎn)換為原始密碼。當(dāng)然,給足夠時間、計算能力,以及弱用戶密碼,一個攻擊者還是有可能采用字典攻擊找出密碼。因此,別輕易讓人碰你的密碼數(shù)據(jù)庫,如果確實有人這樣做了,讓每個用戶更改他們的密碼。
加密 Vs 哈希
技術(shù)上來來說,哈希過程并不是加密。哈希和加密是不同的,這有兩個理由:
不像加密,哈希數(shù)據(jù)不能被解密。
是有可能(但非常罕見)兩個不同的字符串會產(chǎn)生相同的哈希。并不能保證哈希是唯一的,因此別像數(shù)據(jù)庫中的唯一鍵那樣使用哈希。
function hash_ish($string) { return md5($string);}
上面的 md5() 函數(shù)基于 RSA 數(shù)據(jù)安全公司的消息摘要算法(即 MD5)返回一個由 32 個字符組成的十六進(jìn)制串。然后你可以將那個 32 位字符串插入到數(shù)據(jù)庫中和另一個 md5 字符串相比較,或者直接用這 32 個字符。
破解腳本
幾乎不可能解密 MD5 數(shù)據(jù)。或者說很難。但是,你仍然需要好的密碼,因為用一整個字典生成哈希數(shù)據(jù)庫仍然很簡單。有一些在線 MD5 字典,當(dāng)你輸入 06d80eb0c50b49a509b49f2424e8c805 后會得到結(jié)果 “dog”。因此,盡管技術(shù)上 MD5 不能被解密,這里仍然有漏洞,如果某人獲得了你的密碼數(shù)據(jù)庫,你可以肯定他們肯定會使用 MD5 字典破譯。因此,當(dāng)你創(chuàng)建基于密碼的系統(tǒng)的時候尤其要注意密碼長度(最小 6 個字符,8 個或許會更好)和包括字母和數(shù)字。并確保這個密碼不在字典中。
用 Mcrypt 加密數(shù)據(jù)
如果你不需要以可閱讀形式查看密碼,采用 MD5 就足夠了。不幸的是,這里并不總是有可選項,如果你提供以加密形式存儲某人的信用卡信息,你可能需要在后面的某個地方進(jìn)行解密。
最早的一個解決方案是 Mcrypt 模塊,這是一個用于允許 PHP 高速加密的插件。Mcrypt 庫提供了超過 30 種用于加密的計算方法,并且提供口令確保只有你(或者你的用戶)可以解密數(shù)據(jù)。
讓我們來看看使用方法。下面的腳本包含了使用 Mcrypt 加密和解密數(shù)據(jù)的函數(shù):
<?php$data = "Stuff you want encrypted";$key = "Secret passphrase used to encrypt your data";$cipher = "MCRYPT_SERPENT_256";$mode = "MCRYPT_MODE_CBC";function encrypt($data, $key, $cipher, $mode) {// Encrypt datareturn (string) base64_encode ( mcrypt_encrypt ( $cipher, substr(md5($key),0,mcrypt_get_key_size($cipher, $mode)), $data, $mode, substr(md5($key),0,mcrypt_get_block_size($cipher, $mode)) ) );}function decrypt($data, $key, $cipher, $mode) {// Decrypt data return (string) mcrypt_decrypt ( $cipher, substr(md5($key),0,mcrypt_get_key_size($cipher, $mode)), base64_decode($data), $mode, substr(md5($key),0,mcrypt_get_block_size($cipher, $mode)) );}?>
mcrypt() 函數(shù)需要幾個信息:
- 需要加密的數(shù)據(jù)
- 用于加密和解鎖數(shù)據(jù)的口令,也稱為鍵。
- 用于加密數(shù)據(jù)的計算方法,也就是用于加密數(shù)據(jù)的算法。該腳本使用了 MCRYPT_SERPENT_256,但你可以從很多算法中選擇,包括 MCRYPT_TWOFISH192、MCRYPT_RC2、MCRYPT_DES、和 MCRYPT_LOKI97。
- 加密數(shù)據(jù)的模式。這里有幾個你可以使用的模式,包括電子密碼本(Electronic Codebook) 和加密反饋(Cipher Feedback)。該腳本使用 MCRYPT_MODE_CBC 密碼塊鏈接。
- 一個 初始化向量-也稱為 IV 或者種子,用于為加密算法設(shè)置種子的額外二進(jìn)制位。也就是使算法更難于破解的額外信息。
- 鍵和 IV 字符串的長度,這可能隨著加密和塊而不同。使用 mcrypt_get_key_size() 和 mcrypt_get_block_size() 函數(shù)獲取合適的長度;然后用 substr() 函數(shù)將鍵的值截取為合適的長度。(如果鍵的長度比要求的短,別擔(dān)心,Mcrypt 會用 0 填充。)
如果有人竊取了你的數(shù)據(jù)和短語,他們只能一個個嘗試加密算法直到找到正確的那一個。因此,在使用它之前我們通過對鍵使用 md5() 函數(shù)增加安全,就算他們獲取了數(shù)據(jù)和短語,入侵者也不能獲得想要的東西。
入侵者同時需要函數(shù),數(shù)據(jù)和口令,如果真是如此,他們可能獲得了對你服務(wù)器的完整訪問,你只能大清洗了。
這里還有一個數(shù)據(jù)存儲格式的小問題。Mcrypt 以難懂的二進(jìn)制形式返回加密后的數(shù)據(jù),這使得當(dāng)你將其存儲到 MySQL 字段的時候可能出現(xiàn)可怕錯誤。因此,我們使用 base64encode() 和 base64decode() 函數(shù)轉(zhuǎn)換為和 SQL 兼容的字母格式和可檢索行。
破解腳本
除了實驗多種加密方法,你還可以在腳本中添加一些便利。例如,不用每次都提供鍵和模式,而是在包含的文件中聲明為全局常量。
生成隨機(jī)密碼
隨機(jī)(但難以猜測)字符串在用戶安全中很重要。例如,如果某人丟失了密碼并且你使用 MD5 哈希,你不可能,也不希望查找回來。而是應(yīng)該生成一個安全的隨機(jī)密碼并發(fā)送給用戶。為了訪問你站點的服務(wù),另外一個用于生成隨機(jī)數(shù)字的應(yīng)用程序會創(chuàng)建有效鏈接。下面是創(chuàng)建密碼的一個函數(shù):
<?php function make_password($num_chars) { if ((is_numeric($num_chars)) && ($num_chars > 0) && (! is_null($num_chars))) { $password = ''; $accepted_chars = 'abcdefghijklmnopqrstuvwxyz1234567890'; // Seed the generator if necessary. srand(((int)((double)microtime()*1000003)) ); for ($i=0; $i<=$num_chars; $i++) { $random_number = rand(0, (strlen($accepted_chars) -1)); $password .= $accepted_chars[$random_number] ; } return $password; }}?>
使用腳本
make_password() 函數(shù)返回一個字符串,因此你需要做的就是提供字符串的長度作為參數(shù):
<?php$fifteen_character_password = make_password(15);?>
函數(shù)按照下面步驟工作:
- 函數(shù)確保 $num_chars 是非零的正整數(shù)。
- 函數(shù)初始化 $accepted_chars 變量為密碼可能包含的字符列表。該腳本使用所有小寫字母和數(shù)字 0 到 9,但你可以使用你喜歡的任何字符集合。(LCTT 譯注:有時候為了便于肉眼識別,你可以將其中的 0 和 O,1 和 l 之類的都去掉。)
- 隨機(jī)數(shù)生成器需要一個種子,從而獲得一系列類隨機(jī)值(PHP 4.2 及之后版本中并不需要,會自動播種)。
- 函數(shù)循環(huán) $num_chars 次,每次迭代生成密碼中的一個字符。
- 對于每個新字符,腳本查看 $accepted_chars 的長度,選擇 0 和長度之間的一個數(shù)字,然后添加 $accepted_chars 中該數(shù)字為索引值的字符到 $password。
- 循環(huán)結(jié)束后,函數(shù)返回 $password。
許可證
本篇文章,包括相關(guān)的源代碼和文件,都是在 The Code Project Open License (CPOL) 協(xié)議下發(fā)布。
via: http://www.codeproject.com/Articles/363897/PHP-Security
作者:SamarRizvi 譯者:ictlyh 校對:wxy
本文由 LCTT 原創(chuàng)翻譯,Linux中國 榮譽推出
來源: https://linux.cn/article-5868-1.html
Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

TosecurelyhandleauthenticationandauthorizationinPHP,followthesesteps:1.Alwayshashpasswordswithpassword_hash()andverifyusingpassword_verify(),usepreparedstatementstopreventSQLinjection,andstoreuserdatain$_SESSIONafterlogin.2.Implementrole-basedaccessc

To safely handle file uploads in PHP, the core is to verify file types, rename files, and restrict permissions. 1. Use finfo_file() to check the real MIME type, and only specific types such as image/jpeg are allowed; 2. Use uniqid() to generate random file names and store them in non-Web root directory; 3. Limit file size through php.ini and HTML forms, and set directory permissions to 0755; 4. Use ClamAV to scan malware to enhance security. These steps effectively prevent security vulnerabilities and ensure that the file upload process is safe and reliable.

In PHP, the main difference between == and == is the strictness of type checking. ==Type conversion will be performed before comparison, for example, 5=="5" returns true, and ===Request that the value and type are the same before true will be returned, for example, 5==="5" returns false. In usage scenarios, === is more secure and should be used first, and == is only used when type conversion is required.

The methods of using basic mathematical operations in PHP are as follows: 1. Addition signs support integers and floating-point numbers, and can also be used for variables. String numbers will be automatically converted but not recommended to dependencies; 2. Subtraction signs use - signs, variables are the same, and type conversion is also applicable; 3. Multiplication signs use * signs, which are suitable for numbers and similar strings; 4. Division uses / signs, which need to avoid dividing by zero, and note that the result may be floating-point numbers; 5. Taking the modulus signs can be used to judge odd and even numbers, and when processing negative numbers, the remainder signs are consistent with the dividend. The key to using these operators correctly is to ensure that the data types are clear and the boundary situation is handled well.

Yes, PHP can interact with NoSQL databases like MongoDB and Redis through specific extensions or libraries. First, use the MongoDBPHP driver (installed through PECL or Composer) to create client instances and operate databases and collections, supporting insertion, query, aggregation and other operations; second, use the Predis library or phpredis extension to connect to Redis, perform key-value settings and acquisitions, and recommend phpredis for high-performance scenarios, while Predis is convenient for rapid deployment; both are suitable for production environments and are well-documented.

TostaycurrentwithPHPdevelopmentsandbestpractices,followkeynewssourceslikePHP.netandPHPWeekly,engagewithcommunitiesonforumsandconferences,keeptoolingupdatedandgraduallyadoptnewfeatures,andreadorcontributetoopensourceprojects.First,followreliablesource

PHPbecamepopularforwebdevelopmentduetoitseaseoflearning,seamlessintegrationwithHTML,widespreadhostingsupport,andalargeecosystemincludingframeworkslikeLaravelandCMSplatformslikeWordPress.Itexcelsinhandlingformsubmissions,managingusersessions,interacti

TosettherighttimezoneinPHP,usedate_default_timezone_set()functionatthestartofyourscriptwithavalididentifiersuchas'America/New_York'.1.Usedate_default_timezone_set()beforeanydate/timefunctions.2.Alternatively,configurethephp.inifilebysettingdate.timez
