uBlock Origin แก้โค้ด CNAME uncloaking เพื่อสะท้อนตัวเลือก ipaddress=
(github.com/gorhill)- คอมมิตของ uBlock Origin ปรับเขียนโฟลว์ CNAME uncloaking ในการประมวลผลเครือข่ายของ Firefox ใหม่ และเปลี่ยนให้สะท้อน IP ที่ได้จากการค้นหา DNS ลงใน
details.ip - แคช
cnamesMap เดิมถูกยกเลิก และแทนที่ด้วย ring buffer 256 รายการ ที่อิงdnsList,dnsDict,dnsWritePtrพร้อมแคช TTL60000ms - การค้นหา DNS ใช้
browser.dns.resolve(hn, [ 'canonical_name' ])และนำcanonicalNameกับaddresses[0]ในผลลัพธ์มาใช้เป็น CNAME และ IP ตามลำดับ - การจัดการข้อยกเว้น CNAME ยังคงเงื่อนไข 1st-party, ignore list และ root document ไว้ และชื่อโฮสต์ที่เป็นที่อยู่ IPv4 หรือขึ้นต้นด้วย
[จะถูก ยกเว้นจากการค้นหาซ้ำ - เวอร์ชันขั้นต่ำของ Chromium เพิ่มเป็น
80.0, เวอร์ชันขั้นต่ำของ Opera เพิ่มเป็น67.0และลบค่าเริ่มต้นcnameMaxTTLในการตั้งค่าที่ซ่อนอยู่
ปรับโครงสร้างแคช DNS ของ Firefox ใหม่
- โค้ดที่เกี่ยวข้องกับ CNAME uncloaking ใน
platform/firefox/vapi-background-ext.jsเปลี่ยนจากโครงสร้างที่เน้น Map แบบ global ไปเป็นโครงสร้าง แคช DNS ภายในคลาส - แทนที่จะใช้สถานะ global
cnameUncloakEnabledและcnamesMap เดิม จะจัดการแคชด้วยฟิลด์ต่อไปนี้dnsList: ring bufferdnsWritePtr: ตำแหน่งเขียนถัดไปdnsMaxCount: สูงสุด256dnsDict: แมปจากชื่อโฮสต์ไปยังดัชนีของ ring bufferdnsEntryTTL:60000ms
- ใน constructor จะเริ่มต้น
canUncloakCnamesและcnameUncloakEnabledเป็นtrue
โฟลว์การประมวลผลคำขอ
onBeforeSuspendableRequest(details)ดึงชื่อโฮสต์จาก URL ของคำขอ แล้วตรวจสอบแคชก่อนด้วยdnsFromCache(hn)- หากรายการ DNS ที่แคชไว้มี
ipจะตั้งค่าให้details.ip - หากผลลัพธ์จากการเรียก
super.onBeforeSuspendableRequest(details)ตามปกติจบลงด้วยการยกเลิกหรือ redirect เป็นต้น จะคืนผลลัพธ์นั้นตามเดิม - หากรายการ DNS ที่แคชไว้ไม่ใช่
Promiseจะดำเนินการต่อด้วยonAfterDNSResolution(hn, details, dnsEntry) - หากไม่เข้าเงื่อนไขสำหรับการค้นหา DNS ซ้ำ หรือมี
details.proxyInfo?.proxyDNSจะไม่ทำการประมวลผล DNS เพิ่มเติม
วิธีค้นหาและบันทึก DNS
dnsShouldResolve(hn)จะ ยกเว้นจากเป้าหมายการค้นหา DNS สำหรับชื่อโฮสต์ว่าง, ชื่อโฮสต์ที่ขึ้นต้นด้วย[และรูปแบบที่อยู่ IPv4dnsResolve(hn, details)ลงทะเบียนชื่อโฮสต์ไว้ที่ตำแหน่งปัจจุบันของ ring buffer แล้วเรียกdnsAPI.resolve(hn, [ 'canonical_name' ])- เมื่อค้นหาสำเร็จจะเรียก
dnsToCache(hn, rec, details)และหากล้มเหลวจะเรียกdnsToCache(hn)เพื่อทิ้งรายการว่างไว้ในแคช dnsToCacheบันทึกhnและเวลาหมดอายุไว้ในรายการแคชใหม่- หาก
cnameFromRecordคืนค่า จะบันทึกไว้ในdnsEntry.cname - หาก
ipFromRecordคืนค่า จะบันทึกไว้ในdnsEntry.ip
- หาก
dnsFromCacheจะคืนค่ารายการแคชตามเดิมหากเป็นPromiseและจะลบรายการที่หมดอายุออกจากdnsListและdnsDict
เงื่อนไขการสะท้อน CNAME และ IP
cnameFromRecord(hn, record, details)จะไม่คืนค่า CNAME หากไม่มีrecord.canonicalNameหรือค่าเท่ากับชื่อโฮสต์เดิม- หากเปิด
cnameIgnore1stPartyจะยกเว้นกรณีที่โดเมนของ CNAME กับชื่อโฮสต์เดิมเหมือนกัน - หากมี
cnameIgnoreListจะยกเว้น CNAME ที่ไม่แมตช์กับ regular expression นั้น - หากเปิด
cnameIgnoreRootDocumentจะยกเว้นเมื่อชื่อโฮสต์ของคำขอตรงกับชื่อโฮสต์ของdetails.documentUrl || details.url ipFromRecord(record)จะคืนค่าที่อยู่แรกaddresses[0]เมื่อrecord.addressesเป็น array และไม่ว่าง
การเขียน URL ใหม่และการกรองถัดไป
onAfterDNSResolutionจะเขียน URL ใหม่ด้วยuncloakURLหากรายการ DNS มี CNAME และเปิดcnameUncloakEnabled- เมื่อเปลี่ยน URL จะเก็บ URL เดิมไว้ใน
details.aliasURLและสะท้อน URL ใหม่ลงในdetails.url - หากรายการ DNS มี IP และต่างจาก
details.ipปัจจุบัน จะอัปเดตdetails.ip - จะเรียก
onBeforeSuspendableRequest(details)ของคลาสพื้นฐานอีกครั้งเฉพาะเมื่อเกิด การเขียน CNAME ใหม่ หรือการเปลี่ยน IP เท่านั้น uncloakURLจะหาตำแหน่งชื่อโฮสต์ใน URL แล้วเปลี่ยนเป็น CNAME และจะต่อ URL ทั้งหมดหรือคงไว้ถึงช่วงต้นของ path เท่านั้นตามค่าcnameReplayFullURL
การเปลี่ยนแปลงการตั้งค่าและ manifest
- ลบการจัดการ
cnameMaxTTLออกจากsetOptions - เมื่อเปลี่ยนตัวเลือก จะล้างแคช DNS ด้วย
dnsList.fill(null)และdnsDict.clear()แทนการรีเซ็ตcnamesMap เดิม - ลบ
cnameMaxTTL: 120ออกจากค่าเริ่มต้นของการตั้งค่าที่ซ่อนอยู่ในsrc/js/background.js minimum_chrome_versionในplatform/chromium/manifest.jsonเปลี่ยนจาก73.0เป็น80.0minimum_opera_versionในplatform/opera/manifest.jsonเปลี่ยนจาก60.0เป็น67.0
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
คิดว่าชื่อเรื่องน่าจะผิด uBlock Origin รองรับฟีเจอร์นี้มาหลายปีแล้ว เพียงแต่ทำได้เฉพาะบน Firefox เท่านั้น
กรณีนี้ดูเหมือนเป็นการรีแฟกเตอร์โค้ดนั้นมากกว่าจะเป็นฟีเจอร์ใหม่ทั้งหมด
แต่ก็ยังไม่สมบูรณ์แบบ เพราะเมื่อโดเมนหนึ่งมีหลาย IP ก็ไม่รู้ว่าเบราว์เซอร์จะเลือก IP ไหน
ถ้ามีข้อเสนอชื่อที่แม่นยำและเป็นกลางกว่านี้ก็เปลี่ยนได้อีก แต่โดยทั่วไปคอมมิตบน GitHub ที่ไม่มีบริบทเพิ่มเติมมักไม่ค่อยเหมาะกับเธรด HN เท่าไร
ยังไม่ได้รับผลกระทบโดยตรง แต่ถ้า Chrome กำจัด uBO ออกไปจริง ๆ ก็ได้เริ่มปรับส่วนขยายของตัวเองให้ใช้กับ Firefox ได้แล้ว เพื่อให้ย้ายได้
น่าจะมาถึงภายในไม่กี่รุ่นถัดไป จึงควรเตรียมตัวไว้
อย่างมากก็แค่เปลี่ยน
background.service_workerเป็นbackground.scriptsเท่านั้น พูดตรง ๆ คือเปลี่ยนแค่ชื่อคีย์uBlock Origin เป็นสิ่งที่ทำให้ Firefox ยอดเยี่ยมขึ้น และเป็นหนึ่งในเหตุผลสำคัญที่ใช้ Firefox แทน Chrome และอื่น ๆ
มันทำให้อินเทอร์เน็ตอยู่ในสภาพที่ท่องเว็บได้จริง
ตลอดกว่า 10 ปี มีปัญหาการแสดงผลกับบางเว็บอยู่บ้าง แต่เว็บเหล่านั้นก็มีปัญหาบน Chrome เช่นกัน
โดยส่วนตัวมองว่าโฆษณาเป็นเหมือนมะเร็งของสังคมยุคใหม่ มันผสมปนเปกันระหว่างคำโกหกสีขาว คำโกหกที่ไม่ใช่สีขาว และการชักใย แถมยังมีเงินมหาศาลไหลผ่าน จึงยิ่งไม่มีอะไรให้น่าเคารพเลย
Brave ก็เป็นโปรเจกต์คุณภาพดี เลยใช้เป็นตัวสำรอง และบางครั้งก็ใช้ Vivaldi ปนด้วยเพราะการแบ่งหน้าต่างและการจัดการแท็บที่ดีกว่ามาก
CNAME cloaking หมายถึงการที่เว็บโฆษณาใช้ซับโดเมนที่สร้างแบบสุ่มซึ่งชี้ไปยัง wildcard record ใช่ไหม?
โดยทั่วไปเมื่อเข้าชม contentsite.com โฆษณาจะถูกเสิร์ฟจาก adsite.com กฎบล็อกโฆษณาแค่บล็อก adsite.com โฆษณาก็จะไม่แสดง
CNAME cloaking คือวิธีที่เว็บไซต์หลักทำให้ซับโดเมนอย่าง adsite.contentsite.com ชี้ไปยัง adsite.com แบบนี้ตัวบล็อกโฆษณาก็ต้องทำงานแทบเป็นไปไม่ได้ คือบล็อกซับโดเมนหลายล้านรายการที่ดูเหมือนเป็นของเว็บไซต์ปกติ
เว็บไซต์ปกติยังสามารถเปลี่ยนซับโดเมนไปเรื่อย ๆ ได้ และตัวบล็อกโฆษณาก็ไม่มีทางรู้ว่าซับโดเมนไหนเป็นเนื้อหาปกติ และซับโดเมนไหนเป็นโฆษณา อีกทั้งเพราะเนื้อหาถูกเสิร์ฟจากโดเมนเดียวกัน จึงอาจเลี่ยงนโยบายคุกกี้บางอย่างเพื่อใช้ติดตามผู้ใช้ได้ดีขึ้นด้วย
การอัปเดตครั้งนี้ทำให้สามารถตั้งกฎที่กรองตาม IP ที่ถูก resolve แล้วได้
นี่เป็นตัวอย่างที่ดีว่า ทำไม Manifest V3 ถึงไม่ค่อยดี โดยนิยามแล้วมันทำสิ่งแบบนี้ไม่ได้ และ heuristic ที่อิงโค้ดขณะรันก็ทำไม่ได้เช่นกัน
นี่คือการแข่งขันยกระดับกับผู้ลงโฆษณา และ Google เป็นพ่อค้าขายอาวุธให้ทั้งสองฝ่าย พวกเขาจะไม่ให้สิ่งที่ผู้ใช้ต้องใช้เพื่อชนะ
แน่นอนว่าทั้งหมดนี้ขึ้นอยู่กับว่าผู้ให้บริการเบราว์เซอร์ หรือก็คือ Google อยากเพิ่ม API นี้หรือไม่ การมี “โค้ดขณะรัน” เพื่อประมวลผลแบบ imperative ช่วยให้เกิดนวัตกรรมใน user space ได้ก่อนที่ผู้สร้างเบราว์เซอร์จะใส่การรองรับในตัว
ดังนั้นการบอกว่าฟีเจอร์บางอย่างเป็นไปไม่ได้ “โดยนิยาม” จึงไม่ถูกต้อง
[1] https://blog.mozilla.org/addons/2022/05/18/manifest-v3-in-fi...
การพราง CNAME ยกตัวอย่างเช่น สมมติว่าผู้ให้บริการ SaaS A ต้องการให้ซอฟต์แวร์ติดตามโฆษณาสุดเจ๋งแก่บริษัท Q
ถ้าเป็นวิธีเดิม A ก็น่าจะบอกให้ Q แทรกสคริปต์ เช่น https://A-ads-tracking.example ลงในเว็บไซต์ของบริษัท Q ที่อยู่ที่
https://q-company.exampleจากนั้นในรายการบล็อกที่ uBlock Origin ใช้ ก็จะมีกฎประมาณว่า “บล็อกคำขอที่ไปยังโดเมน A-ads-tracking.example” แล้วโฆษณาก็จะถูกบล็อก
การพราง CNAME คือวิธีที่ผู้ให้บริการ SaaS A ไม่ได้วางบริการติดตามโฆษณาไว้ที่โดเมน A-ads-tracking.example แต่ไปวางไว้ที่ที่อยู่ IP เฉพาะ เช่น 29.1.2.3 และส่วนสำคัญคือ SaaS A จะขอให้บริษัท Q สร้างซับโดเมนของ q-company.example แล้วให้เรคคอร์ด CNAME ของมันชี้ไปที่ 23.1.2.3 พร้อมตั้งชื่อที่ดูน่าเชื่อถืออย่าง media.q-company.example
หลังจากบริษัท Q ตั้งค่า CNAME นั้นแล้วเพิ่มแท็กสคริปต์
media.q-company.exampleลงในเว็บไซต์ SaaS A ก็จะสามารถติดตามผู้ใช้ทั้งหมดของไซต์นั้นได้ เพราะชั้นการเลี่ยงแบบนี้ ทำให้เกิดเกมแมวไล่จับหนูที่แทบไม่มีที่สิ้นสุดระหว่างเจ้าของบริษัท Q กับรายการบล็อกสาธารณะถ้าจะหลีกเลี่ยงปัญหานี้ ซอฟต์แวร์ที่รันส่วนขยายอย่าง uBlock Origin จำเป็นต้องมองเห็นไม่ใช่แค่โดเมนปลายทางของคำขอในเบราว์เซอร์ แต่รวมถึงที่อยู่ IP จริงของโดเมนนั้นด้วย คอมมิตนี้ดูเหมือนจะเกี่ยวกับการทำให้พฤติกรรมดังกล่าวเป็นไปได้ หรืออย่างน้อยก็ทำให้โค้ดส่วนนั้นทำงานได้ดีขึ้น
ตัวอย่างเช่น
media.q-company.exampleเป็น CNAME ที่ชี้ไปยังq-company.ads-tracking.exampleแล้วจากนั้นq-company.ads-tracking.exampleจึงมีเรคคอร์ด A ที่ให้ IP อีกทีไม่แน่ใจว่าเบราว์เซอร์ส่งชื่อ DNS ระหว่างทางให้ส่วนขยายหรือไม่ ดังนั้นเครื่องมืออย่าง uBlock อาจต้องพึ่งพารายการ IP แต่การกรองแบบอิง DNS อย่าง pihole สามารถบล็อกได้ง่าย ๆ ด้วยกฎสำหรับ
ads-tracking.exampleไม่ว่าอย่างไร การใช้ตัวบล็อกสิ่งประสงค์ร้ายทั้งแบบบนเบราว์เซอร์และแบบอิง DNS ควบคู่กันก็เป็นเรื่องดี
มันช้าและพลาดได้ง่าย แต่พอชินแล้วก็สบายขึ้น และจะมีภูมิคุ้มกันต่อกลเม็ดไร้สาระแบบนี้อย่างสมบูรณ์
Chrome กำลังจะบล็อก uBO หรือเปล่า? ไม่ได้ตามสถานการณ์ล่าสุดตลอด
เท่าที่รู้ ตอนนี้เขาอนุญาตคุกกี้บุคคลที่สามแล้ว ดังนั้นบางทีอาจเป็นไปได้ก็ได้
กำลังตัด API หลักที่จำเป็นสำหรับให้ uBO ระบุว่าอะไรไม่ควรถูกโหลด แล้วทำให้สิ่งนั้นไม่ถูกโหลด
Google อ้างว่าเป็นเพราะ “ประสิทธิภาพ” หรือ “ความปลอดภัย” แน่นอนว่า “ประสิทธิภาพ” หรือ “ความปลอดภัย” อย่างเดียวที่ได้รับผลกระทบจริง ๆ อย่างมากคือความสามารถในการระบุ ดัก และหยุดการดาวน์โหลดที่เป็นอันตรายหรือเกี่ยวกับโฆษณาก่อนที่มันจะเริ่มต้น
https://developer.chrome.com/docs/extensions/develop/migrate...
https://www.bleepingcomputer.com/news/google/google-chrome-w...
ถ้าใช้ Chromium เวอร์ชันที่รองรับเฉพาะ Manifest V3 ก็จะถูกซ่อนไว้
ในเซิร์ฟเวอร์ DNS บางตัวมีฟีเจอร์ที่ทำงานเหมือน CNAME ที่เซิร์ฟเวอร์ resolve ให้แล้วไม่ใช่หรือ? คือผู้ดูแลใส่เรคคอร์ดที่ชี้ไปยังชื่อ DNS อื่น แต่ไคลเอนต์เห็นแค่เรคคอร์ด A หรือ AAAA เท่านั้นน่ะ
uBO มีฟีเจอร์นี้มาค่อนข้างนานแล้ว ตั้งแต่ 1.34.0 และใน advanced settings ก็มีตั้งแต่ 1.25.0
https://github.com/gorhill/uBlock/wiki/Dashboard:-Settings#u...
จำได้คร่าว ๆ ว่าน่าจะราวปี 2021
สถานะของ uBO บน Brave, Edge, Opera เป็นอย่างไรบ้าง?
https://brave.com/blog/brave-shields-manifest-v3/
อย่างไรก็ตาม ไม่จำเป็นถึงขั้นนั้น Brave มีตัวบล็อกโฆษณาในตัวที่ค่อนข้างทรงพลังอยู่แล้ว และเท่าที่ตรวจสอบครั้งล่าสุด มันถูกคอมไพล์เป็น native code จึงมีประสิทธิภาพสูงกว่า uBO และรองรับรายการโฆษณาเดียวกันได้ครบถ้วน