เพิ่มส่วนหัวความปลอดภัยด้วย Lambda@Edge และ Terraform ใน AWS S3/CloudFront
เผยแพร่แล้ว: 2021-04-24เมื่อคุณเข้าสู่ระบบ https://app.sendgrid.com เพื่อดูรายละเอียดบัญชีของคุณหรือไปที่ https://mc.sendgrid.com สำหรับแคมเปญการตลาด คุณกำลังเยี่ยมชมเว็บแอปพลิเคชันส่วนหน้าของเราที่โฮสต์ในบัคเก็ต AWS S3 ด้วย CloudFront กระจายอยู่ด้านบน
เว็บแอปพลิเคชันของเราโดยพื้นฐานแล้วประกอบด้วยไฟล์ JavaScript และ CSS ที่ย่อและแยกโค้ด ไฟล์ HTML และไฟล์ภาพที่อัปโหลดไปยังบัคเก็ต S3 เป็นแคช CloudFront และให้บริการแก่ผู้ใช้ของเรา สภาพแวดล้อมของเว็บแอปพลิเคชันแต่ละแบบตั้งแต่การทดสอบ การจัดเตรียม และการผลิตมีบัคเก็ต S3 และการกระจาย CloudFront แยกจากกัน
โครงสร้างพื้นฐาน AWS S3 และ CloudFront นี้ทำงานได้ดีสำหรับแอปพลิเคชันเว็บของเราในวงกว้างในการโฮสต์ไฟล์ผ่านเครือข่ายการจัดส่งเนื้อหา แต่การกำหนดค่าเริ่มต้นของเราขาดการป้องกันที่เข้มงวดยิ่งขึ้นในรูปแบบของส่วนหัวความปลอดภัย
การเพิ่มส่วนหัวความปลอดภัยเหล่านี้จะป้องกันผู้ใช้จากการโจมตี เช่น การเขียนสคริปต์ข้ามไซต์ การดมกลิ่น MIME การคลิกแจ็ค การแทรกโค้ด และการโจมตีแบบคนกลางที่เกี่ยวข้องกับโปรโตคอลที่ไม่ปลอดภัย หากปล่อยทิ้งไว้โดยไม่มีใครดูแล สิ่งเหล่านี้จะส่งผลร้ายแรงต่อข้อมูลของลูกค้าและสำหรับความไว้วางใจของบริษัทในการมอบประสบการณ์ที่ปลอดภัยบนเว็บ
ก่อนที่เราจะค้นคว้าวิธีเพิ่มส่วนหัวเหล่านี้ ก่อนอื่นเราย้อนกลับไปดูว่าเราอยู่ที่ไหน หลังจากเรียกใช้ URL ของแอปพลิเคชันเว็บของเราผ่าน เว็บไซต์ สแกนส่วนหัวความปลอดภัย เราได้รับคะแนนที่ล้มเหลวอย่างน่าประหลาดใจ แต่เห็นรายการส่วนหัวที่เป็นประโยชน์ที่ต้องพิจารณาดังที่แสดงด้านล่าง
อย่างที่คุณเห็น ยังมีช่องว่างให้ปรับปรุงอีกมาก เราศึกษาวิธีกำหนดค่าทรัพยากร AWS S3 และ CloudFront เพื่อตอบกลับด้วยส่วนหัวด้านความปลอดภัยเพื่อลดความเสี่ยงและช่องโหว่ที่กล่าวถึง
ในระดับสูง เราสามารถทำได้โดย การสร้างฟังก์ชัน Lambda@Edge ที่เปลี่ยนส่วนหัวการตอบกลับต้นทางเพื่อผนวกส่วนหัวความปลอดภัยที่ต้องการ ก่อนที่ไฟล์ของเว็บแอปจะกลับไปที่เบราว์เซอร์ของผู้ใช้
กลยุทธ์คือการทดสอบการเชื่อมต่อด้วยตนเองผ่านคอนโซล AWS ก่อน จากนั้น เราจะใส่การกำหนดค่าเหล่านี้ใน Terraform เพื่อบันทึกส่วนนี้ของโครงสร้างพื้นฐานในโค้ดสำหรับการอ้างอิงในอนาคตและความสามารถในการแชร์ในทีมและแอปพลิเคชันอื่นๆ
เราต้องการเพิ่มส่วนหัวความปลอดภัยประเภทใด
ตามคำแนะนำจากทีม Product Security เราได้รับมอบหมายให้เพิ่มส่วนหัวด้านความปลอดภัย เช่น "Strict-Transport-Security" และ "X-Frame-Options" เราขอแนะนำให้คุณตรวจสอบแหล่งข้อมูลต่างๆ เช่น MDN Web Security Cheatsheet เพื่อเพิ่มความเร็ว ต่อไปนี้คือข้อมูลสรุปสั้นๆ เกี่ยวกับส่วนหัวด้านความปลอดภัยที่คุณสามารถใช้กับเว็บแอปพลิเคชันของคุณได้
เข้มงวด-ขนส่ง-ความปลอดภัย (HSTS)
นี่เป็นการให้คำแนะนำแก่เบราว์เซอร์ในการเข้าถึงเว็บแอปพลิเคชันของคุณผ่าน HTTPS แทนที่จะเป็น HTTP
เนื้อหา-ความปลอดภัย-นโยบาย (CSP)
นี่คือการตั้งค่ารายการที่อนุญาตอย่างชัดเจนเกี่ยวกับประเภทของทรัพยากรที่คุณโหลดหรือเชื่อมต่อในเว็บแอปพลิเคชันของคุณ เช่น สคริปต์ รูปภาพ สไตล์ แบบอักษร คำขอเครือข่าย และ iframe นี่เป็นวิธีที่ยากที่สุดสำหรับเราในการตั้งค่า เนื่องจากเรามีสคริปต์ รูปภาพ สไตล์ และปลายทาง API ของบุคคลที่สามที่ต้องบันทึกอย่างชัดเจนในนโยบายเหล่านี้
เคล็ดลับ: ใช้ส่วนหัว Content-Security-Policy-Report-Only เพื่อช่วยคุณในการทดสอบในสภาพแวดล้อมบางอย่าง หากทรัพยากรบางอย่างละเมิดนโยบาย เราสังเกตผลลัพธ์ของคอนโซลที่เป็นประโยชน์ของทรัพยากรที่เราต้องอนุญาตในนโยบายของเรา
หากคุณต้องการหลีกเลี่ยงอุบัติเหตุที่ตลกขบขันกับหน้าจอว่างเปล่าและเว็บแอปที่ไม่สามารถโหลดได้ เราขอแนะนำให้คุณทดลองกับนโยบายของคุณในโหมดรายงานเท่านั้นก่อน และทำการทดสอบอย่างละเอียดก่อนที่จะรู้สึกมั่นใจมากพอที่จะปรับใช้นโยบายความปลอดภัยเหล่านี้ในเวอร์ชันที่ใช้งานจริง
X-Content-Type-Options
นี่คือการรักษาและโหลดเนื้อหาด้วยประเภท MIME ที่ถูกต้องในหน้าเว็บของคุณ
X-Frame-Options
นี่คือการกำหนดกฎเกณฑ์ว่าเว็บแอปพลิเคชันของคุณมีศักยภาพที่จะโหลดใน iframe ได้อย่างไร
X-XSS-การป้องกัน
การดำเนินการนี้จะหยุดการโหลดหน้าเว็บหากตรวจพบการโจมตีแบบแฝงสคริปต์ในเบราว์เซอร์บางประเภท
นโยบายผู้อ้างอิง
วิธีนี้จะจัดการวิธีที่ส่วนหัว "ผู้อ้างอิง" ที่มีข้อมูลเกี่ยวกับที่มาของคำขอส่งผ่านเมื่อติดตามลิงก์ไปยังไซต์หรือแหล่งข้อมูลภายนอก
เมื่อคำนึงถึงส่วนหัวด้านความปลอดภัยแล้ว เรามาย้อนกลับไปที่วิธีที่เราตั้งค่าการแจกจ่าย CloudFront ของเราในวันนี้ และวิธีที่ฟังก์ชัน Lambda@Edge จะช่วยให้เราบรรลุเป้าหมายได้อย่างไร
การใช้ Lambda@Edge กับการกระจาย CloudFront ของเรา
สำหรับการกระจาย CloudFront เราตั้งค่าต่างๆ เช่น:
- ใบรับรอง SSL สำหรับโดเมนที่จะแนบที่ด้านบนของ URL ของ CloudFront เช่น https://app.sendgrid.com
- ที่มาของถัง S3
- กลุ่มต้นทางที่มีบัคเก็ตหลักและแบบจำลองสำหรับการเฟลโอเวอร์อัตโนมัติ
- พฤติกรรมแคช
โดยเฉพาะอย่างยิ่ง ลักษณะการทำงานของแคชเหล่านี้ ทำให้เราสามารถควบคุมระยะเวลาที่เราต้องการให้การตอบกลับสำหรับเส้นทางและไฟล์บางประเภทถูกแคชในเซิร์ฟเวอร์ขอบทั่วโลก นอกจากนี้ ลักษณะการทำงานของแคชยังช่วยให้เราสามารถทริกเกอร์ฟังก์ชัน AWS Lambda เพื่อตอบสนองต่อเหตุการณ์ต่างๆ เช่น คำขอต้นทางและการตอบสนองต้นทาง คุณสามารถนึกถึงฟังก์ชัน AWS Lambda เป็นโค้ดเฉพาะที่คุณกำหนดซึ่งจะรันเพื่อตอบสนองต่อเหตุการณ์บางอย่าง
ในกรณีของเรา เราสามารถแก้ไข ส่วนหัวการตอบกลับต้นทาง ก่อนที่ Edge Server จะถูกแคชไว้ ฟังก์ชัน Lambda@Edge ของเราจะเพิ่มส่วนหัวความปลอดภัยที่กำหนดเองให้กับการตอบกลับต้นทาง ก่อนที่มันจะกลับมาที่ Edge Server ในท้ายที่สุด และก่อนที่ผู้ใช้ปลายทางจะได้รับไฟล์ JavaScript, CSS และ HTML ที่มีส่วนหัวเหล่านั้น
เราสร้างแบบจำลองแนวทางของเราหลังจาก โพสต์บล็อกของ AWS นี้ และขยายเพื่อให้ทำการเปลี่ยนแปลงนโยบายการรักษาความปลอดภัยของเนื้อหาเฉพาะได้ง่ายขึ้น คุณสามารถสร้างโมเดลฟังก์ชัน Lambda@Edge หลังจากที่เราตั้งค่าต่างๆ ในการสร้างรายการสำหรับสคริปต์ สไตล์ และแหล่งที่มาของการเชื่อมต่อ ฟังก์ชันนี้จะแก้ไขส่วนหัวการตอบกลับต้นทางของ CloudFront อย่างมีประสิทธิภาพและผนวกส่วนหัวความปลอดภัยแต่ละรายการด้วยค่าบางอย่างในการตอบกลับก่อนที่จะส่งคืนโดยการเรียกใช้ฟังก์ชันการเรียกกลับที่ให้ไว้ดังที่แสดงด้านล่าง
เราจะทดสอบฟังก์ชัน Lambda@Edge นี้ได้อย่างไร
ก่อนที่คุณจะเปลี่ยนวิธีส่งคืนสินทรัพย์อย่างเป็นทางการพร้อมส่วนหัวความปลอดภัย คุณควรตรวจสอบการทำงานของฟังก์ชันหลังจากที่คุณกำหนดค่าทุกอย่างด้วยตนเองผ่านคอนโซล AWS เป็นสิ่งสำคัญที่เว็บแอปพลิเคชันของคุณควรสามารถโหลดและทำงานได้อย่างถูกต้องโดยเพิ่มส่วนหัวความปลอดภัยในการตอบกลับเครือข่ายของคุณ สิ่งสุดท้ายที่คุณต้องการได้ยินคือการหยุดทำงานโดยไม่คาดคิดซึ่งเกิดขึ้นเนื่องจากส่วนหัวด้านความปลอดภัย ดังนั้น ให้ทดสอบอย่างละเอียดในสภาพแวดล้อมการพัฒนาของคุณ
สิ่งสำคัญคือต้องรู้ว่าคุณจะเขียนอะไรในโค้ด Terraform ในภายหลังเพื่อบันทึกการกำหนดค่านี้ใน codebase ของคุณ ในกรณีที่คุณไม่รู้เกี่ยวกับ Terraform มันให้วิธีในการเขียนและจัดการโครงสร้างพื้นฐานระบบคลาวด์ของคุณผ่านโค้ด
เคล็ดลับ: ดู เอกสาร Terraform เพื่อดูว่าสามารถช่วยให้คุณรักษาการกำหนดค่าที่ซับซ้อนได้หรือไม่โดยไม่จำเป็นต้องจำขั้นตอนทั้งหมดที่คุณทำในคอนโซลระบบคลาวด์
วิธีเริ่มต้นใช้งานคอนโซล AWS
มาเริ่มกันด้วยวิธีการตั้งค่าด้วยตนเองผ่านคอนโซล AWS
- ขั้นแรก คุณต้องสร้างฟังก์ชัน Lambda@Edge ในภูมิภาค “us-east-1” ไปที่หน้าบริการแลมบ์ดา เราจะคลิก "สร้างฟังก์ชัน" และตั้งชื่อว่า "testSecurityHeaders1"
2. คุณสามารถใช้บทบาทที่มีอยู่พร้อมสิทธิ์ในการเรียกใช้ฟังก์ชันที่เซิร์ฟเวอร์ edge หรือคุณสามารถใช้เทมเพลตนโยบายบทบาทอย่างใดอย่างหนึ่ง เช่น “Basic Lambda@Edge Permissions…” และตั้งชื่อว่า “lambdaedgeroletest”
3. หลังจากสร้างฟังก์ชันและบทบาททดสอบแลมบ์ดาแล้ว คุณควรเห็นสิ่งนี้ โดยที่คุณจะสังเกตเห็นปุ่ม "เพิ่มทริกเกอร์" สำหรับฟังก์ชันนั้น นี่คือที่ที่คุณจะเชื่อมโยง Lambda กับพฤติกรรมแคชของการกระจาย CloudFront ที่ทริกเกอร์ในเหตุการณ์การตอบสนองต้นทางในที่สุด
4. ถัดไป คุณต้องแก้ไขรหัสฟังก์ชันด้วยรหัสส่วนหัวความปลอดภัยที่เราสร้างขึ้นมาก่อนแล้วกด "บันทึก"
5. หลังจากบันทึกโค้ดฟังก์ชันแล้ว มาทดสอบกันว่าฟังก์ชัน Lambda ของคุณใช้งานได้หรือไม่โดยเลื่อนไปที่ด้านบนสุดแล้วกดปุ่ม "ทดสอบ" คุณจะสร้างเหตุการณ์ทดสอบที่ชื่อว่า "samplecloudfrontresponse" โดยใช้เทมเพลตเหตุการณ์ "cloudfront-modify-response-header" เพื่อจำลองเหตุการณ์การตอบสนองต้นทางของ CloudFront จริงและเพื่อดูว่าฟังก์ชันของคุณทำงานอย่างไรกับเหตุการณ์นั้น
คุณจะสังเกตเห็นสิ่งต่างๆ เช่น ออบเจ็กต์ส่วนหัว "cf.response" ที่โค้ดฟังก์ชัน Lambda ของคุณจะแก้ไข
6. หลังจากสร้างเหตุการณ์ทดสอบ คุณจะคลิกปุ่ม "ทดสอบ" อีกครั้งและควรดูว่าฟังก์ชัน Lambda ทำงานอย่างไร ควรรันได้สำเร็จด้วยบันทึกที่แสดงการตอบสนองที่เป็นผลลัพธ์พร้อมส่วนหัวความปลอดภัยที่เพิ่มเข้ามาเช่นนี้
เยี่ยมมาก ดูเหมือนว่าฟังก์ชันแลมบ์ดาจะผนวกส่วนหัวความปลอดภัยเข้ากับการตอบสนองอย่างถูกต้อง!
7. กลับไปที่ส่วน "ผู้ออกแบบ" แล้วคลิกปุ่ม "เพิ่มทริกเกอร์" เพื่อให้คุณสามารถเชื่อมโยงฟังก์ชัน Lambda กับพฤติกรรมแคชของการแจกจ่าย CloudFront ในเหตุการณ์การตอบสนองต้นทาง ตรวจสอบให้แน่ใจว่าได้เลือกทริกเกอร์ "CloudFront" และคลิกปุ่ม "ปรับใช้กับ Lambda@Edge"
8. ถัดไป เลือกการกระจาย CloudFront (ในตัวอย่างของเรา เราล้างอินพุตที่นี่เพื่อเหตุผลด้านความปลอดภัย) และพฤติกรรมแคชที่จะเชื่อมโยงกับข้อมูลดังกล่าว
จากนั้น คุณเลือกลักษณะการทำงานของแคช “*” และเลือกเหตุการณ์ “การตอบกลับต้นทาง” เพื่อให้ตรงกับเส้นทางคำขอทั้งหมดไปยังการแจกจ่าย CloudFront ของคุณและเพื่อให้แน่ใจว่าฟังก์ชัน Lambda จะทำงานสำหรับการตอบกลับต้นทางทั้งหมดเสมอ
จากนั้นคุณทำเครื่องหมายที่การตอบรับก่อนที่จะคลิก "ปรับใช้" เพื่อปรับใช้ฟังก์ชัน Lambda ของคุณอย่างเป็นทางการ
9. หลังจากเชื่อมโยงฟังก์ชัน Lambda ของคุณกับพฤติกรรมแคชของการแจกจ่าย CloudFront ที่เกี่ยวข้องทั้งหมดเรียบร้อยแล้ว คุณควรเห็นสิ่งที่คล้ายกันนี้ในพื้นที่ "ผู้ออกแบบ" แดชบอร์ดของ Lambda ซึ่งคุณสามารถดูทริกเกอร์ CloudFront และมีตัวเลือกในการดูหรือลบออก
การเปลี่ยนแปลงรหัสแลมบ์ดาของคุณ
เมื่อใดก็ตามที่คุณจำเป็นต้องทำการเปลี่ยนแปลงโค้ด Lambda เราขอแนะนำ:
- เผยแพร่เวอร์ชันใหม่ผ่านดรอปดาวน์ปุ่ม "การทำงาน"
- ลบทริกเกอร์ในเวอร์ชันเก่า (คุณสามารถคลิกที่ดรอปดาวน์ "รอบคัดเลือก" เพื่อดูเวอร์ชันทั้งหมดของแลมบ์ดาของคุณ)
- เชื่อมโยงทริกเกอร์กับหมายเลขเวอร์ชันล่าสุดที่คุณเพิ่งเผยแพร่
เมื่อปรับใช้ Lambda ของคุณเป็นครั้งแรกหรือหลังจากเผยแพร่เวอร์ชันใหม่ของ Lambda และเชื่อมโยงทริกเกอร์กับเวอร์ชันที่ใหม่กว่าของ Lambda คุณอาจไม่เห็นส่วนหัวด้านความปลอดภัยทันทีในการตอบกลับสำหรับเว็บแอปพลิเคชันของคุณ นี่เป็นเพราะวิธีที่ Edge Server ใน CloudFront แคชการตอบสนอง คุณอาจต้องรอสักครู่เพื่อดูส่วนหัวความปลอดภัยใหม่ ทั้งนี้ขึ้นอยู่กับระยะเวลาที่คุณตั้งค่าเวลาใช้งานจริงในลักษณะการทำงานของแคช เว้นแต่ว่าคุณจะทำให้แคชใช้ไม่ได้ในการแจกจ่าย CloudFront ที่ได้รับผลกระทบ
หลังจากปรับใช้การเปลี่ยนแปลงของคุณกับฟังก์ชัน Lambda อีกครั้ง มักต้องใช้เวลาในการล้างแคช (ขึ้นอยู่กับการตั้งค่าแคช CloudFront) ก่อนที่การตอบสนองของคุณจะปรับแต่งส่วนหัวความปลอดภัยล่าสุด
เคล็ดลับ: เพื่อหลีกเลี่ยงไม่ให้รีเฟรชหน้าบ่อย ๆ หรือนั่งเฉยๆ ไม่แน่ใจว่าการเปลี่ยนแปลงของคุณใช้ได้ผลหรือไม่ ให้เริ่มใช้การใช้แคช CloudFront เพื่อทำให้กระบวนการล้างแคชเร็วขึ้น เพื่อให้คุณเห็นส่วนหัวความปลอดภัยที่อัปเดตแล้ว
ไปที่หน้า CloudFront Services ของคุณ รอให้สถานะการกระจาย CloudFront ใช้งานได้ หมายความว่าการเชื่อมโยงแลมบ์ดาทั้งหมดจะเสร็จสมบูรณ์และนำไปใช้งาน และไปที่แท็บ "Invalidations" คลิก "สร้างการตรวจสอบความถูกต้อง" และใส่ "/*" เป็นเส้นทางของวัตถุเพื่อทำให้ทุกสิ่งในแคชใช้ไม่ได้และกด "ทำให้ไม่ถูกต้อง" ไม่ควรใช้เวลานานเกินไป และหลังจากเสร็จสิ้น การรีเฟรชเว็บแอปพลิเคชันของคุณควรเห็นการเปลี่ยนแปลงส่วนหัวด้านความปลอดภัยล่าสุด
ในขณะที่คุณทำซ้ำในส่วนหัวความปลอดภัยตามสิ่งที่คุณพบว่าเป็นการละเมิดหรือข้อผิดพลาดในเว็บแอปพลิเคชันของคุณ คุณสามารถทำขั้นตอนนี้ซ้ำได้:
- เผยแพร่ฟังก์ชันแลมบ์ดาเวอร์ชันใหม่
- การลบทริกเกอร์ในเวอร์ชันเก่าของ Lambda
- การเชื่อมโยงทริกเกอร์ในเวอร์ชันใหม่
- แคชทำให้การแจกจ่าย CloudFront เป็นโมฆะ
- การทดสอบเว็บแอปพลิเคชันของคุณ
- ทำซ้ำจนกว่าคุณจะรู้สึกมั่นใจและปลอดภัย สิ่งต่างๆ ทำงานตามที่คาดไว้โดยไม่มีหน้าว่าง คำขอ API ที่ล้มเหลว หรือข้อผิดพลาดด้านความปลอดภัยของคอนโซล
เมื่อทุกอย่างเสถียรแล้ว คุณสามารถเลือกเปลี่ยนไปใช้ Terraforming สิ่งที่คุณเพิ่งทำในการกำหนดค่าโค้ดด้วยตนเองได้ สมมติว่าคุณมี Terraform ที่ผสานรวมกับบัญชี AWS ของคุณ เราจะไม่ครอบคลุมถึงวิธีการตั้งค่า Terraform ตั้งแต่เริ่มต้น แต่เราจะแสดงตัวอย่างให้คุณเห็นว่าโค้ด Terraform จะมีหน้าตาเป็นอย่างไร
Terraforming Lambda@Edge ที่ทริกเกอร์โดยการกระจาย CloudFront ของเรา
หลังจากทำซ้ำในฟังก์ชัน Lambda@Edge สำหรับส่วนหัวความปลอดภัยในภูมิภาค “us-east-1” เราต้องการเพิ่มสิ่งนี้ลงในฐานรหัส Terraform ของเราสำหรับการบำรุงรักษาโค้ดและการควบคุมเวอร์ชันตลอดเส้นทาง
สำหรับพฤติกรรมแคชทั้งหมดที่เราปรับใช้แล้ว เราต้องเชื่อมโยงพฤติกรรมแคชกับฟังก์ชัน Lambda@Edge ซึ่งเหตุการณ์การตอบสนองต้นทางทริกเกอร์
ขั้นตอนต่อไปนี้ถือว่าคุณมีการกระจาย CloudFront และบัคเก็ต S3 ส่วนใหญ่ที่กำหนดค่าผ่าน Terraform แล้ว เราจะเน้นที่โมดูลหลักและคุณสมบัติที่เกี่ยวข้องกับ Lambda@Edge และเพิ่มทริกเกอร์ให้กับพฤติกรรมแคชของการแจกจ่าย CloudFront เราจะไม่อธิบายวิธีตั้งค่าบัคเก็ต S3 ของคุณและการตั้งค่าการแจกจ่าย CloudFront อื่นๆ ตั้งแต่เริ่มต้นผ่าน Terraform แต่เราหวังว่าคุณจะเห็นระดับของความพยายามในการทำสิ่งนี้ให้สำเร็จด้วยตัวของคุณเอง
ขณะนี้เราแบ่งทรัพยากร AWS ของเราออกเป็นโฟลเดอร์โมดูลที่แยกจากกัน และส่งผ่านตัวแปรไปยังโมดูลเหล่านั้นเพื่อความยืดหยุ่นในการกำหนดค่าของเรา เรามีโฟลเดอร์ apply
ที่มีโฟลเดอร์ย่อยสำหรับ development
และ production
และแต่ละโฟลเดอร์มีไฟล์ main.tf
ของตัวเอง ซึ่งเราเรียกโมดูลเหล่านี้ด้วยตัวแปรอินพุตบางอย่างเพื่อสร้างอินสแตนซ์หรือแก้ไขทรัพยากร AWS ของเรา
โฟลเดอร์ย่อยเหล่านั้นแต่ละโฟลเดอร์ยังมีโฟลเดอร์ lambdas
ที่เราเก็บรหัส Lambda ไว้ เช่น ไฟล์ security_headers_lambda.js
security_headers_lambda.js
มีรหัสเดียวกันกับที่เราเคยใช้ในฟังก์ชัน Lambda เมื่อเราทดสอบด้วยตนเอง ยกเว้นว่าเราจะบันทึกไว้ในฐานรหัสเพื่อให้เราซิปและอัปโหลดผ่าน Terraform
1. อันดับแรก เราต้องการโมดูลที่นำกลับมาใช้ใหม่ได้เพื่อบีบอัดไฟล์ Lambda ของเราก่อนที่จะอัปโหลดและเผยแพร่เป็นเวอร์ชันอื่นของฟังก์ชัน Lambda@Edge สิ่งนี้นำไปสู่เส้นทางไปยังโฟลเดอร์ Lambda ของเราที่มีฟังก์ชัน Node.js Lambda ในที่สุด
2. ต่อไป เราเพิ่มลงในโมดูล CloudFront ที่มีอยู่ ซึ่งรวมบัคเก็ต S3, นโยบาย และทรัพยากรการแจกจ่าย CloudFront ด้วยการสร้างทรัพยากร Lambda ที่สร้างขึ้นจากไฟล์ Lambda ที่บีบอัดไว้ เนื่องจากเอาต์พุตของโมดูล zip ของ Lambda จะส่งผ่านเป็นตัวแปรไปยังโมดูล CloudFront เพื่อตั้งค่าทรัพยากร Lambda เราจึงต้องระบุภูมิภาคของผู้ให้บริการ AWS เป็น “us-east-1” และด้วยนโยบายบทบาทการทำงานเช่นนี้
3. ภายในโมดูล CloudFront เราจะเชื่อมโยงฟังก์ชัน Lambda@Edge นี้กับพฤติกรรมแคชของการกระจาย CloudFront ดังที่แสดงด้านล่าง
4. สุดท้าย เมื่อรวมทั้งหมดเข้าด้วยกันในไฟล์ main.tf
ของโฟลเดอร์ Apply apply/development
Developing หรือ apply/production
Production เราเรียกโมดูลทั้งหมดเหล่านี้และใส่ผลลัพธ์ที่เหมาะสมเป็นตัวแปรลงในโมดูล CloudFront ดังที่แสดงไว้ที่นี่
การปรับแต่งการกำหนดค่าเหล่านี้จะช่วยดูแลขั้นตอนแบบแมนนวลที่เราทำในส่วนก่อนหน้าเพื่ออัปเดตโค้ด Lambda และเชื่อมโยงเวอร์ชันที่ใหม่กว่ากับพฤติกรรมแคชของ CloudFront และทริกเกอร์สำหรับเหตุการณ์ตอบกลับต้นทาง วู้ฮู! ไม่จำเป็นต้องผ่านหรือจำขั้นตอน AWS Console ตราบใดที่เราใช้การเปลี่ยนแปลงเหล่านี้กับทรัพยากรของเรา
เราจะเผยแพร่สิ่งนี้อย่างปลอดภัยในสภาพแวดล้อมที่แตกต่างกันได้อย่างไร
เมื่อเราเชื่อมโยงฟังก์ชัน Lambda@Edge กับการทดสอบการกระจาย CloudFront ในครั้งแรก เราสังเกตเห็นได้อย่างรวดเร็วว่าเว็บแอปพลิเคชันของเราโหลดไม่ถูกต้องอีกต่อไป สาเหตุหลักมาจากวิธีที่เราใช้ส่วนหัว Content-Security-Policy และไม่ครอบคลุมทรัพยากรทั้งหมดที่เราโหลดในแอปพลิเคชันของเรา ส่วนหัวด้านความปลอดภัยอื่นๆ มีความเสี่ยงน้อยกว่าในแง่ของการบล็อกแอปพลิเคชันของเราจากการโหลด ในอนาคต เราจะมุ่งเน้นไปที่การเปิดตัวส่วนหัวความปลอดภัยโดยคำนึงถึงการทำซ้ำเพิ่มเติมเพื่อปรับแต่งส่วนหัวของนโยบายเนื้อหา-ความปลอดภัย
ตามที่กล่าวไว้ก่อนหน้านี้ เราค้นพบวิธีที่เราสามารถใช้ประโยชน์จากส่วนหัว Content-Security-Policy-Report-Only แทนเพื่อลดความเสี่ยงในขณะที่เรารวบรวมโดเมนทรัพยากรมากขึ้นเพื่อเพิ่มในแต่ละนโยบายของเรา
ในโหมดรายงานเท่านั้น นโยบายจะยังคงทำงานในเบราว์เซอร์และข้อความแสดงข้อผิดพลาดของคอนโซลเอาต์พุตของการละเมิดนโยบาย อย่างไรก็ตาม มันจะไม่บล็อกสคริปต์และแหล่งที่มาทั้งหมด ดังนั้นเว็บแอปพลิเคชันของเราจึงยังคงทำงานตามปกติ ขึ้นอยู่กับเราแล้วที่จะใช้งานเว็บแอปพลิเคชันทั้งหมดต่อไปเพื่อให้แน่ใจว่าเราจะไม่พลาดแหล่งข้อมูลที่สำคัญในนโยบายของเรา มิฉะนั้นจะส่งผลเสียต่อลูกค้าและทีมสนับสนุนของเรา
สำหรับแต่ละสภาพแวดล้อม คุณสามารถเปิดตัวส่วนหัวความปลอดภัย Lambda ได้ดังนี้:
- เผยแพร่การเปลี่ยนแปลงใน Lambda ด้วยตนเองหรือผ่านแผน Terraform และนำไปใช้กับการเปลี่ยนแปลงสภาพแวดล้อมด้วยส่วนหัวความปลอดภัยอื่นๆ และส่วนหัว Content-Security-Policy-Report-Only เท่านั้นก่อน
- รอให้สถานะการกระจาย CloudFront ของคุณใช้งานได้อย่างสมบูรณ์กับ Lambda ที่เชื่อมโยงกับพฤติกรรมแคช
- ทำแคชใช้ไม่ได้ในการกระจาย CloudFront ของคุณหากส่วนหัวความปลอดภัยก่อนหน้ายังคงแสดงอยู่ หรือใช้เวลานานเกินไปสำหรับการเปลี่ยนแปลงปัจจุบันของคุณเพื่อแสดงในเบราว์เซอร์ของคุณ
- เยี่ยมชมและเยี่ยมชมหน้าของเว็บแอปพลิเคชันของคุณโดยเปิดเครื่องมือสำหรับนักพัฒนา โดยสแกนคอนโซลเพื่อหาข้อความแสดงข้อผิดพลาดของคอนโซล “รายงานเท่านั้น…” เพื่อปรับปรุงส่วนหัวของนโยบายเนื้อหา-ความปลอดภัย
- ทำการเปลี่ยนแปลงรหัสแลมบ์ดาของคุณเพื่อพิจารณาการละเมิดที่รายงานเหล่านั้น
- ทำซ้ำตั้งแต่ขั้นตอนแรกจนกว่าคุณจะรู้สึกมั่นใจพอที่จะเปลี่ยนส่วนหัวของคุณจาก Content-Security-Policy-Report-Only เป็น Content-Security-Policy ซึ่งหมายความว่าสภาพแวดล้อมจะบังคับใช้
การปรับปรุงคะแนนส่วนหัวความปลอดภัยของเรา
หลังจากใช้การเปลี่ยนแปลง Terraform กับสภาพแวดล้อมของเราสำเร็จและทำให้แคช CloudFront ใช้ไม่ได้ เราก็รีเฟรชหน้าในแอปพลิเคชันเว็บของเรา เราเปิดเครื่องมือสำหรับนักพัฒนาไว้เสมอเพื่อดูส่วนหัวความปลอดภัย เช่น HSTS, CSP และส่วนอื่นๆ ในการตอบกลับเครือข่ายของเรา เช่น ส่วนหัวความปลอดภัยที่แสดงด้านล่าง
เรายังเรียกใช้เว็บแอปพลิเคชันของเราผ่านรายงานการสแกนส่วนหัวด้านความปลอดภัย เช่น รายงานบน เว็บไซต์ นี้ ด้วยเหตุนี้ เราจึงเห็นการปรับปรุงที่ยอดเยี่ยม (คะแนน A!) จากคะแนนที่ล้มเหลวก่อนหน้านี้ และคุณสามารถบรรลุการปรับปรุงที่คล้ายกันได้หลังจากเปลี่ยนการตั้งค่า S3/CloudFront เพื่อให้มีส่วนหัวด้านความปลอดภัย
ก้าวไปข้างหน้าด้วยหัวข้อความปลอดภัย
หลังจากตั้งค่าส่วนหัวความปลอดภัยด้วยตนเองผ่านคอนโซล AWS หรือ Terraforming โซลูชันและนำการเปลี่ยนแปลงไปใช้กับสภาพแวดล้อมของคุณสำเร็จ ตอนนี้คุณมีพื้นฐานที่ดีในการทำซ้ำเพิ่มเติมและปรับปรุงส่วนหัวความปลอดภัยที่มีอยู่ของคุณในอนาคต
ขึ้นอยู่กับวิวัฒนาการของเว็บแอปพลิเคชันของคุณ คุณอาจต้องทำให้ส่วนหัว Content-Security-Policy มีความเฉพาะเจาะจงมากขึ้นในแง่ของทรัพยากรที่อนุญาตสำหรับการรักษาความปลอดภัยที่เข้มงวดยิ่งขึ้น หรือคุณอาจต้องเพิ่มส่วนหัวใหม่ทั้งหมดเพื่อจุดประสงค์ที่แยกจากกัน หรือเพื่อกรอกข้อมูลในช่องความปลอดภัยอื่น
ด้วยการเปลี่ยนแปลงในอนาคตเหล่านี้กับส่วนหัวความปลอดภัยของคุณในฟังก์ชัน Lambda@Edge คุณสามารถปฏิบัติตามกลยุทธ์การเผยแพร่ที่คล้ายคลึงกันในแต่ละสภาพแวดล้อมเพื่อให้แน่ใจว่าเว็บแอปพลิเคชันของคุณปลอดภัยจากการโจมตีที่เป็นอันตรายบนเว็บและยังคงทำงานโดยที่ผู้ใช้ของคุณไม่เคยสังเกตเห็นความแตกต่าง
สำหรับบทความเพิ่มเติมที่เขียนโดย Alfred Lucero ไปที่หน้าผู้เขียนบล็อกของเขา: https://sendgrid.com/blog/author/alfred/