2025年4月18日 星期五

如何在 Laravel 中排除 SQL Injection、XSS 和 CSRF 這些常見的網站安全問題

讓我們先來看看 Laravel 針對這些問題提供的保護機制以及你可以採取的措施:

SQL Injection

SQL Injection 是一種攻擊手法,駭客透過在使用者輸入中插入惡意的 SQL 語法,來竄改或竊取資料庫中的資料。

Laravel 的保護機制:

  • Eloquent ORM 和 Query Builder: Laravel 強烈建議使用 Eloquent ORM 或 Query Builder 來與資料庫互動。這些工具會自動處理參數綁定(parameter binding),確保使用者輸入的資料被安全地轉義,防止惡意的 SQL 語法被執行。

你應該怎麼做:

  1. 始終使用 Eloquent ORM 或 Query Builder: 盡可能避免使用原生的 SQL 查詢。如果真的需要使用,務必使用參數綁定。

    範例 (使用 Eloquent):

    PHP
    $user = App\Models\User::where('name', $name)->first();
    

    範例 (使用 Query Builder):

    PHP
    $users = DB::table('users')->where('email', $email)->get();
    

    避免 (不安全的原生查詢):

    PHP
    // 千萬不要這樣做!$id 是使用者輸入
    $user = DB::select("SELECT * FROM users WHERE id = " . $id);
    

    安全的原生查詢 (使用參數綁定):

    PHP
    $id = request()->input('user_id');
    $user = DB::select("SELECT * FROM users WHERE id = ?", [$id]);
    
  2. 驗證使用者輸入: 在將使用者輸入用於資料庫查詢之前,務必進行嚴格的驗證,確保輸入的格式和內容符合預期。Laravel 提供了強大的驗證功能。

    範例 (驗證規則):

    PHP
    $request->validate([
        'name' => 'required|string|max:255',
        'email' => 'required|email|unique:users,email',
        'user_id' => 'required|integer|min:1',
    ]);
    

Cross-Site Scripting (XSS)

XSS 是一種攻擊手法,駭客透過在網站中注入惡意的 JavaScript、HTML 或 CSS 程式碼,當其他使用者瀏覽到被注入的頁面時,這些惡意程式碼會在他們的瀏覽器上執行,可能導致資料洩漏、帳號劫持等問題。

Laravel 的保護機制:

  • Blade 模板引擎的自動轉義: Laravel 的 Blade 模板引擎預設會對所有輸出的變數進行 HTML 實體轉義(escaping)。這表示像 <script> 這樣的 HTML 標籤會被轉換成 &lt;script&gt;,使其不會被瀏覽器當作可執行的程式碼。

你應該怎麼做:

  1. 始終使用 Blade 模板引擎: 盡量使用 Blade 模板來顯示資料,讓 Laravel 自動處理輸出轉義。

    範例 (Blade 模板):

    Blade
    <div>{{ $userInput }}</div>
    

    如果 $userInput 包含 <script>alert('XSS');</script>,Blade 會將其轉義為:

    HTML
    <div>&lt;script&gt;alert('XSS');&lt;/script&gt;</div>
    
  2. 避免輸出未經處理的使用者輸入: 如果你需要輸出 HTML 內容,例如來自 Markdown 編輯器的內容,你需要特別小心。可以使用像 e() 輔助函數進行轉義,或者使用 !! 語法輸出原始 HTML(但務必確保這些 HTML 是可信任的,例如經過伺服器端的安全處理)。

    範例 (使用 e() 轉義):

    Blade
    <div>{{ e($untrustedInput) }}</div>
    

    範例 (輸出原始 HTML - 請謹慎使用):

    Blade
    <div>{!! $trustedHtml !!}</div>
    
  3. 使用專用的套件進行更複雜的處理: 對於需要處理使用者輸入的 HTML 內容,可以考慮使用專門的 HTML 清理套件,例如 HTMLPurifier,它可以移除惡意的程式碼並保留安全的 HTML 結構。

Cross-Site Request Forgery (CSRF)

CSRF 是一種攻擊手法,駭客誘騙使用者在不知情的情況下,向伺服器發送惡意的請求,執行非使用者本意的操作(例如修改密碼、轉帳等)。

Laravel 的保護機制:

  • CSRF Token: Laravel 會自動為每個使用者的會話產生一個唯一的 CSRF Token。這個 Token 會被包含在每個表單中(透過 @csrf Blade 指令),以及在 AJAX 請求的 Header 中。伺服器端會驗證請求中是否包含正確的 CSRF Token,以確保請求是來自合法的使用者操作,而不是惡意的偽造請求。

你應該怎麼做:

  1. 在所有表單中使用 @csrf 指令: 在你的 Blade 模板中,所有會發送 POST、PUT、PATCH 或 DELETE 請求的表單內,都必須包含 @csrf 指令。這會自動產生一個隱藏的欄位,包含 CSRF Token。

    範例 (包含 CSRF Token 的表單):

    Blade
    <form method="POST" action="/profile">
        @csrf
    
        <label for="name">Name:</label>
        <input type="text" id="name" name="name">
    
        <button type="submit">Update Profile</button>
    </form>
    
  2. 在 AJAX 請求中包含 CSRF Token: 如果你的應用程式使用 JavaScript 發送 AJAX 請求(特別是那些會修改伺服器端資料的請求),你需要確保在請求的 Header 中包含 CSRF Token。Laravel 提供了方便的方式來獲取 CSRF Token。

    範例 (在 JavaScript 中獲取 CSRF Token):

    JavaScript
    const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
    
    fetch('/some-api-endpoint', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRF-TOKEN': csrfToken,
        },
        body: JSON.stringify({ key: 'value' }),
    })
    .then(response => response.json())
    .then(data => console.log(data));
    

    你也可以在你的 Blade 模板的 <head> 標籤中加入以下 meta 標籤來方便 JavaScript 存取 CSRF Token:

    Blade
    <meta name="csrf-token" content="{{ csrf_token() }}">
    

總結來說,在 Laravel 中排除這些安全問題的關鍵在於:

  • 善用 Laravel 框架提供的安全特性: 例如 Eloquent ORM/Query Builder 的參數綁定、Blade 模板的自動轉義以及 CSRF 保護機制。
  • 嚴格驗證和過濾使用者輸入: 確保輸入的資料符合預期,並移除或轉義潛在的惡意內容。
  • 遵循安全開發的最佳實踐: 時刻關注最新的安全漏洞和防護方法。

希望這些說明對你有幫助!如果你有任何更具體的程式碼片段或情境想要討論,隨時都可以提供給我,我很樂意協助你分析和改進。

沒有留言:

張貼留言