飛機的 PHP 學習筆記九:安全

飛機飛過天空發表於2020-01-31

前言

最近在系統的學習 PHP ,參考的資料是《PHP程式設計》+ 官方文件(如果你有好的學習資料,歡迎推薦給我)。雖然這本《PHP程式設計》是基於 PHP5 的,但我筆記裡的程式碼,全部在 PHP 7.2 的環境裡測試過,是能夠執行的。另,本筆記中只記錄我模糊不清的知識。

過濾輸出

開發一個 Web 網站要了解的最基本的事情之一是:所有非程式自己生成的資訊都有潛在的汙染,包括表單資料、檔案和資料庫。也就是說任何時候我們都不要相信使用者輸入的資料。

關於過濾的最佳實踐:

  • 用白名單的方法。這意味著你寧可謹慎地假設資料都是無效的,除非你能證明它有效。
  • 不要糾正無效的資料。歷史證明嘗試糾正無效的資料常常會由於錯誤導致安全漏洞。
  • 使用命名來幫助區分過濾好的和汙染的資料。如果你不確定是否過濾了,過濾是無用的。

跨站指令碼

跨站指令碼(XSS, Cross-site scripting)由於簡寫 CSS 與層疊樣式表重名,而改寫成 XSS 。是最常見的網頁程式安全漏洞,是注入攻擊的一種。其特點是不對伺服器造成任何傷害,而是通過一些正常的站內互動途徑,例如釋出評論,提交含有 JavaScript 的內容的文字。

預防方法

對於任何使用者輸入的資訊,都要進行轉義/過濾。

SQL 注入

SQL 注入是將惡意的 SQL 查詢或新增語句插入到應用的輸出引數中,在由資料庫伺服器解析執行,從而達到攻擊目的。SQL 注入很像 XSS 。

預防方法

  • 使用引數化查詢來設計資料訪問功能。
  • 轉義輸出來達到過濾

轉義輸出檔名

realpath()basename() 來檢查檔名。

  • realpath() : 返回規範化的絕對路徑名

    chdir('/var/www/'); // 改變目錄
    echo realpath('./../../etc/passwd'); // /etc/passwd
  • basename() : 返回路徑中的檔名部分

這裡舉一個例子:檢查當前傳入的引數檔名,是否為規範的檔名(也就是沒有 ./ ../ 的檔名)

$filename = $_POST['filename'];
$vetted = basename(realpath($filename));

if ($filename !== $vetted){
    die("{$filename} is not good filename");
}

會話固定

攻擊者可以很簡單的拿到目標使用者的會話標識,進而目標使用者使用攻擊者的會話標識登入站點,攻擊者劫持會話成功.

預防方法

  • 當使用者登入的時候重置 sessionID 。
  • sessionID 閒置過久,重置 sessionID 。
  • 當使用者許可權變更時重置 sessionID 。

檔案上傳

在檔案上傳時,不要相信瀏覽器提供的檔名。正確的方法時:使用者互動中用瀏覽器提供的名字,但是要自己生成唯一的名字用來呼叫檔案。

PHP 程式碼

我們知道 eval() 函式,可以讓指令碼執行任意PHP程式碼。帶 /e 選項的 preg_replace() 函式與 eval() 函式效果一樣。

以上函式不要使用使用者提供的資料,因為這樣很容易遭到攻擊。

感謝你看到了這裡。如果文章有錯誤,請評論指正,謝謝!

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章