สร้างความสับสนให้กับสื่อกลางที่เป็นอันตรายด้วย HTTPS และ HTTP Strict Transport Security

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

สาเหตุที่ไม่ควรพลาดผลิตภัณฑ์นี้ ลองพิจารณาข้อมูลต่อไปนี้

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

คนแปลกหน้าส่วนใหญ่ในอีเมลฉบับนี้น่าเชื่อถือและจะไม่แอบดูหรือแก้ไขจดหมายเปิดผนึกของคุณ อย่างไรก็ตาม ยิ่งมีการส่งต่อจดหมายมากเท่าใด จำนวนผู้ที่มีสิทธิ์เข้าถึงจดหมายที่คุณส่งก็จะยิ่งมากขึ้นเท่านั้น ท้ายที่สุดแล้ว เป็นไปได้สูงที่ผู้รับจดหมายของคุณจะได้รับสิ่งใดสิ่งหนึ่งทางไปรษณีย์ แต่สิ่งนั้นจะเป็นสิ่งเดียวกันกับที่คุณส่งไปตั้งแต่แรกหรือไม่นั้นเป็นเรื่องที่ต้องรอดู คุณน่าจะปิดผนึกซองจดหมายนั้นไว้…

ผู้ขายคนกลาง

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

คุณสามารถดู Hop เหล่านี้ได้โดยใช้คำสั่ง Traceroute เส้นทางจากคอมพิวเตอร์ของฉันไปยัง HTML5Rocks จะมีลักษณะดังนี้

$ traceroute html5rocks.com
traceroute to html5rocks.com (173.194.71.102), 30 hops max, 60 byte packets
 1  router1-lon.linode.com (212.111.33.229)  0.453 ms
 2  212.111.33.233 (212.111.33.233)  1.067 ms
 3  217.20.44.194 (217.20.44.194)  0.704 ms
 4  google1.lonap.net (193.203.5.136)  0.804 ms
 5  209.85.255.76 (209.85.255.76)  0.925 ms
 6  209.85.253.94 (209.85.253.94)  1.226 ms
 7  209.85.240.28 (209.85.240.28)  48.714 ms
 8  216.239.47.12 (216.239.47.12)  22.575 ms
 9  209.85.241.193 (209.85.241.193)  36.033 ms
10  72.14.233.180 (72.14.233.180)  43.222 ms
11  72.14.233.170 (72.14.233.170)  43.242 ms
12  *
13  lb-in-f102.1e100.net (173.194.71.102)  44.523 ms

13 Hops ถือว่าไม่แย่เลย อย่างไรก็ตาม หากฉันส่งคำขอผ่าน HTTP เราเตอร์กลางแต่ละตัวจะมีสิทธิ์เข้าถึงคำขอและคำตอบของเซิร์ฟเวอร์อย่างสมบูรณ์ ระบบจะโอนข้อมูลทั้งหมดเป็นข้อความธรรมดาที่ไม่ได้เข้ารหัส และสื่อกลางเหล่านี้อาจทำหน้าที่เป็นคนกลางที่อ่านข้อมูลของฉัน หรือแม้แต่ดัดแปลงข้อมูลระหว่างการรับส่ง

ที่แย่กว่านั้นคือ แทบจะตรวจจับการดักรับประเภทนี้ไม่ได้ การตอบกลับ HTTP ที่ดัดแปลงอย่างเป็นอันตรายจะมีลักษณะเหมือนกับการตอบกลับที่ถูกต้องทุกประการ เนื่องจากไม่มีกลไกที่จะช่วยให้คุณมั่นใจได้ว่าข้อมูลที่รับมาคือข้อมูลที่ส่งไป หากมีคนตัดสินใจที่จะทำให้อินเทอร์เน็ตของฉันพังเพื่อเรียกเสียงหัวเราะ ฉันคงจะโชคร้าย

นี่เป็นสายที่ปลอดภัยใช่ไหม

การเปลี่ยนจาก HTTP แบบข้อความธรรมดาเป็นการเชื่อมต่อ HTTPS ที่ปลอดภัยเป็นการป้องกันที่ดีที่สุดสําหรับตัวกลาง การเชื่อมต่อ HTTPS จะเข้ารหัสทั้งแชแนลจากต้นทางถึงปลายทางก่อนที่จะส่งข้อมูล ทำให้เครื่องระหว่างคุณกับปลายทางไม่สามารถอ่านหรือแก้ไขข้อมูลที่อยู่ระหว่างการส่งได้

แถบอเนกประสงค์ของ Chrome จะแสดงรายละเอียดเกี่ยวกับสถานะการเชื่อมต่อค่อนข้างมาก
แถบอเนกประสงค์ของ Chrome จะแสดงรายละเอียดเกี่ยวกับสถานะการเชื่อมต่อค่อนข้างมาก

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

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

ปลอดภัยอุ่นใจเสมอ

เมื่อขอและติดตั้งใบรับรองแล้ว ให้ตรวจสอบว่าผู้ใช้ได้รับประโยชน์จากการทำงานหนักของคุณ โดยย้ายข้อมูลผู้ใช้ที่มีอยู่ไปยังการเชื่อมต่อ HTTPS อย่างโปร่งใสผ่านการเปลี่ยนเส้นทาง HTTP และตรวจสอบว่าคุกกี้ส่งผ่านการเชื่อมต่อที่ปลอดภัยเท่านั้น

โปรดเดินตามทางนี้

เมื่อผู้ใช้เข้าชม http://example.com/ ให้เปลี่ยนเส้นทางผู้ใช้ไปยัง https://example.com/โดยส่งการตอบกลับ 301 Moved Permanently ที่มีส่วนหัว Location ที่เหมาะสม ดังนี้

$ curl -I http://mkw.st/
HTTP/1.1 301 Moved Permanently
Server: nginx/1.3.7
...
Keep-Alive: timeout=20
Location: https://mkw.st/

คุณตั้งค่าการเปลี่ยนเส้นทางประเภทนี้ในเซิร์ฟเวอร์อย่าง Apache หรือ Nginx ได้อย่างง่ายดาย เช่น การกำหนดค่า Nginx ที่เปลี่ยนเส้นทางจาก http://example.com/ เป็น https://example.com/ จะมีลักษณะดังนี้

server {
    listen [YOUR IP ADDRESS HERE]:80;
    server_name example.com www.example.com;
    location "/" {
        rewrite ^(.*) https://www.example.com$1 permanent;
    }
}

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

การตั้งค่าคุกกี้โดยทั่วไปเกี่ยวข้องกับส่วนหัว HTTP ที่ดูคล้ายกับตัวอย่างต่อไปนี้

set-Cookie: KEY=VALUE; path=/; expires=Sat, 01-Jan-2022 00:00:00 GMT

คุณสามารถสั่งให้เบราว์เซอร์จํากัดการใช้คุกกี้เพื่อรักษาเซสชันให้ปลอดภัยได้โดยติดคีย์เวิร์ดเดียวไว้ท้าย

Set-Cookie: KEY=VALUE; path=/; expires=Sat, 01-Jan-2022 00:00:00 GMT; secure

ระบบจะไม่ส่งคุกกี้ที่ตั้งค่าด้วยคีย์เวิร์ด secure ผ่าน HTTP ไม่ว่าในกรณีใดก็ตาม

การปิดหน้าต่างที่เปิดอยู่

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

คุณสามารถลดความเสี่ยงของการโจมตีประเภทนี้ได้ด้วยการขอให้เบราว์เซอร์บังคับใช้ HTTP Strict Transport Security (HSTS) การส่งStrict-Transport-Securityส่วนหัว HTTP จะสั่งให้เบราว์เซอร์เปลี่ยนเส้นทาง HTTP เป็น HTTPS ฝั่งไคลเอ็นต์โดยไม่ต้องเข้าถึงเครือข่าย (วิธีนี้ยังส่งผลดีต่อประสิทธิภาพด้วย เนื่องจากคำขอที่ดีที่สุดคือคำขอที่คุณไม่ต้องส่ง)

$ curl -I https://mkw.st/
HTTP/1.1 200 OK
Server: nginx/1.3.7
...
Strict-Transport-Security: max-age=2592000

เบราว์เซอร์ที่รองรับส่วนหัวนี้ (ปัจจุบันมีเพียง Firefox, Chrome และ Opera: caniuse มีรายละเอียด) จะบันทึกว่าเว็บไซต์นี้ขอการเข้าถึงผ่าน HTTPS เท่านั้น ซึ่งหมายความว่าไม่ว่าผู้ใช้จะเข้าชมเว็บไซต์ด้วยวิธีใดก็ตาม ก็จะเข้าชมผ่าน HTTPS แม้ว่าผู้ใช้จะพิมพ์ http://example.com/ ในเบราว์เซอร์ แต่ผู้ใช้จะเข้าสู่ HTTPS โดยไม่ต้องทำการเชื่อมต่อ HTTP เลย และยิ่งไปกว่านั้น หากเบราว์เซอร์ตรวจพบใบรับรองที่ไม่ถูกต้อง (อาจพยายามแกล้งเป็นข้อมูลประจำตัวของเซิร์ฟเวอร์) ระบบจะไม่อนุญาตให้ผู้ใช้ดำเนินการต่อผ่าน HTTP แต่จะดำเนินการต่อผ่าน HTTPS เท่านั้น ซึ่งถือเป็นเรื่องยอดเยี่ยม

เบราว์เซอร์จะทําให้สถานะ HSTS ของเซิร์ฟเวอร์หมดอายุหลังจาก max-age วินาที (ประมาณ 1 เดือนในตัวอย่างนี้) ให้ตั้งค่านี้ให้สูงพอสมควร

นอกจากนี้ คุณยังตรวจสอบได้ว่าโดเมนย่อยทั้งหมดของต้นทางได้รับการปกป้องแล้วโดยเพิ่มคำสั่ง includeSubDomains ลงในส่วนหัว ดังนี้

$ curl -I https://mkw.st/
HTTP/1.1 200 OK
Server: nginx/1.3.7
...
Strict-Transport-Security: max-age=2592000

ดำเนินการต่ออย่างปลอดภัย

HTTPS เป็นวิธีเดียวที่จะทำให้คุณมั่นใจได้ในระดับหนึ่งว่าข้อมูลที่ส่งถึงผู้รับที่ต้องการจะไปถึงมือผู้รับอย่างปลอดภัย คุณควรตั้งค่าการเชื่อมต่อที่ปลอดภัยสําหรับเว็บไซต์และแอปพลิเคชันของคุณตั้งแต่วันนี้ กระบวนการนี้ค่อนข้างตรงไปตรงมาและจะช่วยรักษาข้อมูลของลูกค้าให้ปลอดภัย เมื่อคุณมีช่องทางที่เข้ารหัสแล้ว คุณควรเปลี่ยนเส้นทางผู้ใช้ไปยังการเชื่อมต่อที่ปลอดภัยนี้อย่างโปร่งใส ไม่ว่าผู้ใช้จะเข้ามายังเว็บไซต์ของคุณด้วยวิธีใดก็ตาม โดยส่งการตอบกลับ HTTP 301 จากนั้นตรวจสอบว่าข้อมูลเซสชันที่ละเอียดอ่อนของผู้ใช้ทั้งหมดใช้การเชื่อมต่อที่ปลอดภัยนั้นเท่านั้นด้วยการเพิ่มคีย์เวิร์ดsecure เมื่อตั้งค่าคุกกี้ เมื่อทําเสร็จแล้ว ให้ตรวจสอบว่าผู้ใช้จะไม่พลาดโอกาสโดยไม่ตั้งใจ โดยปกป้องผู้ใช้โดยการตรวจสอบว่าเบราว์เซอร์ทํางานอย่างถูกต้องด้วยการส่งส่วนหัว Strict-Transport-Security

การตั้งค่า HTTPS นั้นไม่ยุ่งยากและมีประโยชน์อย่างมากต่อเว็บไซต์และผู้ใช้ คุ้มค่ากับความพยายาม

แหล่งข้อมูล

  • StartSSL มีใบรับรองที่ยืนยันด้วยโดเมนให้ใช้งานฟรี ไม่มีอะไรคุ้มค่าไปกว่าการได้รับบริการฟรี แน่นอนว่าคุณอาจอัปเกรดการยืนยันเป็นระดับที่สูงขึ้นได้โดยมีราคาไม่แพง
  • การทดสอบเซิร์ฟเวอร์ SSL: เมื่อตั้งค่า HTTPS สำหรับเซิร์ฟเวอร์แล้ว ให้ตรวจสอบว่าได้ดำเนินการอย่างถูกต้องแล้วโดยทำการทดสอบเซิร์ฟเวอร์ของ SSL Labs คุณจะได้รับรายงานที่ละเอียดซึ่งจะแสดงว่าคุณพร้อมใช้งานแล้วจริงๆ หรือไม่
  • บทความล่าสุดของ Ars Technica เรื่อง"การรักษาความปลอดภัยให้เว็บเซิร์ฟเวอร์ด้วย SSL/TLS" เป็นเรื่องที่ควรอ่านเพื่อดูรายละเอียดเพิ่มเติมเกี่ยวกับพื้นฐานการตั้งค่าเซิร์ฟเวอร์
  • ข้อกำหนด HTTP Strict Transport Security (RFC6797) เป็นเอกสารที่ควรอ่านคร่าวๆ เพื่อดูข้อมูลทางเทคนิคทั้งหมดเกี่ยวกับส่วนหัว Strict-Transport-Security ที่คุณอาจต้องการ
  • เมื่อคุณเข้าใจสิ่งที่ทําอยู่จริงๆ ขั้นตอนถัดไปที่เป็นไปได้คือการโฆษณาว่าเว็บไซต์ของคุณควรเข้าถึงได้ผ่านชุดใบรับรองที่เฉพาะเจาะจงเท่านั้น IETF กำลังดำเนินการบางอย่างที่จะช่วยให้คุณดำเนินการดังกล่าวได้ผ่านส่วนหัว Public-Key-Pins อยู่ ขณะนี้ยังอยู่ในขั้นเริ่มต้น แต่ก็น่าสนใจและควรติดตาม