安全圈 | 专注于最新网络信息安全讯息新闻

首页

php安全座椅

作者 trentadue 时间 2020-02-14
all

該頁面旨在為開發者和管理者提供有關PHP安全的基本提示。請注意,為了確保Web應用的安全性,僅通過本頁說明的提示可能還不够。

PHP概要

PHP是最常用的服務器側面程式設計語言,根據W3 Techs 81.8%的Web服務器被採用。

作為開放源的科技PHP,是語言的同時Web框架也有這樣的點獨特,標準的Web框架機能被語言編入。和其他Web語言一樣,存在諸如圖書館等大型社區,有助於PHP程式設計的安全性。在致力於PHP網站的安全確保時,需要全部考慮這個3個側面(語言,框架,庫)的全部。

與其說PHP是慎重被設計了的語言,倒不如說是反復增長的語言,容易容易記述了不安全的PHP應用程序。為了安全地使用PHP,必須預先掌握那個潜在的危險性。

語言的問題點

指定弱型

PHP關於型號指定是鬆散。也就是說,在PHP中,不合適類型的數據會自動轉換成應該處理的類型。這個功能往往掩蓋了開發者錯誤和不適當的數據的插入,導致脆弱性(關於例子參照下麵的「輸入處理」)。

使用不進行隱式轉換的函數和運算子。例如,使用===而不是==並不是所有的運算子都具有嚴格的版本(如更大、更小等)。此外,在許多嵌入函數(in_array等)中,定義了類型較弱的比較函數。這使得難以描述合適的程式碼。

== === in_array == === in_array

例外處理和錯誤處理

大體上全部PHP嵌入函數和多的PHP庫不使用例外,用另外的方法(通知等)報告錯誤。囙此,即使有缺陷的程式碼也可以繼續執行。結果會覆蓋很多錯誤。在與PHP競爭的多種其他語言和大多數高階語言中,一旦開發者失誤或開發者無法預測的執行時發生錯誤,程式就會停止運行。這是最安全的對策。

讓我們看看下一個程式碼吧。此程式碼使用資料庫査詢來限制用戶名是否包含在黑名單中。

此程式碼可能在運行時發生各種錯誤。例如,由於密碼錯誤、服務器關閉等原因導致資料庫連接失敗,或者用戶端打開的連接被服務器關閉。在這種情況下,mysqli_函數組發出警告或通知,但不會發生例外或致命錯誤。總之,程式碼就那樣繼續。變數$row成為NULL。PHP$row[0]也評估為NULL,型號指定較弱(int)$row[0]評估為0。最終can_access_feature函數返回true,不管黑名單是否被刊登,都允許所有用戶訪問。

mysqli_ $row NULL $row[0] NULL (int)$row[0] can_access_feature true mysqli_ $row NULL $row[0] NULL (int)$row[0] can_access_feature true

使用這些本地資料庫API,您必須在每個地方添加錯誤檢查。但是,因為要求多餘的工作所以容易被省略,既定不安全。另外,需要很多規定的程式碼記述。囙此,除非有明確的原因,不能不採用本地驅動程序和精緻的錯誤檢查,建議使用PHP數據對象(PDO)來指定ERRMODE_WARNING標誌或ERRMODE_EXCEPTION標誌。對。

另外,在很多情况下,最好使用error_reporting函數將錯誤報告級別設定得盡可能高。請絕對不要抑制錯誤消息。請務必按照警告記下更堅固的程式碼。

php.ini

PHP程式碼的行動大體上取決於多種配寘值。這包括基本操作的變更,例如錯誤的處理方法。囙此,在所有環境中描述正確的操作程式碼是極難的業。由於關於這些設定的設定和要求根據庫的不同而不同,囙此很難適當地使用協力廠商程式碼。下麵的“設定”中對一部分進行了說明。

無用的嵌入函數

一般認為PHP安全用的嵌入函數多數被準備,不過(addslashes,mysql_escape_string,mysql_real_escape_string等),那個多淨是bug,實際對安全問題的處理不有用。這些函數的一部分正在被廢除和删除,但是從低相容性的策略開始,需要很長的時間。

addslashes mysql_escape_string mysql_real_escape_string addslashes mysql_escape_string mysql_real_escape_string

在PHP裏(上)array這個資料結構也被準備,在PHP編碼和內部寬廣地被使用,不過,這個排列和dexyonari一起做了的容易混淆的東西。由於這種混亂的原因,即使是積累了經驗的PHP開發者,也帶入了像Drupal SA-CORE-2014-005(參照補丁)一樣的重大的安全的脆弱性。

框架的問題點

URL路由

嵌入到PHP中的URL路由機制是使用目錄結構內的“.php”結束的檔案。從這裡產生象下麵一樣的脆弱性。

.htaccess .htaccess

輸入處理

攻擊者使用以下査詢字串時,

美元supplied_nonce成為排列。此後,strcmp()函數返回(這個對遙遠方便,不過,不是衝破例外)NULL。型指定的弱點和==(同一性)不是運算子=(相當性)因為使用運算子,比較成功(因為PHP中式NULL==0是真的)。囙此,攻擊者不用指定正確的nonce,就可以重置密碼。

$supplied_nonce strcmp() NULL === == NULL == 0 $supplied_nonce strcmp() NULL === == NULL == 0

與這個完全相同的問題,與PHP array資料結構的容易混淆組合,有由於Drupal SA-CORE-2014-005等的問題被惡用的可能。請參照惡用例子。

範本語言

PHP基本上是範本語言。可是,既定不進行HTML逃脫。為此,成為在Web應用程序的使用非常問題多的語言。請參照下麵的“XSS”區域。

其他缺點

除此之外,還有如既定開啟的CSRF對策機制等,Web框架應提供的重要功能。因為PHP初步性的Web框架附屬著,這個對於Web網站的製作充分實用,多的人CSRF對策沒有必要的知識製作Web網站。

協力廠商PHP程式碼

由於上述問題,PHP中記述的庫和項目往往是危險的。特別,如果恰當的Web框架沒被使用。因為乍一看好象無害的編碼安全的脆弱性也大量地潜藏的可能性,在Web上發現了的PHP編碼請不要信用。

不完全記述的PHP碼警告被發出的事多,容易引起問題。一般的解決辦法是關閉全部的通知,不過,這個與恰當的對應相反(上述參照),程式碼更加惡化。

定期更新

請注意定期更新正在運行的服務器上的PHP的視圖。每天新的脆弱性PHP找到,被發表。攻擊者經常利用任何服務器上的這種新的脆弱性。

有很多與安全相關的設定選項。下麵是其中一部分。

塞特Handler

PHP碼請設定為“SetHandler”使用目錄執行。在許多情况下,錯誤地使用“AddHander”目錄設定。這樣也可以操作,不過,其他的檔案也作為PHP編碼變得可執行。例如,檔名“foo.php.txt”作為PHP碼被處理,不過,如果這個檔不是打算執行的情况和(樣本程式碼等),是來自惡意的文件上傳的東西,成為非常嚴重的遠程執行的脆弱性有。

用戶輸入的結果或副產品的數據都不可靠。必須通過適當的方法驗證數據,或者進行過濾處理。這樣才可以看出數據沒有被污染。

$_SERVER $_GET $_POST $_REQUEST $_FILES $_COOKIE $_SERVER

上傳文件

從用戶接受的檔案,特別是其他用戶能下載那個的話,成為各種各樣的安全威脅的原因。特別,能考慮象下麵一樣的威脅。

因為PHP是能非常簡單地執行PHP編碼(簡單地有適當的副檔名的檔案)的設計,在PHP網站(PHP被安裝設定的全部的網站)中,保存上傳了的檔案的時候必定sanitizu的檔名特別重要。

$_FILES陣列處理中的一般錯誤

在互聯網上經常可以看到進行類似下麵程式碼處理的程式碼寵物。

在這裡,$mimeType是更恰當被確認了的檔案類型。這個方法會使服務器的資源消耗更多,但是可以防止用戶發送危險的檔案,欺騙程式碼使其置信為影像。影像檔案通常被認為是安全的檔案類型。

$_使用REQUEST

美元_REQUEST強烈建議您不要使用。不能推薦這個超級全域變數的理由,不僅僅是POST和GET的數據,根據請求被發送了的Cookie也包含在這個變數中。所有這些數據都匯總到一個佈局,囙此資料來源的定義幾乎是不可能的。這招致混亂,用程式碼變得容易犯錯誤。囙此,可能會導致安全問題。

SQL噴射的脆弱性如果有1個,Web網站的入侵變得可能。囙此,每個駭客都會首先突破SQL注射的脆弱性。囙此,修正SQL噴射的脆弱性是確保基於PHP的應用的安全的第一步。請遵守以下規則。

在SQL中絕對不進行數據的連接和內插

請不要使用連接來創建包含用戶數據的SQL字串。

請不要使用內插。

逃生是不安全的

mysql_real_escape_string不安全。關於SQL噴射的對策,請不要指望這個。

理由:所有變數使用mysql_real_escape_string,將其連接到査詢時,肯定會忘記一次的。那個一次成為致命傷。絕對不要忘記是誰都不可能的。另外,在SQL內也必須確實使用引號,但是在假定數據為數值的情况下,這是不自然的行為。代替,請使用預付語句或者,經常執行適當的SQL逃脫的同等的API(大部分的ORM除了做這個逃避以外,製作SQL)。

使用預付語句

預付語句非常安全。在預付語句中,數據已從SQL命令中分離。將所有用戶輸入的內容視為數據,並保持原始狀態保存在表格中。

請參照PHP檔案的“MySQLi prepared statements”和“PDO prepared statements”。

如果首碼語句無效

如果您需要創建動態査詢或設定不支持作為預付變數的變數,或者如果資料庫引擎不支持預付語句。例如,不支持PDO MySQL中的?作為LIMIT指定子。同時,預付語句在`SELECT`句子錶名和列等也不能使用。在這種情況下,如果在框架中準備了査詢生成器,就使用它。如果您沒有提供査詢創建器,您可以從Composer和Packagist中使用多個包。請不要使用自己的東西。

ORM

ORM(對象關係映射)是恰當的安全慣例。在PHP項目中即使使用ORM(Doctrine等)也可能受到SQL噴射攻擊。在ORM中插入査詢比通常要難得多,但是如果連接了ORM査詢,就會產生與SQL査詢連接時的脆弱性。囙此,發送到資料庫的字串絕對不要連接。ORM也對應於預付語句。

請務必檢查所使用的所有ORM的程式碼,並確認該程式碼所生成的SQL的執行將如何處理。確認不是內部連接值,而是使用了預付語句,或者遵守了適當的安全對策。

編碼問題

除了不得已的情况,使用UTF-8

許多新的攻擊向量是基於編碼的迂回。請使用UTF-8,除非您必須使用不同的編碼,否則資料庫和應用程序的字元集。

除了SQL以外,PHP中也存在幾個可執行且一般的注册。

殼式噴射

下麵列出的少數PHP函數是:

將字串作為形狀腳本或命令來執行。傳遞給這些函數的輸入(尤其是與函數不同的尾碼(尾碼)運算子)。根據設定,根據sheruskureputo的注射應用程序的設定和構成洩漏,也有服務器全體被奪取的可能性。這是非常危險的噴射,被認為是攻擊者的天堂。

除非有絕對的危險信心(這必須是白名單化),受污染的輸入(即,用戶進行了某些操作的輸入)請絕對不要交給上述函數。逃避和其他對策都沒有效果。為了回避各自的對策的向量多數存在。不成熟的開發者說的話請不要相信。

程式碼注入

以PHP為首,任何解釋語言都準備了接受字串並在語言中執行的函數。PHP中將此函數稱為eval()使用eval是非常壞的慣例。不僅在安全方面。如果eval以外沒有方法的事有絕對的信心,被污染了的輸入完全沒有的狀態使用eval。另外,eval通常執行得慢。

不要將preg_replace()函數與未縮略的用戶輸入一起使用。有效載荷在eval()中被評估。

反射也可能是程式碼噴射的缺陷。這是個高度的話題,請參攷有關迴響的合適檔案。

其他注釋

執行LDAP、XPath和字串的其他協力廠商應用程序對於噴射來說很脆弱。字串有時不是數據而是指令,所以要時刻留意,確保安全,然後傳遞到協力廠商庫。

有關XSS有下麵的2個劇本。各自有必要採取適當的對策。

無標記

大多數情况下,在輸出時,無需將未解脫的HTML標籤包含在用戶輸入數據中。例如,當翻轉文字方塊的值或輸出儲存格中的用戶數據時。

如果範本使用了標準PHP,或者使用了`echo`等,可以通過將'htmlspecialchars'或'htmlspecialchars'或'echars'等函數(實質上是'htmlspecialchars'的更方便的包裝器)應用於數據,來減輕XSS。但是,我不推薦這個。問題在於,必須記住每次都適用,即使一次忘記也會產生XSS的脆弱性。既定而又不安全的方法論,必須作為危險的東西來對待。

作為替代,推薦您使用默認的範本引擎,該範本引擎適用於HTML逃生(見下麵)。HTML請全部通過範本引擎傳遞。

如果不能切換到安全範本引擎,請使用以下函數將不可靠的全部數據:

在危險的要素(style,script,image src,a等)使用用戶輸入的時候,這個劇本不能減輕XSS,請注意。但是,一般不會這樣做。另外,請注意,不打算包含HTML標籤的輸出,需要全部用下麵函數過濾之後發送給瀏覽器。

不可靠的標籤

輸出時使用HTML標籤的輸入允許用戶輸入(富有的部落格評論、論壇投稿、部落格投稿等),當用戶不信任時,必須使用安全的編碼庫。但是,這通常是很困難的,實行也會比較慢。幾乎所有的應用程序XSS的脆弱性就是這個原因。OWASP ESAPI準備了用於對數據的各種部分進行編碼的程式碼組。同時,也有OWASP AntiSammy和PHP用的HTMLPurifier。無論哪一個都需要進行適當的設定和學習,但是要開發好的應用軟體,這些都是必不可少的。

範本發動機

在數據的輸出,以及從幾乎XSS脆弱性的防禦中支援程式師和設計者的範本引擎存在幾個。範本引擎的主要目的不是安全性,而是設計擴展的提高,但主要範本引擎的大部分會自動地逃脫輸出上的變數,如果有不能逃脫的變數的情况會強制開發者明示。囙此,變數的輸出帶有白名單的性質。這樣的引擎存在複數,不過,那個好例子是twig[1]。其他一般範本引擎包括Smarty、Haanga、Rain TPL。

因為手動應用了逃脫,過分容易忘記,XSS恰當的處理,用白名單管道逃脫的範本引擎不可缺少。同時,如果開發者重視安全性,必須採用既定安全的系統。

其他提示

CSRF對策在理論上很簡單,但是要正確實施還是很難的。首先,對CSRF的一些提示。

OWASP PHP CSRFGuard是表示CSRF的對策方法的碼斯尼寵物。只是複製粘貼這個是不够的。在不久的將來,可以複製&粘貼的版本可能得到吧(希望的觀測)。現時,這個和以下的提示組合應對。

PHP沒有附帶馬上就可用的認證模塊。您必須單獨實現或使用PHP框架。遺憾的是,大部分PHP框架都是由開放原始碼的開發商社區開發的,不是安全專家,離完美還差得很遠。接下來,給出幾個有益的提示。

會話管理

認為PHP既定的會話功能是安全的。生成PHPSessionID充分是隨機,不過,保存不一定安全。

應對會話劫持

將會話綁定到IP地址是恰當的慣例。這樣,您可以封锁大部分會話劫持腳本(但不能封锁)。但是,其中說不定有使用匿名化工具(Tor等)的用戶。這樣的使用者服務會造成障礙。

要實現此操作,您可以簡單地在創建會話時將用戶端的IP存儲在會話中,然後強制執行此操作。下一個程式碼寵物返回用戶端的IP地址。

禁用會話ID

違規(例如,IP地址2被觀測等)每當發生時,請禁用會話(Cookie的解除、會話保存的解除、追跡的删除)。日誌活動可能有用。很多的應用程序,登入用戶也通知(GMail等)。

會話ID

每次陞級時請滾動會話ID。例如,如果用戶登錄,會話的重要性就會發生變化,所以需要更改會話ID。

會話ID

會話ID一般認為守秘性高(貴)。請注意不要讓應用程序在任何地方曝光會話ID(尤其是被登入用戶綁定的情况)。請不要使用URL作為會話ID的媒體。

如果會話包含機密資訊,則必須經由TLS轉發會話ID。否則,埋伏攻擊者可執行會話劫持。

固定會話

用戶登錄後(或每項請求後)使用session_regenerate_id()禁用會話ID。

會話過期

在一定空閒時間之後,以及經過一定活動時間後會話必須過期。有效期過期處理意味著禁用並删除會話,如果另一個請求來了,則創建一個新的會話。

此外,關閉[註銷]按鈕,退出時取消所有會話的追跡箭頭。

空閒時間超時

如果當前請求已經從上次請求中超過X秒,則會話將過期。這需要每次請求時更新會話數據的請求時間。一般的設定時間是30分鐘,但很大程度上左右了應用程序的條件。

這個過期對登入到能够訪問公共的機器的用戶忘記註銷時有用。啟用會話劫持。

一般超時

如果當前會話持續一段時間,即使處於活動狀態,會話也會過期。根據這個變得容易掌握狀況。時間各不相同,但通常是1天到1周左右可以。要執行此操作,必須存儲會話的起始時間。

沉默寡言

用PHP腳本處理Cookie,有幾個訣竅。

不序列化

請絕對不要將Cookie中存儲的數據序列化。操作簡單,可能會新增作用範圍中的變數。

適當删除

要安全删除Cookie,請使用以下小寵物。

1確保瀏覽器中的Cookie有效期滿。2行是删除Cookie的標準方法(false不能存儲在Cookie)。3從腳本中删除第行的Cookie。很多導遊建議開發者使用time()-3600來過期,但如果瀏覽器的時間不正確,則有可能無法運行。

另外,使用session_name()可以獲得既定的PHP會話Cookie名稱。

Internet Explorer的問題點

作為傾向Internet Explorer的很多版本有關Cookie的問題。通常,將有效期限設定為0,以消除問題。

認證

自動登錄(Remember Me)功能

很多的網站對自動登錄功能有脆弱性。正確的方法是,對用戶生成1次限定的權杖,並將其保存到Cookie。為了驗證該權杖並分配給用戶,該權杖必須存在於應用的數據商店中。這個權杖必須與用戶名和密碼無關,安全且足够長的隨機數值是適當的。

為了防止對自動登錄的權杖的burotofosu攻擊,推薦這個。另外,請確保權杖的長度足够長。不然的話,攻擊者會對自動登錄用的權杖發起攻擊,不久就會沒有資格資訊登入用戶。

請參照「PHP Configuration Cheat Sheet」。

Achim-Achim at owasp.org

Andrew van der Stock

Luke Plant

OWASP Cheat Sheets Project Homepage

Developer Cheat Sheets(Builder)

Assesment Cheat Sheets(Breaker)

Mobile Cheat Sheets

OpSec Cheat Sheets(Defender)

Draft Cheat Sheets