บทความ

Laravel Web Security: Cross-Site Request Forgery (CSRF) คืออะไร ?

ในบทช่วยสอน Laravel นี้ เราพูดถึงความปลอดภัยของเว็บและวิธีปกป้องเว็บแอปพลิเคชันจากการโจมตี Cross-Site Request Forgery หรือ CSRF

CSRF เป็นกิจกรรมที่เป็นอันตรายที่ดำเนินการโดยผู้โจมตี ซึ่งดำเนินการในนามของผู้ใช้ที่ผ่านการรับรองความถูกต้อง ซึ่งเป็นอันตรายต่อความปลอดภัยของเว็บ โชคดีที่ Laravel มีเครื่องมือเพื่อป้องกันช่องโหว่ประเภทนี้

CSRF คืออะไร?

การโจมตี CSRF จี้เซสชันของผู้ใช้ โดยหลอกให้ผู้ใช้ส่งคำขอผ่านแท็กแบบฟอร์มที่ซ่อนอยู่หรือ URL ที่เป็นอันตราย (รูปภาพหรือลิงก์) โดยที่ผู้ใช้ไม่ทราบ

การโจมตีนี้นำไปสู่การเปลี่ยนแปลงสถานะเซสชันของผู้ใช้ ข้อมูลรั่วไหล และบางครั้งแฮ็กเกอร์สามารถจัดการข้อมูลผู้ใช้ปลายทางในแอปพลิเคชันได้

ภาพด้านบนแสดงสถานการณ์ที่ความปลอดภัยของเว็บถูกละเมิด เหยื่อส่งคำขอโดยคลิกที่ลิงค์ (ได้รับ) ส่งคำขอไปยังเซิร์ฟเวอร์ของเว็บไซต์ซึ่งจะสร้างเอฟเฟกต์ตามที่แฮ็กเกอร์ต้องการ ซึ่งเข้ามาครอบครองข้อมูลที่เป็นประโยชน์สำหรับการเข้าถึงและจัดการเซิร์ฟเวอร์ของเว็บไซต์

วิธีป้องกันคำขอ CSRF

เพื่อปรับปรุง ความปลอดภัย เว็บของแอปพลิเคชันของคุณ ในแต่ละเซสชันของผู้ใช้ Laravel จะสร้างโทเค็นที่ปลอดภัยซึ่งใช้เพื่อให้แน่ใจว่าผู้ใช้ที่ผ่านการรับรองความถูกต้องเป็นผู้ร้องขอแอปพลิเคชัน

เนื่องจากโทเค็นนี้เปลี่ยนแปลงทุกครั้งที่มีการสร้างเซสชันผู้ใช้ใหม่ ผู้โจมตีจึงไม่สามารถเข้าถึงได้

เมื่อใดก็ตามที่มีการขอเปลี่ยนแปลงข้อมูลผู้ใช้ทางฝั่งเซิร์ฟเวอร์ (แบ็กเอนด์) เช่น POSTPUTPATCHDELETEคุณต้องรวมคำสั่ง @csrf ในแบบฟอร์มคำขอ blade HTML. เดอะ @csrf ดังนั้นจึงเป็นคำสั่ง Blade ใช้เพื่อสร้างโทเค็นที่ซ่อนอยู่ซึ่งตรวจสอบโดยแอปพลิเคชัน

คำสั่ง Blade เป็นไวยากรณ์ที่ใช้ภายในเอ็นจิ้นเทมเพลต Laravel ที่เรียกว่า ใบมีด . เพื่อสร้างไฟล์ blade คุณต้องตั้งชื่อ - ในรูปแบบเคสของเรา - ตามด้วยส่วนต่อขยายของใบมีด ซึ่งหมายความว่าไฟล์จะมีชื่อ form.blade.php.

มีการใช้ไฟล์ blade เพื่อแสดงมุมมองสำหรับผู้ใช้บนหน้าเว็บ มี pre-directivesdefiไวยากรณ์ชวเลขของ nite หรือ blade ที่คุณสามารถใช้ได้ ตัวอย่างเช่น, @if ตรวจสอบว่าตรงตามเงื่อนไขหรือไม่ @empty ตรวจสอบว่าระเบียนไม่ว่างเปล่า @auth ตรวจสอบว่าผู้ใช้ได้รับการรับรองความถูกต้องหรือไม่ เป็นต้น

แต่กลับไปที่คำสั่ง @csrf. นี่คือวิธีที่คุณใช้:

<form method="POST" action="{{route('pay')}}">

    @csrf
    
</form>

Laravel เวอร์ชันก่อนหน้ามีการตั้งค่าที่แตกต่างกัน: ทั้งคู่ทำงานและทำในสิ่งเดียวกัน

จดหมายข่าวนวัตกรรม
อย่าพลาดข่าวสารที่สำคัญที่สุดเกี่ยวกับนวัตกรรม ลงทะเบียนเพื่อรับพวกเขาทางอีเมล
<form method="POST" action="{{route('pay')}}">
    
    <input type="hidden" name="_token" value="{{ csrf_token() }}" />
    
</form>

เมื่อโทเค็น CSRF หายไปจากคำขอแบบฟอร์มที่กำลังส่งหรือหากดูเหมือนว่าไม่ถูกต้อง Laravel จะแสดงข้อความแสดงข้อผิดพลาด "Page Expired" พร้อมรหัสสถานะ 419

การตรวจสอบ CSRF เกิดขึ้นได้อย่างไรและที่ไหน

ตัวกลาง VerifyCsrfToken จัดการการยืนยัน CSRF ภายในแอปพลิเคชัน Laravel เดอะ middleware มีการลงทะเบียนใน Kernel.php และอยู่ในไดเรกทอรี app/Http/Middleware. ซึ่งหมายความว่า middleware มันถูกทริกเกอร์สำหรับคำขอภายในเว็บ ซึ่งไม่เกี่ยวข้องกับ API

protected $middlewareGroups = [
        'web' => [
           .
           .
           .
           .
           .
            \App\Http\Middleware\VerifyCsrfToken::class,
        ],
    ];

มิดเดิลแวร์ VerifyCsrfToken ขยายคลาส Illuminate\Foundation\Http\Middleware\VerifyCsrfTokenเช่น การตรวจสอบ CSRF คือ defiคืนภายในชั้นเรียน

มาเจาะลึกเพื่อดูว่า Laravel จัดการกับการยืนยัน CSRF อย่างไร

ภายในคลาสเรามีฟังก์ชั่น tokensMatch.

protected function tokensMatch($request)
{
     $token = $this->getTokenFromRequest($request);

     return is_string($request->session()->token()) &&
            is_string($token) &&
            hash_equals($request->session()->token(), $token);
}

ในรหัสจะกำหนดว่าเซสชันและโทเค็น CSRF ที่ป้อนเข้าตรงกันหรือไม่

ฟังก์ชันทำสองสิ่ง:

  1. รับ $this->getTokenFromRequest โทเค็นจากคำขอขาเข้าที่แนบผ่านฟิลด์ที่ซ่อนอยู่หรือส่วนหัวของคำขอ โทเค็นถูกถอดรหัสแล้วส่งคืนไปยังตัวแปรโทเค็น
protected function getTokenFromRequest($request)
{
    $token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN');

    if (! $token && $header = $request->header('X-XSRF-TOKEN')) {
        try {
            $token = CookieValuePrefix::remove($this->encrypter->decrypt($header, static::serialized()));
        } catch (DecryptException $e) {
            $token = '';
            }
    }

    return $token;
}

ในรหัสจะได้รับโทเค็นจากส่วนหัว

2. ส่งทั้งโทเค็นคำขอและเซสชันไปยังสตริงแล้วใช้ hash_equals สร้างขึ้นใน PHP เพื่อเปรียบเทียบว่าสตริงทั้งสองเท่ากันหรือไม่ ผลลัพธ์ของการดำเนินการนี้อยู่เสมอ บูล (จริง) หรือ (เท็จ) .

Ercole Palmeri

จดหมายข่าวนวัตกรรม
อย่าพลาดข่าวสารที่สำคัญที่สุดเกี่ยวกับนวัตกรรม ลงทะเบียนเพื่อรับพวกเขาทางอีเมล

บทความล่าสุด

ผู้จัดพิมพ์และ OpenAI ลงนามข้อตกลงเพื่อควบคุมการไหลของข้อมูลที่ประมวลผลโดยปัญญาประดิษฐ์

เมื่อวันจันทร์ที่แล้ว Financial Times ได้ประกาศข้อตกลงกับ OpenAI FT อนุญาติให้ทำข่าวระดับโลก...

30 2024 เมษายน

การชำระเงินออนไลน์: นี่คือวิธีที่บริการสตรีมมิ่งทำให้คุณชำระเงินตลอดไป

ผู้คนนับล้านชำระค่าบริการสตรีมมิ่ง โดยจ่ายค่าธรรมเนียมการสมัครสมาชิกรายเดือน เป็นความเห็นทั่วไปที่คุณ...

29 2024 เมษายน

Veeam มีการสนับสนุนแรนซัมแวร์ที่ครอบคลุมที่สุด ตั้งแต่การป้องกันไปจนถึงการตอบสนองและการกู้คืน

Coveware by Veeam จะยังคงให้บริการตอบสนองต่อเหตุการณ์การขู่กรรโชกทางไซเบอร์ต่อไป Coveware จะนำเสนอความสามารถในการนิติเวชและการแก้ไข...

23 2024 เมษายน

การปฏิวัติสีเขียวและดิจิทัล: การบำรุงรักษาเชิงคาดการณ์กำลังเปลี่ยนแปลงอุตสาหกรรมน้ำมันและก๊าซอย่างไร

การบำรุงรักษาเชิงคาดการณ์กำลังปฏิวัติภาคส่วนน้ำมันและก๊าซ ด้วยแนวทางเชิงรุกและนวัตกรรมในการจัดการโรงงาน...

22 2024 เมษายน

อ่านนวัตกรรมในภาษาของคุณ

จดหมายข่าวนวัตกรรม
อย่าพลาดข่าวสารที่สำคัญที่สุดเกี่ยวกับนวัตกรรม ลงทะเบียนเพื่อรับพวกเขาทางอีเมล

ติดตามเรา