跳至主要內容
>_ITDITD網站資安平台

各框架對策

Laravel 資安對策 — 正式環境的加固參考

一份 Laravel 正式環境加固參考:依優先度排序的檢查清單、危險的預設值,以及從機密與設定到授權與相依套件 CVE 的各領域指引,另附自我驗證檢查清單。純防禦,不含攻擊步驟。

發布於 2026-07-02 更新於 2026-07-02 閱讀時間 4 分鐘

適用對象:任何在正式環境運行 Laravel 的人。這裡沒有攻擊步驟——這是一份加固用的可實作參考:依優先度排序的檢查清單、危險的預設值、各領域指引,以及自我驗證。想看跨框架的全貌,請見 各框架資安對策的入口

依優先度排序的加固檢查清單

由上而下處理這張表。P0 是其餘一切的前提,P1 是最常見的事故來源,P2 是持續的維運衛生。

P0 ── 前提(最先做)

正式環境關閉除錯/把機密以權限 600 擋在公開面之外/管理 APP_KEY

P1 ── 首要事故來源

授權(Policy/Gate)/Mass Assignment 控制/相依套件 CVE/正式環境快取

P2 ── 維運衛生

工作階段/CSRF/cookie/上傳驗證/HTTPS、標頭、限流

從地基往上加固:P0(前提)→ P1(首要事故來源)→ P2(維運衛生)。
優先度控制項具體做法(Laravel)
P0關閉正式環境除錯APP_DEBUG=falseAPP_ENV=production,並用 config:cache 固定。別在錯誤頁面上洩漏內部資訊
P0機密擋在公開面之外.env、備份、金鑰放在 public/ 之外,權限 600。storage/logs 不對外公開
P0妥善管理 APP_KEY加密、簽章 cookie、工作階段的基礎。從環境變數注入;外洩時輪替
P1明確的授權Policy/Gate + authorize()can middleware,依擁有者/權限界定範圍
P1控制 Mass Assignment宣告 $fillable;避免整批指派 $request->all(),改用 validated()
P1監控 Composer CVEcomposer audit/osv-scanner;依執行版本判斷,快速修補
P1正式環境快取config:cache route:cache view:cache,讓設定可靠生效+加速
P2工作階段/cookie 安全設定 secure http_only same_site;登入時重新產生工作階段
P2上傳驗證驗證類型/大小,存放在 public/ 之外,不給執行權限
P2HTTPS/標頭/限流強制 HTTPS、HSTS,登入/API 加上 throttle

1. 機密與 APP_KEY(P0)

Laravel 預設就把 .env 放在文件根目錄之外(在專案根目錄)。事故多半來自把機密放到不該放的地方。

  • 絕不要把 .env、DB 匯出檔、備份或金鑰檔放在 public/。把機密以權限 600(僅擁有者)放在應用程式根目錄之外。
  • 別對外暴露 storage/storage/logs/(日誌可能含有機密或個資)。別把 .env commit 進儲存庫。
  • APP_KEY 是加密、簽章 URL、加密 cookie 與工作階段的基礎。從環境變數注入它,並在外洩時立即輪替(注意這會使既有的加密資料/工作階段失效)。

一般原則見 別把機密資訊放進公開目錄;真實的完整外洩案例見 .env 完整外洩的案例

2. 正式環境設定:DEBUG、環境、快取(P0)

1

APP_DEBUG=false/APP_ENV=production

在正式環境關閉除錯。開著時,錯誤頁面會洩漏環境變數與連線資訊,可透過刻意觸發錯誤被抓出。
2

用快取固定設定

php artisan config:cache(+ route:cache view:cache)讓設定可靠生效並加速應用程式。注意:config:cache 之後,config/ 以外的 env() 會回傳 null,因此在應用程式中要透過 config('...') 引用值。
3

別在正式環境暴露診斷工具

在正式環境停用或限制 Telescope/Horizon/Debugbar 的存取。讓詳細錯誤與堆疊追蹤遠離公開面。

3. 授權:Broken Access Control(P1——首要來源)

最常見的正式環境事故是「已驗證但未授權」。能夠登入,不代表被允許執行該動作。

常見(危險)

  • 沒有授權——「登入=可檢視/更新」
  • route-model binding 抓到別的使用者的 ID
  • Model::create($request->all()) 接受每一個欄位
  • is_admin 這類權限欄位被使用者輸入指派

正確

  • Policy/Gateauthorize()can middleware,每次都界定擁有者/權限範圍
  • 讀取也依擁有者界定範圍(例如 where('user_id', $me)
  • $request->validated()(FormRequest)限制輸入
  • 宣告 $fillable 以擋下 Mass Assignment

IDOR 是什麼。關鍵在於每一條讀取/更新/刪除路徑都要做擁有者檢查。

4. 注入與輸出

Laravel 的 Eloquent/查詢建構器會以佔位符綁定值,而 Blade 預設會跳脫輸出。規則是別自己把那道安全機制關掉。

  • SQL:別用字串串接把使用者輸入混進 whereRawDB::raw。即使需要原生 SQL,也要使用綁定(→ SQL injection 是什麼)。
  • XSS:Blade {{ }} 會跳脫;{!! !!}原始輸出。別把使用者輸入傳給 {!! !!}。若一定要輸出 HTML,也要在淨化之後才做(→ XSS 是什麼)。
  • 驗證:使用前,用 FormRequest/validate() 驗證類型/範圍/允許值。

5. 工作階段、CSRF、cookie(P2)

  • CSRF:別全域停用 web middleware 的 CSRF 防護。表單中使用 @csrf,SPA 則做妥善的 token 處理(→ CSRF 是什麼)。
  • Cookie/工作階段:在 config/session.php 設定 secure(HTTPS)、http_onlysame_site登入時重新產生工作階段以防止固定攻擊(Laravel 的驗證會重新產生)。
  • 暴力破解:對登入套用 throttle/登入嘗試次數限制。

6. 檔案上傳與公開檔案(P2)

  • 驗證 mime type、副檔名與大小,且別信任用戶端提供的檔名
  • 存放在 public/ 之外(例如 storage/),且不給執行權限。只透過受控路徑對外提供需要公開的內容。
  • 也對遞送加上授權,讓連續的直接連結無法抓到別人的檔案。

7. HTTPS、安全標頭、限流(P2)

  • 強制 HTTPSURL::forceScheme('https') 等)+ HSTS。在負載平衡器後方,使用 TrustProxies 讓協定被正確偵測。
  • 安全標頭(X-Content-Type-Options 等;依你的資產配置設計 CSP)。用 安全標頭檢測工具 檢查自己的網站。
  • 限流:對登入、API 與密碼重設套用 throttle

8. 相依套件與版本(P1)

  • composer audit 或 osv-scanner 監控 Composer 相依套件的 CVE依執行版本判斷,並快速修補(→ 監控相依套件 CVE · 漏洞應變實務手冊)。
  • Laravel 與 PHP 維持在受支援的版本。別留著 EOL 版本(無法修補的漏洞會不斷累積)。

驗證:你的 Laravel 真的加固了嗎?

蓋好不是終點——檢查過才算完成。以下是針對你自己網站/環境的防禦性自我檢查。

1

機密無法透過網址取得

在你自己的網域上,存取 /.env/storage/logs/laravel.log,確認它們回傳 404(若能讀取,立即修正並輪替金鑰)。
2

正式環境沒有除錯外洩

觸發一個錯誤(例如不存在的路由),確認顯示的是通用錯誤頁面——沒有環境變數或堆疊追蹤。
3

授權有效

在測試環境中,請求別的使用者的資源 ID,確認它被拒絕(在讀取、更新與刪除路徑上)。
4

Cookie/工作階段與相依套件

確認工作階段 cookie 帶有 Secure/HttpOnly/SameSite,且 composer audit 是乾淨的

本站的觀點:即使預設值很強,授權與相依套件仍要靠你自己

Laravel 有許多好的預設值,但授權——誰可以做什麼——以及相依套件的新鮮度是應用程式與維運特有的,所以沒有任何框架能自動替你守。我們反覆看到的事故,與其說是精巧的攻擊,不如說是設定/維運的模式:「有驗證卻沒有擁有者檢查」「正式環境開著除錯」「機密被暴露」。所以重心在於由上而下處理上面的表格,並做那件不起眼的工作——每次讀取/更新都依擁有者界定範圍,並監控相依套件的 CVE。

接下來讀

FAQ

Q要保護 Laravel,我該先做什麼?
A

三個 P0 項目:(1) 確保正式環境 APP_DEBUG=false,並用 config:cache 把設定固定下來;(2) 讓 .env 與機密檔案待在公開目錄之外,並設定嚴格權限;(3) 妥善管理 APP_KEY(它是加密、簽章 cookie 與工作階段的基礎,因此外洩時要輪替)。這些是其餘一切的前提。接著再進到授權(Policy/Gate)與 Composer 相依套件 CVE 監控。

Q帶著 APP_DEBUG=true 上線有什麼危險?
A

開著除錯時,錯誤頁面不只會顯示堆疊追蹤,還會顯示設定值、環境變數、連線資訊等內部資訊。攻擊者可以刻意觸發錯誤把它們抓出來。在正式環境,請設定 APP_DEBUG=false 與 APP_ENV=production,並用 config:cache 讓它固定下來。此外,別在正式環境對外暴露 Telescope 或 Debugbar 這類診斷工具。

Q為什麼 config:cache 之後 env() 會回傳 null?
A

config:cache 為了效能把設定編譯成單一檔案,之後在設定檔以外呼叫的 env() 會回傳 null(只讀取快取當下的 .env)。修正方式是只在 config/ 內使用 env(),並在應用程式中透過 config('...') 引用值。在正式環境,快取 config/route/view 是常態——它讓設定可靠地生效,並讓應用程式更快。

Q如何避免『只要登入就代表被允許』?
A

驗證(登入)和授權(該動作是否被允許)是兩回事。在 Laravel 中,實作 Policy/Gate,並使用 authorize() 或 can middleware,讓每一次讀取/更新/刪除都依擁有者或權限界定範圍。此外,透過宣告 $fillable 來控制 Mass Assignment,避免整批指派 $request->all()。少了這個,把網址裡的 ID 換掉就能碰到別人的資料(IDOR)。

Q如何管理 Composer 相依套件的漏洞?
A

用 composer audit 或 osv-scanner 以機器監控已知 CVE,依實際執行的版本判斷,並快速修補(依實際安裝的版本決定,而非 composer.json 的宣告)。此外,讓 Laravel 與 PHP 維持在受支援的版本,別留著 EOL 版本。相依套件的新鮮度,是比精巧攻擊更貼近現實的事故因素。