這篇討論的不是 PHP Web 的安全相關議題,而是 Web server 管理者應該考量的系統安全議題。XSS、SQL injection 屬於前者,防禦的對象是網頁的瀏覽者;而這篇討論的防禦對象是經常被忽略的 PHP 網頁系統開發人員。
很多人都知道,PHP 屬直譯語言。因為不需要編譯,所以程式碼幾乎可以說是裸露的;除非用 ionCube PHP Encoder 這類的產品作加密,否則,開發人員只要有程式檔案的存取權,就可以看到程式碼。
現今,幾乎所有的 PHP 網頁系統都使用了後端資料庫,而資料庫存取的設定也都是寫在 PHP 程式碼裡面,類似以下這樣:
define( 'DB_SERVER' , 'localhost' );
define( 'DB_SERVER_USERNAME' , 'db_username' );
define( 'DB_SERVER_PASSWORD' , 'db_password' );
define( 'DB_DATABASE' , 'db_name' );
再透過 require()、require_once()、incluce()、include_once() 等設定檔引入。
如果這個設定檔的路徑沒有在 include_path 系統變數中,引入的方法大概會是這樣:
require_once( '/SOME/WHERE/DB_SETTING.php' );
這樣的系統意味著,有心的程式開發人員可以透過以下這一行程式,輕易取得資料庫存取設定:
echo file_get_contents( '/SOME/WHERE/DB_SETTING.php' );
若是 /SOME/WHERE 被放入 include_path 系統變數,程式開發人員可以透過以下的程式碼引入資料庫存取設定:
require_once( 'DB_SETTING.php' );
雖然以下的程式碼已經無法取出資料庫存取設定:
echo file_get_contents( 'DB_SETTING.php' );
但遇到以下這種程式碼依然是破功:
$paths = explode( ':' , ini_get( 'include_path' ) );
foreach ( $paths as $path ) {
$file_str = $path . DIRECTORY_SEPARATOR . 'DB_SETTING.php';
if ( file_exists( $file_str ) ) {
echo file_get_contents( $file_str );
}
}
即使設定 auto_prepend_file(之前的文章有提過),或是採用 Autoloading classes,這種問題依然存在。
根本的解決方法就是用 ionCube PHP Encoder 這類的產品作加密,或是用 C 語言撰寫 PHP extension。
很無奈.. 但卻是一針見效。
8 月 22 2024
更換 SSL 憑證與 DNSSEC 演算法
近期處理一些網站 SSL 憑證與 DNSSEC 相關的事,寫這篇留點紀錄供日後參考…
原先的 SSL 憑證幾乎都是透過 certbot 取得 (參考:用 certbot 取用 Let’s Encrypt 的 certificates);在 ECDSA certificates by default and other upcoming changes in Certbot 2.0 能看到其預設的演算法已從 RSA 變更成 ECDSA,但… 早期取得憑證時產生的設定檔仍須自己做更改。
設定檔都在 /etc/letsencrypt/renewal 目錄裡面,調整後的參數如下:
在準備更換 SSL 憑證時,恰巧看到 RFC 8624 – Algorithm Implementation Requirements and Usage Guidance for DNSSEC,就順便處理 DNSSEC 的事。
依據 3.1 節的說明,ED25519 是最佳選擇,其次就是 ECDSAP384SHA384 或 ED448;選擇演算法前,必須先看看域名註冊商提供的設定項。
以 ED25519 為例,我的操作流程如下:
過一段時間後,可以透過一些線上工具作驗證,像是 DNSViz | A DNS visualization tool。
By Joe Horn • Network 0 • Tags: DNS, DNSSEC, HTTPS, security, SSL