整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          php的HTML輸入和輸出復(fù)雜凈化

          思維新建站官網(wǎng):www.inspinovation.cn

          文|何掌柜

          對于很多 web 應(yīng)用來說,簡單地轉(zhuǎn)義 HTML 是不夠的。 你可能想完全去除任何HTML,或者允許一小部分子集的 HTML 存在。 若是如此,則使用 HTML Purifier 庫。

          HTML Purifier 是一個經(jīng)過充分測試但效率比較低的庫。 這就是為什么如果你的需求并不復(fù)雜就應(yīng)使用htmlentities(), 因?yàn)樗男室斓枚唷?/p>

          HTML Purifier 相比 strip_tags() 是有優(yōu)勢的, 因?yàn)樗趦艋?HTML 之前會對其校驗(yàn)。 這意味著如果用戶輸入無效 HTML,HTML Purifier 相比 strip_tags() 更能保留 HTML 的原意。 HTML Purifier 高度可定制,允許你為 HTML 的一個子集建立白名單來允許這個 HTML 子集的實(shí)體存在輸出中。

          但其缺點(diǎn)就是相當(dāng)?shù)穆?,它要求一些設(shè)置,在一個共享主機(jī)的環(huán)境里可能是不可行的。 其文檔通常也復(fù)雜而不易理解。 以下示例是一個基本的使用配置。 查看文檔閱讀 HTML Purifier 提供的更多更高級的特性。

          示例

          // Include the HTML Purifier library

          require_once('htmlpurifier-4.4.0/HTMLPurifier.auto.php');

          // Oh no! The user has submitted malicious HTML, and we have to display it in our web app!

          $evilHtml = '

          Mua-ha-ha! Twiddling my evil mustache...

          ';

          // Set up the HTML Purifier object with the default configuration.

          $purifier = new HTMLPurifier(HTMLPurifier_Config::createDefault());

          $safeHtml = $purifier->purify($evilHtml);

          // $safeHtml is now sanitized. You can output $safeHtml to your users without fear!

          ?>

          陷阱

          以錯誤的字符編碼使用 htmlentities() 會造成意想不到的輸出。 在調(diào)用該函數(shù)時(shí)始終確認(rèn)指定了一種字符編碼,并且該編碼與將被凈化的字符串的編碼相匹配。 更多細(xì)節(jié)請查看 UTF-8 一節(jié)。

          使用 htmlentities() 時(shí),始終包含 ENT_QUOTES 和字符編碼參數(shù)。 默認(rèn)情況下,htmlentities() 不會對單引號編碼。多愚蠢的默認(rèn)做法!

          HTML Purifier 對于復(fù)雜的 HTML 效率極其的低??梢钥紤]設(shè)置一個緩存方案如APC來保存經(jīng)過凈化的結(jié)果以備后用。

          因思維新專注于高端網(wǎng)站訂制開發(fā),不僅僅為您建設(shè)網(wǎng)站,還為您做網(wǎng)絡(luò)營銷。

          .文件系統(tǒng)安全


          php如果具有root權(quán)限,且在腳本中允許用戶刪除文件,那么用戶提交數(shù)據(jù),不進(jìn)行過濾,就非常有可能刪除系統(tǒng)文件

          <?php// 從用戶目錄中刪除指定的文件$username = $_POST['user_submitted_name'];$userfile = $_POST['user_submitted_filename'];$homedir = "/home/$username";unlink ("$homedir/$userfile");echo "The file has been deleted!";?>

          上面的代碼,假設(shè)用戶提交的$userfile值是 ../etc/,那么/etc目錄就會被刪除

          防范文件系統(tǒng)攻擊,策略如下:

          只給php有限的權(quán)限

          用戶提交上來的變量要監(jiān)測和過濾,不能包含文件路徑等特殊字符

          盡量避免使用PHP操作文件(刪除),如果有這方面的需求,那用戶可刪除文件也必須是系統(tǒng)生成的隨機(jī)名稱,不可被用戶控制

          2.數(shù)據(jù)庫安全


          數(shù)據(jù)庫安全主要防范的是sql injection,即sql注入攻擊,提升數(shù)據(jù)庫安全的策略如下:

          不用使用root帳號或者數(shù)據(jù)庫所有者帳號連接數(shù)據(jù)庫,連接數(shù)據(jù)庫限定連接用戶的ip

          使用php的pdo擴(kuò)展,有效防止sql注入,除了安全方面的優(yōu)勢,php的pdo擴(kuò)展在性能方面有有很大優(yōu)勢

          請參看 http://php.net/manual/en/pdo.prepared-statements.php

          對一些敏感信息進(jìn)行加密,常見的比如對密碼進(jìn)行加密



          3.用戶數(shù)據(jù)過濾

          對用戶數(shù)據(jù)過濾,可以防范XSS和CSRF攻擊

          使用白名單(用戶輸入是固定模式)的方式

          比如用戶名只能使用數(shù)字字母,那么可以使用函數(shù)ctype_alnum判斷

          對用戶輸入使用函數(shù) htmlentities或者h(yuǎn)tmlspecialchars進(jìn)行處理,輸入url不允許傳入非http協(xié)議

          用戶身份驗(yàn)證使用令牌 token(csrf)

          http://htmlpurifier.org/ HTML Purifier 是開源的防范xss攻擊的有效解決方案,

          4.其他安全策略


          線上環(huán)境關(guān)閉錯誤報(bào)告(error_reporting,dislay_erros,可在php.ini中配置error_log路徑,記錄錯誤信息,這樣有助于發(fā)現(xiàn)可能的用戶攻擊)

          Register Globals,棄用(移除)的特性,不要使用

          魔術(shù)引號特性,不要開啟,在PHP-5.4中已經(jīng)被移除

          盡量使用PHP的最新版本,最新版本修復(fù)了已知的很多安全漏洞和bug

          代碼中嚴(yán)格遵守上述策略,基本能保證代碼不會有太多的安全漏洞,能防范常見攻擊。

          如果想要學(xué)習(xí)交流PHP的朋友,可以關(guān)注小編,私信【學(xué)習(xí)交流】手機(jī)用戶可以直接私信,電腦端尚未開放此功能,需要下載app,我已經(jīng)設(shè)置了自動回復(fù),具體后續(xù)會自動回復(fù)各位。

          言#

          2018 年將至,一般程序員(特別是 Web 開發(fā)程序員)應(yīng)當(dāng)拋棄過去開發(fā)PHP程序的很多不好的習(xí)慣和觀念了。雖然部分人不以為意,但是這確實(shí)是事實(shí)。

          這個指南應(yīng)該以重點(diǎn)部分作為 PHP: The Right Way 安全章節(jié)的補(bǔ)充,而不是以一般的 PHP 編程話題。

          正文#

          PHP 版本#

          請?jiān)?2018 年使用 PHP 7.2, 并且計(jì)劃 2019 年初切換到 PHP 7.3。

          PHP 7.2 已于 2017 年 11 月 30 日發(fā)布。

          寫這篇文章的時(shí)候,只有 7.1 和 7.2 版本還在被 PHP 官方積極維護(hù),而 5.6 和 7.0 只在大概1年內(nèi)提供安全補(bǔ)丁更新。

          對于其他官方不維護(hù)的 PHP 版本,雖然某些操作系統(tǒng)會提供長期支持和維護(hù),但這其實(shí)通常是有害的。尤其是他們提供安全支持補(bǔ)丁卻沒有版本號,這使得很難解釋系統(tǒng)的安全性(僅僅知道 PHP 版本)。

          因此,無論其他供應(yīng)商提出了什么承諾,如果可以,你就應(yīng)該在任何時(shí)候都堅(jiān)決地使用官方提供支持的 PHP 版本。這樣,盡管最終是一個短暫的安全版本,但一個不斷致力于升級的版本,總會讓你收獲一些意外的驚喜。

          依賴管理#

          人生苦短,我用 Composer

          在 PHP 生態(tài)中,Composer 是最先進(jìn)的依賴管理方案。我們推薦 PHP: The Right Way 中關(guān)于依賴管理的完整章節(jié)。

          如果你沒有使用 Composer 來管理應(yīng)用的依賴,最終(hopefully later but most likely sooner)會導(dǎo)致應(yīng)用里某個依賴會嚴(yán)重過時(shí),然后老舊版本中的漏洞會被利用于計(jì)算機(jī)犯罪。

          重要: 開發(fā)軟件時(shí),時(shí)常記得保持依賴的更新。幸運(yùn)地,這只需一行命令:

          composer update

          如果你正在使用某些專業(yè)的,需要使用 PHP 擴(kuò)展(C 語言編寫),那你不能使用 Composer 管理,而需要 PECL 。

          推薦擴(kuò)展#

          不管你正在編寫什么,你總會受益于這些依賴。這是除了大多數(shù) PHP 程序員的推薦(PHPUnit, PHP-CS-Fixer, ...)外的補(bǔ)充。

          roave/security-advisories

          Roave's security-advisories 使用 Friends of PHP repository 確保你的項(xiàng)目沒有依賴一些已知易受攻擊的依賴。

          composer require roave/security-advisories:dev-master

          或者,你可以上傳你的composer.lock文件到 Sensio Labs ,作為例行自動化漏洞評估工作流的一部分,以提醒發(fā)現(xiàn)任何過時(shí)的軟件包。

          vimeo/psalm

          Psalm 是一個幫助你識別代碼里可能存在 bugs 的靜態(tài)分析工具。還有其他很好的靜態(tài)分析工具(例如 Phan 和 PHPStan 都很棒),但當(dāng)你發(fā)現(xiàn)你需要支持 PHP 5,Psalm 將是 PHP 5.4+ 的首選。

          使用 Psalm 挺簡單:

          如果你是第一次在現(xiàn)有代碼庫運(yùn)行,可能會看到很多紅色錯誤。但除非你在構(gòu)建像 WordPress 那么大的程序,否則努力通過所有測試絕不是艱巨的。

          無論使用哪種靜態(tài)分析工具,我們都推薦你能將他加入到持續(xù)集成工作流(Continuous Integration workflow)中,以便在每次更改代碼中運(yùn)行。

          HTTPS 和瀏覽器安全#

          HTTPS, which should be tested, and security headers .

          2018 年,不安全的 HTTP 網(wǎng)站將不再被接受。幸運(yùn)的是,由于 ACME 協(xié)議 和 Let's Encrypt certificate authority,免費(fèi)的 TLS 證書成為了可能。

          將 ACME 集成到你的服務(wù)器,小菜一碟。

          • Caddy: 自動加入。

          • Apache: 很快作為mod_md可用。在此之前,網(wǎng)上很多高質(zhì)量教程。

          • Nginx: 相對簡單。

          你也許會想,“好,我已經(jīng)有 TLS 證書了,為了網(wǎng)站變得安全和快速,得花些時(shí)間折騰配置信息?!?/p>

          不!Mozilla做了件好事情!。你可以根據(jù)網(wǎng)站的目標(biāo)受眾,使用配置生成器生成推薦套件。

          如果你希望網(wǎng)站安全,HTTPS ( HTTP over TLS ) 是絕對不能妥協(xié)的。使用 HTTPS 立刻就能消除多種攻擊(中間人攻擊、竊聽、重放攻擊以及若干允許用戶模仿的會話形式的攻擊)。

          安全頭#

          在服務(wù)器使用 HTTPS 確實(shí)為用戶提供了許多安全性和性能方面的好處,但也還能通過利用某些瀏覽器的安全功能來進(jìn)一步提升安全性。而這大部分會涉及到響應(yīng)內(nèi)容的安全頭。

          • 1、Content-Security-Policy

          • 你需要該 Header ,因?yàn)樗峁┝藢τ跒g覽器是否允許加載內(nèi)部和外部資源的細(xì)化控制,從而為跨域腳本攻擊漏洞提供了有效防御層。

          • 參閱 CSP-Builder,以便快速簡便地部署/管理內(nèi)容安全策略(Content Security Policies)。

          • 為了更加深入的分析, Scott Helme's introduction to Content-Security-Policy headers,會是一個很好的引導(dǎo)。

          • 2、Expect-CT

          • 你需要該 Header ,因?yàn)樗芡ㄟ^強(qiáng)制某些不良行為者將其錯誤證書的證據(jù)頒發(fā)到可公開驗(yàn)證的僅可追加的數(shù)據(jù)結(jié)構(gòu),從而針對流氓/受損的證書頒發(fā)機(jī)構(gòu)增加一層防護(hù)。

          • 優(yōu)先設(shè)置為enforce,max-age=30。只要你有足夠的自信該 Header 不會造成服務(wù)中斷,增加max-age吧。

          • 3、Referrer-Policy

          • 你需要該 Header ,因?yàn)樗试S你控制用戶的行為信息是否泄露給第三方。

          • 同樣地,Scott Helme 提供了一篇關(guān)于Referrer-Policy Header 介紹好文。

          • 除非有理由允許更加寬松的設(shè)置,否則請?jiān)O(shè)置為same-origin或no-referrer。

          • 4、Strict-Transport-Security

          • 你需要該 Header ,因?yàn)樗嬖V瀏覽器通過 HTTPS 而不是不安全的 HTTP ,將 future requests 設(shè)為同源。

          • 在第一次部署時(shí),將其設(shè)置為max-age = 30,然后當(dāng)你確信沒有任何內(nèi)容會中斷時(shí),將此值增加到某個較大的值(例如 31536000)。

          • 5、X-Content-Type-Options

          • 你需要該 Header ,因?yàn)?MIME 類型的混淆可能會導(dǎo)致不可預(yù)知的結(jié)果,包括奇怪的允許 XSS 漏洞的邊緣情況。這最好伴隨著一個標(biāo)準(zhǔn)的 Content-Type Header 。

          • 除非需要默認(rèn)的行為(例如文件的下載),否則請?jiān)O(shè)置為nosniff。

          • 6、X-Frame-Options

          • 你需要該 Header ,因?yàn)樗试S你防止點(diǎn)擊劫持。

          • 設(shè)置為DENY (或者SAMEORIGIN, 但僅僅當(dāng)你使用<frame>元素的時(shí)候)。

          • 7、X-XSS-Protection

          • 你需要該 Header ,因?yàn)樗鼏⒂昧艘恍┠J(rèn)情況下未啟用的瀏覽器反 XSS 功能。

          • 設(shè)置為1; mode=block。

          同樣,如果你使用 PHP 的內(nèi)置會話管理功能(建議使用),則可能需要這樣調(diào)用session_start():

          這會強(qiáng)制你的應(yīng)用在發(fā)送會話標(biāo)識符時(shí)使用 HTTP-Only 和 Secure 標(biāo)志,從而防止 XSS 攻擊竊取用戶的 Cookie ,并強(qiáng)制它們分別通過 HTTPS 發(fā)送。 我們之前在 2015 年的博客文章中介紹了安全的 PHP 會話。

          子資源完整性#

          在將來的某個時(shí)候,你也許會使用 CDN 來加載網(wǎng)站的公共 JavaScript/CSS 庫。安全工程師已經(jīng)遇見了這存在一個明顯的風(fēng)險(xiǎn),如果很多網(wǎng)站使用 CDN 提供內(nèi)容,Hack 和替換 CDN(獲得了 CDN 的控制權(quán))就可以注入(惡意)代碼到成千上萬的網(wǎng)站。

          查閱子資源完整性吧。

          子資源完整性(SRI,Subresource integrity)允許你將希望 CDN 服務(wù)的文件的內(nèi)容進(jìn)行哈希處理。目前實(shí)行的 SRI 只允許使用安全的密碼散列函數(shù),這意味著攻擊者不可能生成與原始文件哈希相同的惡意版本資源。

          一個真實(shí)例子: Bootstrap v4-alpha uses SRI in their CDN example snippet

          文檔關(guān)系#

          Web 開發(fā)人員經(jīng)常在超鏈接上設(shè)置目標(biāo)屬性(例如,target ="_ blank"在新窗口中打開鏈接)。但是,如果你沒有傳遞rel ="noopener"標(biāo)簽,則可以允許目標(biāo)頁面控制當(dāng)前頁面。

          不要這樣做:

          這會讓http://example.com頁面能控制當(dāng)前頁面。

          而應(yīng)該這樣做:

          通過這樣在新窗口打開https://example.com,當(dāng)前窗口的控制權(quán)也不會授予可能的惡意第三方。

          可以更加深入研究。

          開發(fā)安全的 PHP 程序#

          如果應(yīng)用程序安全性對你來說是一個新話題,請從應(yīng)用程序安全性簡介開始吧。

          大多數(shù)安全專家指出,開發(fā)者可以使用 OWASP Top 10 等資源開始著手。

          但是,大多數(shù)常見的漏洞也可以是相同高等級的安全問題(例如代碼和數(shù)據(jù)沒有完全分離、邏輯不嚴(yán)謹(jǐn)和健全、操作環(huán)境不安全或是可破譯的密碼協(xié)議等)。

          我們的假設(shè)是,應(yīng)該授予安全新手知道一些更簡單、基礎(chǔ)的安全知識和問題,并如何解決這些問題,應(yīng)該是一個更好的、長遠(yuǎn)的安全工程。

          因此,我們避免推薦十大或二十大安全清單。

          數(shù)據(jù)庫注入#

          避免 PHP 程序存在 SQL 注入。

          如果你是自己編寫 SQL 代碼,請確保使用prepared語句,并且從網(wǎng)絡(luò)或文件系統(tǒng)提供的信息都作為參數(shù)傳遞,而不是字符串拼接的形式。此外,確保你沒有使用模擬的prepared語句。

          為了達(dá)到好的效果,可以使用 EasyDB 。

          不要這樣做:

          應(yīng)該這樣做:

          還有其他數(shù)據(jù)庫抽象層提供了相同的安全性(EasyDB實(shí)際上是在使用 PDO ,但在實(shí)際的prepare語句前避免了prepared語句模擬)。 只要用戶輸入不會影響查詢的結(jié)構(gòu),就很安全(包括存儲過程)。

          文件上傳#

          深入:如何安全地允許用戶上傳文件?

          接受文件上傳是一個冒險(xiǎn)的提議,但只要采取一些基本的預(yù)防措施,是能保證安全的。也就是說,允許文件直接上傳的話,這些文件可能會被意外的允許執(zhí)行或解釋。上傳的文件應(yīng)該是只讀(read-only)或讀寫(read-write)的,永遠(yuǎn)不應(yīng)該可執(zhí)行(executable)。

          如果你的網(wǎng)站根目錄是/var/www/example.com,請不要保存上傳文件在/var/www/example.com/uploaded_files。

          而應(yīng)該保存到一個不能直接訪問的目錄(例如:/var/www/example.com-uploaded/),以免意外地將其作為服務(wù)器端腳本執(zhí)行,并獲得執(zhí)行遠(yuǎn)程代碼的后門。

          一個更加簡潔的方法是將網(wǎng)站根目錄往下移動一個層級(即:/var/www/example.com/public)。

          如何安全地下載這些上傳文件也是一個問題。

          • 直接訪問 SVG 圖像類型時(shí),將在用戶瀏覽器執(zhí)行 JavaScript 代碼。盡管它的MIME類型中的image/前綴具有誤導(dǎo)性,但是這是正確的。

          • 正如前面提及的,MIME 類型嗅探可能導(dǎo)致類型混淆攻擊。請參閱X-Content-Type-Options。

          • 如果你放棄前面關(guān)于如何安全地存儲上傳文件的建議,攻擊者就會通過上傳 .php 或 .phtml 文件,直接在瀏覽器中訪問文件來執(zhí)行任意代碼,從而完全控制服務(wù)器。

          跨站腳本#

          關(guān)于 PHP 中的跨站腳本攻擊,你想知道的都在這里

          同樣地,預(yù)防 XSS 和 SQL 注入是一樣簡單的。我們有簡單而易用的 API 來分離文檔結(jié)構(gòu)(structure of a document)和填充的數(shù)據(jù)。

          然而,實(shí)際上還有很多 Web 開發(fā)程序員仍是通過生成一大串 HTML 代碼作為響應(yīng)的形式開發(fā)。并且,這不是 PHP 獨(dú)有的現(xiàn)實(shí),這是所有 Web 開發(fā)程序員都應(yīng)該重視的。

          減少 XSS 漏洞不失為一個好方法??傊?,前面談及的瀏覽器安全的章節(jié)就顯得十分相關(guān)了。簡言之:

          • 盡量避免輸出和輸入(Always escape on output, never on input)。如果你把已清洗的數(shù)據(jù)(sanitized data)保存在數(shù)據(jù)庫,然后在其它地方被發(fā)現(xiàn)了 SQL 注入漏洞,攻擊者將通過惡意程序污染這些受信任的已清洗數(shù)據(jù)(trusted-to-be-sanitized record),從而繞開 XSS 保護(hù)。

          • 如果你的框架有一個提供自動上下文過濾的模板引擎,那就使用它吧。這些工作可由框架安全地做到。

          • echo htmlentities($ string,ENT_QUOTES | ENT_HTML5,'UTF-8') 是一種安全、有效的方法阻止UTF-8編碼的網(wǎng)頁上的所有 XSS 攻擊,但不是任何 HTML 都有效。

          • 如果你的環(huán)境要求你使用 Markdown 而不是 HTML ,那就不要使用 HTML 了。

          • 如果你需要使用原生 HTML(沒有使用模板引擎),參閱第一點(diǎn),并且使用 HTML Purifier 吧。HTML Purifier 不適合轉(zhuǎn)義為 HTML 屬性上下文(HTML attribute context)。

          跨站請求偽造#

          跨站請求偽造(CSRF)是一種混淆的代理攻擊,通過誘導(dǎo)用戶的瀏覽器代表攻擊者執(zhí)行惡意的 HTTP 請求(使用的是該用戶的權(quán)限)。

          這在一般情況下是很容易解決的,只需兩步:

          • 使用 HTTPS 。這是先決條件。沒有 HTTPS 的話,任何保護(hù)措施都是脆弱的,雖然 HTTPS 本身并不防御 CSRF 。

          • 增加基本的 Challenge-response authentication。

          • 為每個表單添加一個隱藏的表單屬性。

          • 填充一個密碼安全的隨機(jī)值(稱為令牌)。

          • 驗(yàn)證是否提供了隱藏的表單屬性,以及是否匹配上期望值。

          我們寫了一個名為 Anti-CSRF 的庫,并且:

          • 你可以使每個令牌只能使用一次,以防止重放攻擊。

          • 多個令牌存儲在后端。

          • 一旦令牌獲取完,令牌會循環(huán)使用。

          • 每個令牌可以綁定特定的 URL 。

          • 如果某個令牌泄露了,它不能在不同的上下文使用。

          • 令牌可以綁定特定的 IP 地址。

          • v2.1 后,令牌可以重復(fù)使用(例如供 Ajax 使用)。

          如果你沒有使用防止 CSRF 漏洞的框架,請將 Anti-CSRF 放在一邊。在不久的將來,SameSite cookies將允許我們更簡單地避免CSRF攻擊。

          XML 攻擊 (XXE, XPath Injection)#

          在處理大量 XML 的應(yīng)用程序中存在兩個主要的漏洞:

          • XML External Entities (XXE)

          • XPath 注入

          除此之外, XXE 攻擊可用作包含攻擊代碼的本地/遠(yuǎn)程文件的啟動器。

          早期版本的 Google Docs 被著名于 XXE ,但除了在很大程度上使用 XML 的商業(yè)應(yīng)用程序之外,基本聞所未聞。

          針對 XXE 襲擊的主要緩解措施:

          除 XML 文檔外,XPath注入與 SQL 注入非常相似。

          幸運(yùn)的是,將用戶輸入傳遞給 XPath 查詢的情況在 PHP 生態(tài)中非常罕見。

          而不幸的是,這也意味著 PHP 生態(tài)中不存在可用的最佳避免措施(預(yù)編譯和參數(shù)化 XPath 查詢)。最好的辦法是在任何涉及 XPath 查詢的數(shù)據(jù)上設(shè)置允許使用的字符白名單。

          白名單總會比黑名單更安全。

          反序列化和 PHP 對象注入#

          深入: 在PHP中安全地實(shí)現(xiàn)(反)序列化

          如果你將不可信的數(shù)據(jù)傳遞給unserialize(),則通常是這兩個結(jié)果之一:

          • PHP 對象注入,它能用于啟動 POP 鏈(POP chain)并觸發(fā)其他誤用對象的漏洞。

          • PHP 解釋器本身的內(nèi)存損壞。

          大多數(shù)開發(fā)人員更喜歡使用JSON序列化,這是對其軟件安全狀況的顯著改進(jìn)。但請記住,json_decode()容易受到散列沖突拒絕服務(wù)(Hash-DoS)攻擊。不幸的是,PHP的Hash-DOS問題還沒有得到徹底解決。

          從djb33遷移到Siphash,對于字符串輸入,哈希輸出的最高位設(shè)置為 1 ,對于整數(shù)輸入設(shè)置為 0 ,使用CSPRNG提供的請求密鑰,將完全解決這些攻擊。

          不幸的是, PHP 團(tuán)隊(duì)還沒有準(zhǔn)備好放棄他們已經(jīng)在 PHP 7 系列中取得的性能提升,所以很難說服他們放棄 djb33 (這是非??斓话踩模?贊成 SipHash (這也是快速的,但不像 djb33 那么快,但更安全)。 如果性能受到重大影響,可能會阻礙未來版本的采用,但也影響了安全性。

          因此,最好的辦法是:

          • 使用JSON,因?yàn)樗萿nserialize()更安全。

          • 在任何可能的地方,確保輸入在反序列化之前被認(rèn)證。

          • 對于提供給用戶的數(shù)據(jù),通過一個只有服務(wù)器知道的秘鑰使用sodium_crypto_auth()和sodium_crypto_auth_verify()驗(yàn)證。

          • 對于第三方提供的數(shù)據(jù),讓他們使用sodium_crypto_sign()簽名他們的 JSON 消息,

            然后使用sodium_crypto_sign_open()和第三方公鑰驗(yàn)證消息。

          • 如果你需要對傳輸?shù)暮灻M(jìn)行十六進(jìn)制或 Base64 位編碼,也可以使用分離的簽名 API 。

          • 如果你無法驗(yàn)證 JSON 字符串,請嚴(yán)格限制速度并阻止 IP 地址,以減輕重復(fù)的違規(guī)者。

          密碼散列#

          深入:2016 年,如何安全地保存用戶密碼

          安全的密碼存儲曾經(jīng)是一個激烈爭論的話題,但現(xiàn)在實(shí)現(xiàn)起來相當(dāng)微不足道,特別是在 PHP 中:

          你甚至不需要知道在后臺使用什么算法,因?yàn)槿绻闶褂米钚掳姹镜?PHP ,你也將使用當(dāng)前最新的技術(shù),用戶的密碼將會自動進(jìn)行升級(只要有新的默認(rèn)算法可用)。

          無論你做什么,都不要做 WordPress 所做的事情。

          從 PHP 5.5 到 7.2 ,默認(rèn)算法都是 Bcrypt 。在未來,它可能會切換到獲得密碼哈希大賽冠軍的 Argon2 。

          如果你以前沒有使用password_* API ,那需要遷移遺留哈希,請確保以這種方式進(jìn)行。很多公司搞錯了, 最有名的是雅虎。 最近,錯誤地實(shí)施傳統(tǒng)哈希升級似乎導(dǎo)致了蘋果的iamroot錯誤。

          通用加密#

          這是一些我們詳細(xì)寫了的話題:

          • Using Encryption and Authentication Correctly (2015)

          • Recommended: Choosing the Right Cryptography Library for your PHP Project: A Guide (2015)

          • Recommended: You Wouldn't Base64 a Password - Cryptography Decoded (2015)

          • Cryptographically Secure PHP Development (2017)

          • Recommended: Libsodium Quick Reference: Similarly-Named Functions and Their Use-Cases (2017)

          一般來說,你總是希望使用 Sodium cryptography library(libsodium)進(jìn)行應(yīng)用層加密。如果你需要支持早于 7.2 的 PHP 版本(像 5.2.4),你可以使用sodium_compat,基本上可以假設(shè)你的用戶也是 7.2 。

          在特定情況下,由于嚴(yán)格的算法選擇和互操作性,你可能需要不同的庫。如有疑問,請咨詢密碼專家和密碼工程師,了解密碼選擇是否安全(這是我們提供的服務(wù)之一)。

          隨機(jī)性#

          深入:如何在 PHP 中生成安全的整數(shù)和字符串?

          如果你需要隨機(jī)數(shù)字,請使用random_int()。如果你需要隨機(jī)字節(jié)字符串,請使用random_bytes()。不要使用mt_rand(),rand()或uniqid()。

          如果你需要從秘密種子(secret seed)生成偽隨機(jī)數(shù)(pseudorandom),請使用SeedSpring,而不是srand()或mt_srand()。

          服務(wù)器端 HTTPS 請求#

          確保 TLS 證書驗(yàn)證沒有被禁用

          隨意使用你已經(jīng)熟悉的任何兼容 PSR-7 的 HTTP 客戶端。 我們喜歡 Guzzle ,有些人喜歡直接使用 cURL 。

          無論你最終使用什么,請確保使用的確定性,以確保始終可以擁有最新的 CACert 軟件包,從而允許啟用最嚴(yán)格的 TLS 證書驗(yàn)證設(shè)置并保護(hù)服務(wù)器的出站 HTTPS 請求。

          安裝 Certainty 很簡單:

          composer require paragonie/certainty:^1

          使用 Certainty 也很簡單:

          這樣可以保護(hù)你免受網(wǎng)絡(luò)服務(wù)器與集成的任何第三方 API 之間的中間人攻擊。

          我們真的需要 Certainty 嗎?

          保護(hù)你的系統(tǒng), Certainty 并不是嚴(yán)格的要求。缺少它并不是什么漏洞。但如果沒有 Certainty ,開源軟件必須猜測操作系統(tǒng)的 CACert 軟件包的存在位置,如果猜測錯誤,它往往會失敗并導(dǎo)致可用性問題。從歷史上看,這激勵了許多開發(fā)人員只是禁用證書驗(yàn)證,以便他們的代碼“正常工作”,卻沒有意識到他們只是將應(yīng)用程序變成主動攻擊。 Certainty 通過將 CACert 捆綁在最新的可預(yù)測位置來消除這種激勵。 Certainty 還為希望運(yùn)行自己的內(nèi)部 CA 為企業(yè)提供大量的工具。

          誰禁用了證書驗(yàn)證?

          流行的內(nèi)容管理系統(tǒng)(WordPress,Magento 等 CMS)的插件/擴(kuò)展開發(fā)者!這是我們試圖在生態(tài)系統(tǒng)層面上解決的一個巨大的問題。 它不是孤立的任何特定的 CMS ,你會發(fā)現(xiàn)這些不安全的插件等都是類似的。

          如果使用了類似的 CMS ,請?jiān)诓寮兴阉鰿URLOPT_SSL_VERIFYPEER和CURLOPT_SSL_VERIFYHOST,你可能會發(fā)現(xiàn)有幾個將這些值設(shè)置為FALSE。

          避免的事情#

          • 不要使用mcrypt。這是一個十多年來沒有開發(fā)出來的密碼學(xué)庫。如果你遵循我們的 PHP 版本建議,這應(yīng)該是一個容易避免的錯誤,因?yàn)閙crypt不再被 PHP 7.2 和更新的版本支持。

          • 配置驅(qū)動的安全建議應(yīng)該大部分地忽略。如果你正在閱讀 PHP 安全性指南,并告訴你更改 php.ini 設(shè)置而不是編寫更好的代碼,那么你可能正在閱讀過時(shí)的建議。關(guān)閉窗口并轉(zhuǎn)到一些和register_globals無關(guān)的文章上吧。

          • 不要使用 JOSE(JWT,JWS,JWE),這是一套互聯(lián)網(wǎng)標(biāo)準(zhǔn),它編纂了一系列容易出錯的密碼設(shè)計(jì)。盡管由于某種原因,被寫入了標(biāo)準(zhǔn),也吸引了很多傳道人。

          • 加密 URL 參數(shù)是公司常用來模糊元數(shù)據(jù)的反模式(例如,我們有多少用戶?)。 它帶來了實(shí)施錯誤的高風(fēng)險(xiǎn),也造成了錯誤的安全感。我們在鏈接的文章中提出了一個更安全的選擇。

          • 除非迫不得已,否則不要提供“我忘記了我的密碼”的功能。

            不要諱言:密碼重置功能是一個后門。 有一些方法可以實(shí)施以抵御合理的威脅模型,但高風(fēng)險(xiǎn)用戶應(yīng)該不被考慮。

          • 避免使用 RSA,改用 libsodium 。如果你必須使用 RSA ,請確保指定 OAEP 填充。

          如果你不得不使用 PKCS#1 v1.5 填充,那么無論你與哪個集成在一起,幾乎肯定會受到 ROBOT 的影響,請以允許明文泄露和簽名偽造的漏洞將其報(bào)告給相應(yīng)的供應(yīng)商(或 US-CERT )。

          專業(yè)用法#

          現(xiàn)在你已經(jīng)掌握了在 2018 年及以后構(gòu)建安全 PHP 應(yīng)用程序的基礎(chǔ)知識,接下來我們來看一些更專業(yè)的用法。

          可搜索的加密#

          深入:使用PHP和SQL構(gòu)建可搜索的加密數(shù)據(jù)庫

          可搜索的加密數(shù)據(jù)庫是可取的,但被廣泛認(rèn)為是不太可能實(shí)現(xiàn)的。上面鏈接的博客文章試圖通過改進(jìn)我們解決方案來實(shí)現(xiàn),但本質(zhì)上是這樣的:

          • 設(shè)計(jì)你的架構(gòu),以便數(shù)據(jù)庫(database compromise)不會讓攻擊者訪問你的加密密鑰。

          • 用一個密鑰加密數(shù)據(jù)。

          • 基于 HMAC 或具有靜態(tài)鹽的安全 KDF (secure KDF with a static salt)創(chuàng)建多個索引(具有自己獨(dú)特的密鑰)

          • 可選:截?cái)嗖襟E3的輸出,將其用作布隆過濾器(Bloom filter)

          • 在 SELECT 查詢中使用步驟3或4的輸出

          • 解密結(jié)果。

          在這個過程中的任何一步,你都可以根據(jù)實(shí)際使用情況進(jìn)行不同的權(quán)衡。

          沒有 Side-Channels 的基于令牌的身份驗(yàn)證#

          深入: Split Tokens: Token-Based Authentication Protocols without Side-Channels

          說到數(shù)據(jù)庫(上一節(jié)),你是否知道 SELECT 查詢理論上可能是定時(shí)信息泄漏的來源?

          簡單的緩解措施:

          • 把你的認(rèn)證令牌分為兩半

          • 一半在 SELECT 查詢中使用

          • 后一半在恒定的時(shí)間(constant-time)驗(yàn)證

          • 可以選擇將后半部分的散列存儲在數(shù)據(jù)庫中。這對于只能使用一次的令牌是有意義的,例如 密碼重置或“在此計(jì)算機(jī)上記住我”的令牌

          即使可以使用定時(shí)泄漏來竊取一半的令牌,剩下的也需要暴力破解才能成功。

          開發(fā)安全的API#

          深入: Hardening Your PHP-Powered APIs with Sapient

          我們寫了 SAPIENT (the Secure API ENgineering Toolkit),讓服務(wù)器到服務(wù)器驗(yàn)證的消息傳遞變得簡單易行。除了 HTTPS 提供的安全性之外,Sapient允許你使用共享密鑰或公鑰來加密和驗(yàn)證消息。 這使得即使存在中間攻擊者,并設(shè)有流氓證書頒發(fā)機(jī)構(gòu),你也可以使用Ed25519對 API 請求和響應(yīng)進(jìn)行身份驗(yàn)證,或者將消息加密到只能由接收方服務(wù)器的密鑰解密的目標(biāo)服務(wù)器。 由于每個 HTTP 消息體都通過安全密碼進(jìn)行身份驗(yàn)證,所以可以安全地使用它來代替stateful token juggling protocols(例如 OAuth)。但是,在密碼學(xué)方面,在做任何不規(guī)范的事情之前,總要確保他們的實(shí)現(xiàn)是由專家研究的。

          所有Sapient使用的密碼算法都由Sodium cryptography library提供。

          進(jìn)一步閱讀:

          • Sapient Documentation

          • Sapient Tutorial

          • Sapient Specification

          Paragon Initiative Enterprises已經(jīng)在其許多產(chǎn)品(包括許多開源軟件項(xiàng)目)中使用了Sapient,

          并將繼續(xù)添加軟件項(xiàng)目到Sapient用戶群中。

          使用Chronicle記錄安全事件#

          深入: Chronicle Will Make You Question the Need for Blockchain Technology

          Chronicle是一個基于散列鏈數(shù)據(jù)結(jié)構(gòu)的僅追加密碼分類賬(append-only cryptographic ledger),具有很多吸引公司“區(qū)塊鏈”技術(shù)的屬性,而不會過分矯枉過正。

          除了僅追加密碼分類賬(append-only cryptographic ledger)這個具有創(chuàng)造性的用例之外,Chronicle集成到SIEM中時(shí),也可以十分有亮點(diǎn),因?yàn)槟憧梢詫踩P(guān)鍵事件發(fā)送到私人Chronicle中,并且它們是不能被改變的。

          如果你的Chronicle設(shè)置為將其摘要散列交叉簽名到其他Chronicle實(shí)例,或者如果有其他實(shí)例配置為復(fù)制你的Chronicle內(nèi)容,攻擊者就很難篡改你的安全事件日志。

          在Chronicle的幫助下,你可以獲得區(qū)塊鏈所承諾的彈性特性(resilience),而沒有任何隱私,性能或可伸縮性問題。

          要將數(shù)據(jù)發(fā)布到本地Chronicle,你可以使用任何與Sapient-compatible API,但最簡單的解決方案稱為Quill。

          作者的一些話#

          一些聰明的讀者可能注意到我們引用了很多我們自己的工作,包括博客文章和開源軟件。(當(dāng)然也不僅僅引用了我們自己的工作)

          這絕不是偶然的。

          自從我們在 2015 年初成立以來,一直在編寫安全庫并參與提高 PHP 生態(tài)系統(tǒng)安全性的工作。我們已經(jīng)涉足了很多領(lǐng)域,而且我們的安全工程師(他們最近推動了更安全的加密技術(shù)加入 PHP 核心,就在最近的 PHP 7.2 中)自我擔(dān)保地說,并不擅長自我炒作,或是對已經(jīng)做過的工作持續(xù)熱情。但你很可能沒有聽說我們多年來開發(fā)的工具或庫。對于這個,深感抱歉。

          不論如何,我們也不可能成為各方面的先行者,所以我們盡可能地選擇與重視公共利益而不是貪圖小利的行業(yè)專家工作。

          這也是為什么瀏覽器安全的許多章節(jié)都參考了 Scott Helme 和他公司的工作,他們在為開發(fā)人員提供這些新的安全功能方面具有可訪問性和可理解性。

          本指南當(dāng)然不會是詳盡的。編寫不安全代碼的方法幾乎和編寫代碼的方法一樣多。 安全是一種心態(tài),而不是目的地。隨著上面所寫的一切,以及后面涉及的資源,我們希望這將有助于全世界的開發(fā)人員,從今天開始用 PHP 編寫安全的軟件。

          資源#

          如果你已經(jīng)按照本頁上的所有內(nèi)容進(jìn)行了操作,并且需要更多內(nèi)容,則可能會對我們策劃的閱讀列表感興趣,以便學(xué)習(xí)應(yīng)用程序安全性。

          如果你認(rèn)為自己編寫的代碼足夠安全,并希望我們從安全工程師的角度對其進(jìn)行評判,這也是我們?yōu)榭蛻籼峁┑姆?wù)。

          你如果為一家要進(jìn)行合規(guī)性測試(PCI-DSS,ISO 27001等)的公司工作,可能還想聘請我們公司來審核你的源代碼。我們的流程比其他安全咨詢公司更適合開發(fā)者。

          接下來是 PHP 和信息安全社區(qū)提供的資源列表,這些資源幫助互聯(lián)網(wǎng)更加安全。

          • PHP: The Right Way:現(xiàn)代 PHP 開發(fā)的實(shí)用指南,免費(fèi)在線。

          • Mozilla's SSL Config Generator

          • Let's Encrypt:證書頒發(fā)機(jī)構(gòu),通過提供免費(fèi) TLS 證書,為創(chuàng)建更安全的 Internet 做了很多。

          • Qualys SSL Labs:為 TLS 配置提供了一個快速而簡單的測試套件。幾乎每個人都使用這個來解決他們的密碼組和證書問題,理由很充分:It does its job well.

          • Security Headers:可以檢驗(yàn)?zāi)愕木W(wǎng)站在使用瀏覽器安全功能來保護(hù)用戶方面的表現(xiàn)如何。

          • Report-URI:一個很好的免費(fèi)資源,提供監(jiān)控 CSP/HPKP 等安全策略的實(shí)時(shí)安全報(bào)告服務(wù)。他們給你一個 Report-URI,你可以傳遞給你的用戶的瀏覽器,如果有什么事情發(fā)生或有人發(fā)現(xiàn) XSS 攻擊媒介,他們會投訴Report-URI。 Report-URI 會匯總這些錯誤,并允許你更好地對這些報(bào)告進(jìn)行疑難解答和分類。

          • PHP Security Advent Calenda:RIPSTech旗下的團(tuán)隊(duì)負(fù)責(zé)。

          • Snuffleupagus:一個面向安全的 PHP 模塊(Suhosin的精神繼承者,似乎在很大程度上會被放棄)

          • PHP Delusions:一個致力于更好地使用 PHP 的網(wǎng)站。大部分的口吻是非常有見地的,作者對技術(shù)的準(zhǔn)確性和清晰度的奉獻(xiàn)使得值得一讀,特別是對于那些不太喜歡 PDO 功能的人來說。

          • Have I Been Pwned?:幫助用戶發(fā)現(xiàn)他們的數(shù)據(jù)是否屬于過時(shí)數(shù)據(jù)泄露。

          結(jié)尾#

          原文地址:The 2018 Guide to Building Secure PHP Software - P.I.E. Staff

          最早是在社區(qū)里帖子 - The 2018 Guide to Building Secure PHP Software 看到,一位同學(xué)只發(fā)了原鏈接,由于是全英,文章也比較長,就沒有深讀,但可以知道這是一篇很好的文章,值得學(xué)習(xí),這幾天花了時(shí)間翻譯了全文。

          為避免歧義,部分專業(yè)名詞和語句保留了原文。翻譯過程借助了 Google 和 Google 翻譯,本人英文和相關(guān)專業(yè)水平有限,如有錯誤感謝指出修正。

          本文轉(zhuǎn)載自互聯(lián)網(wǎng),如侵犯了你的權(quán)益,請立即聯(lián)系告知,謝謝!

          原文地址:

          https://laravel-china.org/articles/7235/2018-php-application-security-design


          主站蜘蛛池模板: 色综合一区二区三区| 国产成人综合精品一区| 国产精品亚洲专区一区| 视频在线一区二区三区| 亚洲国产综合无码一区| 亚洲精品日韩一区二区小说| 久久精品国产第一区二区| 亚洲AV无码一区二区三区电影| 亚洲色无码一区二区三区| 内射一区二区精品视频在线观看| 2022年亚洲午夜一区二区福利| 日本一区二区三区高清| 区三区激情福利综合中文字幕在线一区亚洲视频1| 熟女精品视频一区二区三区| 不卡一区二区在线| jazzjazz国产精品一区二区| 精品福利一区3d动漫| 精品国产免费一区二区| 亚洲熟女www一区二区三区| 中文字幕日韩一区| 2021国产精品视频一区| 精品一区二区三区免费毛片爱| 亚洲综合无码精品一区二区三区| 亚洲欧洲一区二区三区| 538国产精品一区二区在线| 波多野结衣一区二区三区高清在线| 夜夜高潮夜夜爽夜夜爱爱一区| 亚洲AV无码国产精品永久一区| 国产91大片精品一区在线观看| 无码人妻一区二区三区在线| 无码人妻一区二区三区在线| 人妻天天爽夜夜爽一区二区| 人体内射精一区二区三区| 2021国产精品一区二区在线 | 在线日韩麻豆一区| 国产在线不卡一区| 一区二区在线视频观看| 成人午夜视频精品一区| 亚洲色婷婷一区二区三区| 亚洲av福利无码无一区二区| 91久久精品午夜一区二区|