Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> ซอฟต์แวร์ >> เบราว์เซอร์

ทำความเข้าใจวิธีการที่เบราว์เซอร์ประมวลผลเนื้อหาเว็บ

บทนำสู่ความปลอดภัยของเว็บแอปพลิเคชัน

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

เบราว์เซอร์คือ Rendering Engine (เครื่องมือเรนเดอร์) หน้าที่ของมันคือดาวน์โหลดหน้าเว็บและแสดงผลในรูปแบบที่มนุษย์เข้าใจได้

แม้ว่านี่จะเป็นการลดความซับซ้อนเกินไป แต่เพียงเท่านี้ก็เพียงพอสำหรับตอนนี้

  • ผู้ใช้ป้อนที่อยู่ในแถบที่อยู่ของเบราว์เซอร์
  • เบราว์เซอร์ดาวน์โหลด "เอกสาร" ที่ URL นั้นและแสดงผล

คุณอาจคุ้นเคยกับเบราว์เซอร์ยอดนิยมอย่าง Chrome, Firefox, Edge หรือ Safari แต่ไม่ได้หมายความว่าไม่มีเบราว์เซอร์อื่นๆ อยู่

ตัวอย่างเช่น lynx เป็นเบราว์เซอร์เบาๆ ที่ทำงานจากบรรทัดคำสั่ง (command line) ที่หัวใจของ lynx มีหลักการเดียวกับเบราว์เซอร์ "หลัก流行" อื่นๆ ผู้ใช้ป้อนที่อยู่เว็บ (URL) เบราว์เซอร์ดึงเอกสารและแสดงผล — แตกต่างกันเพียงอย่างเดียวคือ lynx ไม่ใช้ Visual Rendering Engine แต่ใช้ Text-based Interface แทน ทำให้เว็บไซต์อย่าง Google ดูเหมือนนี้:

[รูปภาพแสดง lynx กำลังแสดง Google]

เบราว์เซอร์ทำอะไรบ้าง?

สรุปสั้นๆ งานหลักของเบราว์เซอร์ประกอบด้วย:

  • DNS Resolution (การแก้ไข DNS)
  • HTTP Exchange (การแลกเปลี่ยน HTTP)
  • Rendering (การเรนเดอร์)
  • ทำซ้ำขั้นตอนเหล่านี้

DNS Resolution

กระบวนการนี้ทำให้แน่ใจว่าเมื่อผู้ใช้ป้อน URL เบราว์เซอร์จะรู้ว่าต้องเชื่อมต่อกับเซิร์ฟเวอร์ไหน เบราว์เซอร์ติดต่อ DNS Server เพื่อหาว่า google.com แปลเป็น 216.58.207.110 ซึ่งเป็น IP Address ที่เบราว์เซอร์สามารถเชื่อมต่อได้

HTTP Exchange

เมื่อเบราว์เซอร์ระบุได้แล้วว่าเซิร์ฟเวอร์ไหนจะให้บริการคำขอของเรา มันจะเริ่มการเชื่อมต่อ TCP และเริ่ม HTTP Exchange นี่คือวิธีที่เบราว์เซอร์สื่อสารกับเซิร์ฟเวอร์ว่าต้องการอะไร และเซิร์ฟเวอร์ตอบกลับ

HTTP คือชื่อของโปรโตคอลยอดนิยมสำหรับการสื่อสารบนเว็บ และเบราว์เซอร์ส่วนใหญ่สื่อสารผ่าน HTTP เมื่อติดต่อเซิร์ฟเวอร์ การแลกเปลี่ยน HTTP เกิดขึ้นเมื่อ Client (เบราว์เซอร์ของเรา) ส่ง Request และ Server ตอบกลับด้วย Response

ตัวอย่างเช่น หลังจากเบราว์เซอร์เชื่อมต่อกับเซิร์ฟเวอร์หลัง google.com สำเร็จ มันจะส่ง Request ที่คล้ายนี้:

GET / HTTP/1.1
Host: google.com
Accept: */*

ลองแยก Request ออกเป็นบรรทัดต่อบรรทัด:

  • GET / HTTP/1.1: บรรทัดแรกนี้เบราว์เซอร์ขอให้เซิร์ฟเวอร์ดึงเอกสารที่ตำแหน่ง / พร้อมบอกว่าส่วนที่เหลือของ Request จะปฏิบัติตามโปรโตคอล HTTP/1.1 (อาจใช้ 1.0 หรือ 2 ได้)
  • Host: google.com: นี่คือ HTTP Header ที่บังคับใน HTTP/1.1 เท่านั้น เนื่องจากเซิร์ฟเวอร์อาจให้บริการหลายโดเมน (google.com, google.co.uk ฯลฯ) Client จึงระบุว่าคำขอนี้เป็นสำหรับโฮสต์เฉพาะนั้น
  • Accept: */*: Header ตัวเลือก บอกเซิร์ฟเวอร์ว่าเบราว์เซอร์ยอมรับ Response ประเภทใดก็ได้ เซิร์ฟเวอร์อาจมีทรัพยากรที่มีในรูปแบบ JSON, XML หรือ HTML จึงสามารถเลือกได้ตามต้องการ

หลังจาก Client (เบราว์เซอร์) ส่ง Request เสร็จ ก็ถึงคิวของ Server ตอบกลับ Response คล้ายนี้:

HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Type: text/html; charset=ISO-8859-1
Server: gws
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
Set-Cookie: NID=1234; expires=Fri, 18-Jan-2019 18:25:04 GMT; path=/; domain=.google.com; HttpOnly

<!doctype html><html>......</html>

ว้าว ข้อมูลเยอะมากที่ต้องย่อย การตอบกลับบอกว่าคำขอสำเร็จ (200 OK) และเพิ่ม Header หลายตัว เช่น โฆษณาว่าเซิร์ฟเวอร์อะไรประมวลผลคำขอ (Server: gws), นโยบาย X-XSS-Protection ของ Response นี้ ฯลฯ

ตอนนี้คุณไม่จำเป็นต้องเข้าใจทุกบรรทัดใน Response เราจะครอบคลุมโปรโตคอล HTTP, Header ต่างๆ ในภายหลังของซีรีส์นี้

ตอนนี้เพียงต้องเข้าใจว่า Client และ Server กำลังแลกเปลี่ยนข้อมูล และทำได้ผ่าน HTTP

Rendering (การเรนเดอร์)

สุดท้ายแต่สำคัญไม่แพ้กัน คือกระบวนการ Rendering เบราว์เซอร์จะมีประโยชน์แค่ไหนถ้ามันแสดงแค่ตัวอักษรแปลกๆ ให้ผู้ใช้ดู?

<!doctype html><html>......</html>

ใน Body ของ Response เซิร์ฟเวอร์รวมการแสดงผลของ Response ตาม Header Content-Type ในกรณีนี้ Content-Type ถูกตั้งเป็น text/html จึงคาดหวัง HTML Markup ใน Response — ซึ่งตรงกับที่พบใน Body

นี่คือจุดที่เบราว์เซอร์แสดงความสามารถจริง มัน Parse HTML, โหลดทรัพยากรเพิ่มเติมที่อยู่ใน Markup (เช่น ไฟล์ JavaScript หรือเอกสาร CSS ที่ต้องดึงมา) และนำเสนอให้ผู้ใช้โดยเร็วที่สุด

ผลลัพธ์สุดท้ายคือสิ่งที่คนทั่วไปเข้าใจได้

[รูปภาพแสดงหน้าเว็บที่เรนเดอร์แล้ว]

สำหรับรายละเอียดลึกของสิ่งที่เกิดขึ้นจริงๆ เมื่อเรากด Enter ในแถบที่อยู่ของเบราว์เซอร์ ขอแนะนำให้อ่าน "What happens when…" ซึ่งเป็นการพยายามอธิบายกลไกข้างหลังอย่างละเอียด

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

Vendors (ผู้จัดจำหน่าย)

เบราว์เซอร์ 4 ตัวที่ยอดนิยมที่สุดมาจาก Vendor ต่างกัน:

  • Chrome โดย Google
  • Firefox โดย Mozilla
  • Safari โดย Apple
  • Edge โดย Microsoft

นอกจากการแข่งขันกันเพื่อเพิ่ม Market Penetration แล้ว Vendor ยังร่วมมือกันเพื่อปรับปรุง Web Standards ซึ่งเป็น "ข้อกำหนดขั้นต่ำ" สำหรับเบราว์เซอร์

W3C เป็นองค์กรที่พัฒนา Standard แต่ไม่แปลกที่เบราว์เซอร์จะพัฒนาฟีเจอร์ของตัวเองซึ่งภายหลังกลายเป็น Web Standard ความปลอดภัยก็ไม่ใช่ข้อยกเว้น

ตัวอย่างเช่น Chrome 51 นำเสนอ SameSite Cookies ฟีเจอร์ที่ช่วยให้เว็บแอปพลิเคชันกำจัดช่องโหว่ประเภทหนึ่งที่รู้จักกันในชื่อ CSRF (จะอธิบายภายหลอน) Vendor อื่นๆ เห็นว่าดีมาก จึงปฏิบัติตาม ทำให้ SameSite กลายเป็น Web Standard: จนถึงตอนนี้ Safari เป็นเบราว์เซอร์หลักเพียงตัวเดียวที่ไม่รองรับ SameSite Cookies

[รูปภาพแสดงตารางเปรียบเทียบการรองรับ SameSite]

นี่บอกเรา 2 เรื่อง:

  • Safari ดูไม่ค่อยสนใจความปลอดภัยของผู้ใช้ (เฉยๆ นะ: SameSite Cookies จะมีใน Safari 12 ซึ่งอาจวางจำหน่ายแล้วตอนที่คุณอ่านบทความนี้)
  • การแก้ช่องโหว่ในเบราว์เซอร์หนึ่งไม่ได้หมายความว่าผู้ใช้ทุกคนปลอดภัย

จุดแรกเป็นการเยาะ Safari (บอกแล้วว่าเฉยๆ!) ส่วนจุดที่สองสำคัญมาก ในการพัฒนาเว็บแอปพลิเคชัน เราไม่แค่ต้องทำให้ดูเหมือนกันในเบราว์เซอร์ต่างๆ แต่ต้องทำให้ผู้ใช้ได้รับการป้องกันในลักษณะเดียวกันทุกแพลตฟอร์ม

กลยุทธ์ด้านความปลอดภัยของคุณควรแตกต่างกันไปตามสิ่งที่ Vendor ของเบราว์เซอร์อนุญาตให้ทำ ปัจจุบันเบราว์เซอร์ส่วนใหญ่รองรับชุดฟีเจอร์เดียวกัน และนادرที่จะเบี่ยงเบนจาก Road Map ร่วมกัน แตกรณีแบบด้านบนยังคงเกิดขึ้น และเราต้องคำนึงถึงเมื่อกำหนดกลยุทธ์ความปลอดภัย

ในกรณีของเรา ถ้าตัดสินใจลดทอนการโจมตี CSRF เพียงแค่ผ่าน SameSite Cookies เราควรทราบว่ากำลังเสี่ยงผู้ใช้ Safari และผู้ใช้ควรทราบด้วย

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

Pro Tip: คุณไม่ควรกระตุ้นให้ผู้ใช้ใช้เบราว์เซอร์เก่า หรือรองรับอย่างต่อเนื่อง แม้คุณจะมีการป้องกันครบถ้วน นักพัฒนาเว็บคนอื่นอาจไม่ได้ทำเช่นนั้น กระตุ้นให้ผู้ใช้ใช้เวอร์ชันล่าสุดที่รองรับของเบราว์เซอร์หลัก

Vendor Bug หรือ Standard Bug?

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

Vendor โดยทั่วไปให้รางวัล (Bug Bounties) แก่นักวิจัยความปลอดภัยที่พบช่องโหว่บนเบราว์เซอร์ Bug เหล่านี้ไม่เกี่ยวกับการนำไปใช้ของคุณ แต่เกี่ยวกับวิธีที่เบราว์เซอร์จัดการความปลอดภัยด้วยตัวมันเอง

โปรแกรมรางวัลของ Chrome เช่นกัน ให้นักวิศวกรรมความปลอดภัยติดต่อทีมความปลอดภัย Chrome เพื่อรายงานช่องโหว่ที่พบ หากยืนยันแล้ว จะมีการออก Patch, ปล่อย Security Advisory สู่สาธารณะ และนักวิจัยจะได้รับรางวัล (มักเป็นเงิน)

บริษัทอย่าง Google ลงทุนเงิน 꽤 มากใน Bug Bounty Programs เพราะดึงดูดนักวิจัยด้วยผลประโยชน์ทางการเงิน

ใน Bug Bounty Program ทุกฝ่ายได้ประโยชน์: Vendor ปรับปรุงความปลอดภัยของซอฟต์แวร์ และนักวิจัยได้เงินจากผลงาน เราจะพูดถึงโปรแกรมเหล่านี้ภายหลัง เพราะเชื่อว่า Bug Bounty Initiatives สมควรได้รับส่วนของตัวเองในภูมิทัศน์ความปลอดภัย

Jake Archibald เป็น Developer Advocate ที่ Google ซึ่งค้นพบช่องโหว่ที่มีผลกระทบต่อเบราว์เซอร์มากกว่า 1 ตัว เขาบันทึกความพยายาม วิธีการจัดการกับ Vendor ต่างๆ และการตอบสนองของพวกเขาในบล็อกโพสต์น่าสนใจที่ขอแนะนำให้อ่าน

เบราว์เซอร์สำหรับนักพัฒนา

ตอนนี้เราควรเข้าใจแนวคิดที่เรียบง่ายแต่สำคัญ: เบราว์เซอร์คือ HTTP Clients ที่สร้างขึ้นสำหรับผู้เล่นอินเทอร์เน็ตทั่วไป

มันแน่นอนว่ทรงพลังกว่า HTTP Client เบื้องต้นของแพลตฟอร์ม (เช่น require('http') ของ NodeJS) แต่ท้ายที่สุดมันก็เป็น "แค่" 演化 ทางธรรมชาติต่อเนื่องของ HTTP Clients ที่เรียบง่ายกว่า

ในฐานะนักพัฒนา HTTP Client ที่เราเลือกมักจะเป็น cURL โดย Daniel Stenberg หนึ่งในโปรแกรมยอดนิยมที่นักพัฒนาเว็บใช้ทุกวัน มันช่วยให้เราทำ HTTP Exchange แบบ On-the-fly โดยส่ง HTTP Request จาก Command Line:

$ curl -I localhost:8080
HTTP/1.1 200 OK
server: ecstatic-2.2.1
Content-Type: text/html
etag: "23724049-4096-"2018-07-20T11:20:35.526Z"
last-modified: Fri, 20 Jul 2018 11:20:35 GMT
cache-control: max-age=3600
Date: Fri, 20 Jul 2018 11:21:02 GMT
Connection: keep-alive

ในตัวอย่างข้างต้น เราขอเอกสารที่ localhost:8080/ และเซิร์ฟเวอร์ท้องถิ่นตอบกลับสำเร็จ

แทนที่จะ Dump Body ของ Response ลง Command Line ที่นี่เราใช้ Flag -I บอก cURL ว่าเราสนใจแค่ Response Headers หากไปต่ออีกขั้น เราสั่งให้ cURL Dump ข้อมูลเพิ่มเติม รวมถึง Request จริงที่มันทำ เพื่อให้เราเห็น HTTP Exchange ทั้งหมดชัดขึ้น Option ที่ต้องใช้คือ -v (verbose):

$ curl -I -v localhost:8080
* Rebuilt URL to: localhost:8080/
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> HEAD / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< server: ecstatic-2.2.1
< Content-Type: text/html
< etag: "23724049-4096-"2018-07-20T11:20:35.526Z"
< last-modified: Fri, 20 Jul 2018 11:20:35 GMT
< cache-control: max-age=3600
< Date: Fri, 20 Jul 2018 11:25:55 GMT
< Connection: keep-alive
* Connection #0 to host localhost left intact

ข้อมูลเกือบเหมือนกันพร้อมใช้ในเบราว์เซอร์หลักผ่าน DevTools

เช่นที่เห็น เบราว์เซอร์ไม่ได้เป็นอะไรมากกว่า HTTP Clients ที่ซับซ้อน แน่นอนมันเพิ่มฟีเจอร์มหาศาล (Credential Management, Bookmarking, History ฯลฯ) แต่ความจริงคือมันเกิดมาเป็น HTTP Clients สำหรับมนุษย์ นี่สำคัญ เพราะในกรณีส่วนใหญ่คุณไม่ต้องการเบราว์เซอร์ในการทดสอบความปลอดภัยของเว็บแอป คุณแค่ "curl it" และดู Response

อีกอย่างหนึ่งที่อยากชี้ให้เห็น: อะไรก็ตามสามารถเป็นเบราว์เซอร์ได้ หากคุณมี Mobile App ที่บริโภค API ผ่านโปรโตคอล HTTP แล้ว App นั้นคือเบราว์เซอร์ของคุณ — แค่มันเป็นเบราว์เซอร์ที่ปรับแต่งสูงมากซึ่งคุณสร้างเอง ที่เข้าใจเฉพาะประเภท HTTP Response บางประเภท (จาก API ของคุณเอง)

สู่โปรโตคอล HTTP

เช่นที่กล่าวมา HTTP Exchange และ Rendering เป็นเฟสที่เราจะครอบคลุมมากที่สุด เพราะให้ Attack Vectors (เวกเตอร์การโจมตี) มากที่สุดสำหรับผู้ใช้งานร้าย

ในบทความต่อไป เราจะลองดูลึกโปรโตคอล HTTP และพยายามเข้าใจว่าควรมีมาตรการอะไรเพื่อรักษาความปลอดภัยการแลกเปลี่ยน HTTP

เผยแพร่ต้นฉบับที่ odino.org (29 กรกฎาคม 2018)
คุณสามารถติดตามผมได้ที่ Twitter - ยินดีรับฟังความคิดเห็น!

Learn to code for free. freeCodeCamp's open source curriculum has helped more than 40,000 people get jobs as developers. Get started