- Nhóm bảo mật Chrome đã đề xuất một cơ chế "quyền truy cập mạng cục bộ" mới để giải quyết vấn đề website truy cập mạng cục bộ
- Hiện nay, các website công khai có thể có nguy cơ truy cập trái phép hoặc tấn công các thiết bị trong mạng cục bộ của người dùng như máy in, nhưng đề xuất này nhằm chặn các yêu cầu tới mạng cục bộ nếu không có sự cho phép của người dùng
- Khác với Private Network Access (PNA) hiện tại, cơ chế này hoạt động dựa trên sự đồng ý cấp quyền của người dùng thay vì preflight, qua đó tăng cường quyền kiểm soát của người dùng, đồng thời có thể triển khai chỉ bằng cách cập nhật website mà không cần thay đổi thiết bị
- Cụ thể, khi một website công khai gửi yêu cầu fetch tới IP cục bộ, miền
.local v.v., nếu không có quyền thì trình duyệt sẽ hiển thị yêu cầu xin chấp thuận rõ ràng tới người dùng
- Với chính sách này, bên cạnh việc tăng cường bảo mật và quyền riêng tư, các trường hợp sử dụng hợp lệ như cấu hình thiết bị IoT vẫn sẽ được đảm bảo hoạt động bình thường nếu người dùng cho phép
Tổng quan và mục tiêu của đề xuất
- Nhóm Chrome Secure Web and Network đã công bố bản thiết kế ban đầu cho cơ chế cấp quyền 'truy cập mạng cục bộ' nhằm giải quyết vấn đề website công khai truy cập trái phép vào mạng cục bộ
- Trước đây, các website người dùng truy cập có thể thử thực hiện CSRF hoặc các cuộc tấn công khác tới thiết bị trong mạng cục bộ như máy in, bộ định tuyến
- Trong tương lai, đề xuất đưa ra cấu trúc trong đó trình duyệt sẽ chặn các yêu cầu vượt qua ranh giới giữa các không gian địa chỉ, như IP công khai → IP cục bộ, và chỉ cho phép khi có sự chấp thuận rõ ràng của người dùng theo từng website
Bối cảnh và điểm khác biệt
- Private Network Access (PNA) hiện tại dựa trên preflight (yêu cầu/phản hồi trước), đồng thời cũng đòi hỏi thiết bị phải thay đổi nên khó triển khai
- Đề xuất lần này có thể xử lý chỉ bằng sự đồng ý cấp quyền của người dùng, và vì chỉ cần chỉnh sửa nhẹ ở phía website nên dễ áp dụng và phổ biến hơn trong thực tế
Mục tiêu và những gì không nhằm tới
- Mục tiêu
- Ngăn chặn việc khai thác thiết bị và máy chủ dễ bị tấn công thông qua web kiểu drive-by
- Chỉ cho phép website công khai giao tiếp với thiết bị cục bộ khi người dùng thực sự muốn và cho phép
- Không nhằm tới
- Không chủ trương chặn toàn bộ các luồng sử dụng hợp lý như cấu hình/điều khiển thiết bị cục bộ hiện có
- Các vấn đề như HTTPS trong mạng cục bộ hay cấp phát chứng chỉ phức tạp không nằm trong phạm vi của đề xuất lần này
Các trường hợp sử dụng
- Trường hợp 1: Nếu người dùng không mong muốn, khi example.com gửi yêu cầu tới 192.168.0.1 chẳng hạn, trình duyệt sẽ hỏi có cho phép hay không; nếu từ chối thì yêu cầu sẽ bị chặn
- Trường hợp 2: Các trang cấu hình web chính thức của nhà sản xuất thiết bị như IoT, bộ định tuyến sẽ được phép giao tiếp sau khi nhận được sự cho phép của người dùng trong lần truy cập đầu tiên
Thiết kế cụ thể
- Phân tách không gian địa chỉ:
- Phân loại các lớp mạng IP thành ba tầng:
loopback (chỉ dành cho chính máy đó), local (bên trong mạng cục bộ), public (mọi nơi đều có thể truy cập)
- Bao gồm nhiều tiêu chí nhận diện mạng cục bộ như miền
.local, IP riêng theo RFC1918/4193, tên link-local theo RFC6762
- Yêu cầu mạng cục bộ: yêu cầu quyền khi truy cập từ public→local, public→loopback, local→loopback
- Các truy cập từ mạng công khai vào mạng cục bộ/loopback, cũng như từ local vào loopback, đều được coi là yêu cầu mạng cục bộ
- Ngoại lệ: local→local, loopback→bất kỳ địa chỉ nào v.v. không thuộc diện bị hạn chế
- Hộp thoại xin quyền:
- Khi website gửi yêu cầu tới mạng cục bộ mà chưa có quyền, trình duyệt sẽ hiển thị lời nhắc hỏi người dùng có cho phép hay không
- Nếu từ chối thì chặn yêu cầu, nếu chấp nhận thì tiếp tục yêu cầu
- Tích hợp với fetch API: có thể chỉ định các tùy chọn như
targetAddressSpace: "local" trong lời gọi fetch để phân biệt rõ ràng
- Đặc tả Fetch chỉ định nghĩa kết nối đơn thuần mà không có phân giải DNS, nên sẽ xác định đây có phải là yêu cầu mạng cục bộ hay không tại thời điểm tạo kết nối mới
- Chỉ cho phép yêu cầu mạng cục bộ trong security context; nếu chưa có quyền thì hiện prompt, nếu đã được cấp quyền thì cho phép yêu cầu
- Thêm tham số
targetAddressSpace vào options của fetch() để nhà phát triển có thể chỉ định rõ không gian địa chỉ đích
- Nếu địa chỉ kết nối thực tế không khớp với không gian được chỉ định trong option, yêu cầu sẽ thất bại để ngăn vượt qua mixed content
- HTML, WebRTC, ServiceWorker v.v. cũng áp dụng cùng chính sách
- Thêm giá trị không gian địa chỉ vào tài liệu HTML/worker để theo dõi không gian dựa trên origin
- Khi thêm candidate cho ICE Agent trong WebRTC, các địa chỉ local/loopback sẽ dùng prompt xin quyền
- Quyền này được liên kết với Permissions API, cho phép website truy vấn trạng thái quyền hiện tại
- Theo mặc định, chỉ tài liệu cấp cao nhất mới có thể truy cập mạng cục bộ; khi cần có thể ủy quyền cho frame con bằng chính sách ủy quyền của Permissions Policy
- Vấn đề mixed content (HTTP/HTTPS):
- Bao gồm các kịch bản như thử truy cập mạng cục bộ từ non-secure context, tải subresource HTTP, hay áp dụng chặn mixed content
- Với private IP literal, miền
.local, hoặc các yêu cầu có chỉ định targetAddressSpace, sẽ bỏ qua bước nâng cấp và chặn mixed content, rồi chặn ở kết nối tiếp theo nếu origin chưa có quyền
- Ví dụ về cách hoạt động
- Khi có truy cập mạng cục bộ ngoài mong đợi, người dùng có thể từ chối quyền để chặn các yêu cầu trái phép
- Với trang điều khiển thiết bị do nhà sản xuất vận hành, nếu gọi bằng thuộc tính phù hợp (ví dụ
targetAddressSpace="local"), hệ thống vẫn có thể hoạt động như trước nếu người dùng đồng ý
Các phương án thay thế và thảo luận
- Cách tiếp cận PNA:
- PNA hiện tại yêu cầu CORS preflight, nhưng việc áp dụng và triển khai thực tế gặp nhiều khó khăn
- Ở một số đoạn, đã có đề xuất dùng prompt xin quyền và cho phép ngoại lệ mixed content
- Tồn tại các giới hạn thực tế như vấn đề DNS, thiết bị không hỗ trợ theo từng đặc tả
- Chặn mọi yêu cầu mạng cục bộ: đơn giản nhưng không thực tế vì có thể phá vỡ các trường hợp sử dụng và làm tăng chi phí né tránh
- Giữ nguyên hiện trạng: khi các hệ điều hành bắt đầu quản lý quyền mạng cục bộ theo từng ứng dụng, nhu cầu quản lý ở cấp trình duyệt càng được nhấn mạnh
- Các phương án thay thế cho mixed content:
- Đã có thảo luận về việc đánh giá mức độ an toàn của cách kết nối như “chỉ cho phép subresource của mạng cục bộ an toàn” cũng như gánh nặng triển khai
- Các phương án như khai báo không gian địa chỉ qua response header/meta tag, hoặc thêm thuộc tính vào phần tử HTML cũng được đưa ra bàn luận
Các điểm bổ sung
- Đang thảo luận khả năng thêm thuộc tính không gian địa chỉ cho HTML subresource (iframe, img v.v.)
- Phản ánh các kết quả nghiên cứu về vấn đề truyền quyền quá mức (transitivity) khi cấp quyền
- Có thể hạn chế truy cập mạng cục bộ hoặc hiển thị interstitial cảnh báo khi điều hướng main frame
- Cũng đang xem xét phương án coi mọi yêu cầu cross-origin hướng tới địa chỉ local/loopback là yêu cầu mạng cục bộ theo nghĩa rộng
- Nghiên cứu phương án cấp quyền chi tiết theo từng mạng, và liệu có cần xin lại sự đồng ý khi chuyển sang mạng khác (địa điểm khác) hay không
Các cân nhắc về bảo mật và quyền riêng tư
- Website được cấp quyền có thể làm dấy lên lo ngại về việc mở rộng khả năng dò quét và truy cập tới toàn bộ thiết bị trong mạng của người dùng
- Khi chấp nhận prompt, người dùng cần nhận thức rõ ý định; so với mô hình preflight, cách này cho phép kiểm soát trực tiếp hơn
- Nếu không có quyền từ trước thì sẽ không thể gửi bất kỳ yêu cầu mạng cục bộ nào, qua đó tăng cường bảo vệ quyền riêng tư
1 bình luận
Ý kiến Hacker News
Lúc mới thấy đề xuất này, tôi rất thích nó; bản thân ý tưởng rằng một website có thể tùy ý gửi yêu cầu HTTP tới IP nội bộ của người dùng — hay bất kỳ IP nào — đã là một rủi ro vô lý đến mức khó chấp nhận. Kể cả nếu vì vậy mà một số ứng dụng doanh nghiệp hay tích hợp bị hỏng thì tôi cũng không bận tâm; doanh nghiệp có thể bật lại tính năng này bằng công cụ quản trị, còn người dùng phổ thông thì tự cấu hình. Chỉ cần hiện một hộp thoại kiểu “Trang web này đang cố điều khiển thiết bị cục bộ - cho phép/từ chối” là đủ.
Có một góc nhìn dễ gây hiểu nhầm ở đây: các thiết bị trong mạng nội bộ vốn đã được bảo vệ khỏi website tùy ý nhờ CORS. Nó không hoàn hảo, nhưng là một cơ chế khá hiệu quả. Vấn đề là CORS chỉ dựa vào sự đồng ý của máy chủ đích; máy chủ phải cho phép website đó truy cập bằng các header cụ thể. Đề xuất lần này nhằm siết chặt hơn: ngay cả khi cả máy chủ lẫn website đều muốn giao tiếp, vẫn phải có sự chấp thuận rõ ràng từ người dùng. Trước đây người ta cho rằng chỉ cần máy chủ và website đồng thuận là đủ, nhưng những trường hợp gần đây như Facebook lén truy cập ứng dụng bên trong điện thoại đã phá vỡ nguyên tắc đó. Nói cách khác, hiện nay website và máy chủ mạng nội bộ có thể phối hợp theo cách đi ngược lại lợi ích của người dùng.
Về ý kiến “người dùng phổ thông chỉ cần tự chọn cho phép/từ chối trong popup”, MacOS hiện đã yêu cầu quyền kiểu này theo từng ứng dụng, nhưng phần lớn người dùng vẫn bấm “cho phép” mà không suy nghĩ nhiều. Làm theo từng website chưa chắc đã khiến mức cảnh giác tăng lên đáng kể.
Tôi không hiểu vì sao website lại cần truy cập mạng nội bộ. Nó chỉ tạo ra một mô hình đe dọa bảo mật hoàn toàn mới. Cũng không rõ liệu có trường hợp nào thực sự không có giải pháp tốt hơn hay không.
Tôi cũng mong Apple, Microsoft, Google làm điều tương tự với USB và Bluetooth. Gần như mọi ứng dụng cài gần đây đều đòi quyền truy cập Bluetooth, rất phiền. Tôi muốn manifest của ứng dụng phải chỉ rõ ID thiết bị Bluetooth mà nó được phép truy cập, và hệ điều hành giới hạn chỉ đúng các thiết bị đó. Ví dụ, ứng dụng Bose chỉ nên nhìn thấy thiết bị Bose. Tôi đã từng từ chối một ứng dụng vì không hiểu tại sao nó cần quyền đó. Sẽ tốt hơn nếu có cơ chế đăng ký ID thiết bị và hiện prompt cho người dùng, tương tự quyền camera hay GPS. Với Bose chẳng hạn, có thể đăng ký prefix
bose.xxxvà trong manifest chỉ xin quyền truy cậpbose.*, rồi OS chỉ cho phép đúng rule đó. Một hệ thống ID tương tự cũng nên áp dụng cho USB và thiết bị mạng nội bộ. Tôi muốn OS ngăn ứng dụng quét bừa mạng, USB và Bluetooth.Tôi hy vọng rồi sẽ có ngày ít nhất Apple cung cấp tùy chọn “cấp quyền giả” cho ứng dụng. Ví dụ khi app nói rằng nó bắt buộc phải có danh bạ của tôi, hệ thống có thể đưa cho nó một danh sách ngẫu nhiên nhưng trông như thật. GPS cũng có thể làm tương tự. Tôi cũng từng nghe rằng WhatsApp không cho đặt tên liên hệ nếu bạn không chia sẻ danh bạ.
Giống như tích hợp ứng dụng bên thứ ba trên Github, tôi thích mô hình quyền chi tiết kiểu “ABC muốn xem repo của bạn. Bạn muốn chia sẻ repo nào?”
Có ý kiến cho rằng Internet Explorer trước đây đã giải quyết vấn đề này bằng hệ thống zone. Xem thêm trong tài liệu MS.
Trớ trêu là Chrome trên Windows cũng từng dùng một phần mô hình bảo mật zone của IE, nhưng gần như không có tài liệu chính thức nào về chuyện đó.
Thật khó tin là ngày nay lại không có phương án thay thế hiện đại cho việc này. Truy cập mạng nội bộ cũng nên chỉ được cấp như một quyền đặc biệt, giống camera hay microphone.
Thật khó tin là trình duyệt web mặc định lại cho phép hành vi này. Nếu một website công khai có thể âm thầm truy cập toàn bộ hệ thống file của tôi thì đó sẽ là một lỗ hổng bảo mật kinh hoàng; vậy mà với dịch vụ mạng nội bộ, nó vẫn có thể dùng XHR bình thường, và bảo mật bị phó mặc hoàn toàn cho cấu hình máy chủ. Nếu là lập trình viên, khi bạn chạy web app nội bộ trên máy phát triển của mình để thử nghiệm với cấu hình bảo mật rất lỏng lẻo hoặc không có, thì
facebook.com,google.comvà các trang tương tự đều có thể truy cập trực tiếp. Ở nhà cũng vậy, nhiều người tin vào firewall của router rồi chạy các dịch vụ không xác thực; ai dám chắc tất cả họ đều cấu hình CORS đúng cách?Có kỳ vọng rằng đề xuất này sẽ giúp chặn cách Meta dùng SDK của họ để chia sẻ mã định danh giữa ứng dụng native và website bằng mẹo dựa trên localhost, đặc biệt trên Android. Xem thêm chi tiết.
Có ý kiến chỉ ra rằng việc cấp cho website quyền truy cập mạng nội bộ nói chung là một quyền quá thô và rộng không cần thiết. Phần lớn website thực sự cần quyền này chỉ cần truy cập một máy chủ cục bộ duy nhất. Cho phép toàn bộ mạng nội bộ là vi phạm nguyên tắc đặc quyền tối thiểu. Hơn nữa, đa số người dùng còn chẳng biết localhost hay trong mạng đang có dịch vụ gì chạy, nên cũng không nhận thức đúng mức độ rủi ro.
Vì phần lớn mọi người không biết localhost hay mạng của họ đang có gì chạy, nên dù trình duyệt hiện thông báo kiểu cho phép truy cập http://localhost:3146 hay http://localhost:8089, họ cũng khó mà đoán được nó có nghĩa gì. Một thông điệp trực quan hơn như “Trang web này đang cố truy cập tài nguyên mạng nội bộ” sẽ tốt hơn cho người dùng so với thuật ngữ kỹ thuật.
Nếu làm cho đúng, về cơ bản cần mức kiểm soát kiểu firewall ngay trong trình duyệt. Sẽ tốt nếu có API cho phép kiểm soát chi tiết như CIDR nào, cổng nào, v.v. Tôi cũng muốn tiện ích mở rộng trình duyệt có thể dùng firewall API kiểu này, hoặc giao diện mặc định phân biệt rõ từng phạm vi như một máy cụ thể (ví dụ router), LAN, VPN hay private network của Windows để xin quyền truy cập cho từng phạm vi riêng.
Từ sau khi plugin NPAPI biến mất, nhiều website công khai muốn tích hợp với phần mềm cục bộ gần như buộc phải chạy một HTTP server trên localhost. Nếu giờ ngay cả luồng sử dụng đó cũng bị làm phức tạp thêm, nó sẽ cực kỳ bất tiện. Các nhà phát triển trình duyệt đáng ra phải có công nghệ thay thế từ thời hậu NPAPI, nhưng giờ có lẽ đã quá muộn.
Phần lớn phần mềm thích cách đăng ký protocol handler ở cấp OS, ví dụ website chỉ cần đưa một link như
zoommtg://để trình duyệt chuyển cho Zoom hoặc ứng dụng tương ứng. Các trường hợp như Jupyter Notebook dùng hoàn toàn cục bộ mà không cần yêu cầu cross-origin thì không bị ảnh hưởng. Việc đăng nhập OAuth2 rồi chuyển hướng về URL localhost cũng chỉ là redirect đơn thuần nên có lẽ không có vấn đề gì.Nếu cách làm này — giao tiếp với ứng dụng cục bộ qua HTTP server — biến mất hoàn toàn thì có lẽ còn tốt hơn, vì nó từ lâu đã là nguồn gốc của không ít lỗ hổng bảo mật.
Những công nghệ như Mozilla Native messaging đã tồn tại. Dù cần cài extension, nhưng so với NPAPI thì đó vẫn là một cách hợp lý hơn.
Nếu phần mềm cục bộ hoạt động theo kiểu “pull” — tức ứng dụng tự định kỳ gửi yêu cầu ra ngoài — thì sẽ không cần phải dựng server nữa. Đi kèm với đó, website cũng không thể tùy tiện quét khắp mạng cục bộ của người khác, nên đây là một hướng tốt.
Trong JavaScript, nếu gửi
fetchhoặc yêu cầu POST mà không có tùy chọn CORS, thì CORS chỉ chặn việc đọc phản hồi; còn bản thân yêu cầu vẫn được trình duyệt gửi đi. Nếu ứng dụng cục bộ khiến máy chủ thêm CORS header thông qua proxy, thì bất kỳ website nào cũng có thể truy cập bằng JSfetch/XMLHttpRequest. Extension còn có thể sửa header để vượt qua CORS. Việc lách bằng cách đụng vào header quá dễ, trong khi CSP (Content Security Policy) trên thực tế rất khó hoặc gần như không thể vượt qua. Ứng dụng Facebook hiện cũng đang vận hành một máy chủ proxy CORS riêng theo mô hình này. Lại còn có WebSocket, nên ngay cả khi Chrome có cờ chặn truy cập localhost thì cũng chẳng có tác dụng. Chặn hoàn toàn localhost có khi còn hại nhiều hơn lợi, vì rất nhiều người đang dùng server cục bộ cho bookmark self-hosted, ghi chú, trình quản lý mật khẩu và các ứng dụng tương tự; chặn các trường hợp đó là không hợp lý.Có lo ngại đề xuất này sẽ gây vấn đề trong môi trường IPv6. Người ta thắc mắc liệu có cách nào xác định một địa chỉ IPv6 có “cục bộ” hay không. Nếu không, trong mạng chỉ dùng IPv6 thì đề xuất này sẽ thành vấn đề. Có người từng gặp chuyện này khi làm ứng dụng IoT: vì khó xác định địa chỉ IPv6 có phải cục bộ không, họ quyết định tạm thời chuyển mọi thứ về IPv4 local. Địa chỉ IPv6 link-local trên thực tế cũng không có nhiều ý nghĩa vì ứng dụng bình thường khó dùng. Việc coi domain
.locallà máy chủ cục bộ cũng rất khó xử vì mỗi OS diễn giải khác nhau, dẫn đến triển khai thiếu nhất quán. Ví dụ trên Raspberry Pi OS,some_addressđược phân giải bằng mDNS nhưngsomeaddress.localthì không; còn trên Ubuntu 24.04 thì chỉsomeaddress.localhoạt động,someaddressthì không, vàsomeaddress.local.cũng không chạy. Cuối cùng, chuyện không thể dùng chứng chỉ riêng cho địa chỉ mạng nội bộ cũng rất khó chịu; vấn đề “bắt buộc https cho địa chỉ local” cũng phải được giải quyết.IPv6 vẫn còn khái niệm “routable”, nên về mặt logic vẫn có thể định nghĩa site-local theo bảng định tuyến. Ngày xưa với IPv4, octet thứ hai biểu thị site, octet thứ ba là VLAN; IPv6 còn có nhiều tùy chọn hơn. Mọi thiết bị IPv6 đều có địa chỉ link-local, tức cục bộ trong VLAN.
.locallà khái niệm liên quan đến ánh xạ tên-địa chỉ như Apple hay DNS, chứ không trực tiếp là IP. Với chứng chỉ https trong mạng nội bộ, vẫn có thể dùng xác thực DNS-01 của Let's Encrypt, CNAME và các cách tương tự. Hơi phiền nhưng vẫn có phương án miễn phí, và các công cụ nhưacme.shcũng được khuyên dùng. Có lẽ cần phân biệt rõ hơn các khái niệm như IPv4, IPv6, DNS, mDNS, Bonjour; nhớ lại thời xưa đến cả packet capture còn phải trả phí mới thấy bây giờ vẫn dễ chịu hơn nhiều.Có người nhấn mạnh rằng từ phía endpoint không có cách nào xác định một địa chỉ IPv6 có phải là “local” hay không. Đó là vì nguyên lý của IPv6 là định tuyến toàn cục. Bài viết cũng cho thấy ngay cả Google khi thảo luận về nghĩa của “local” cũng đã lẫn lộn, giữa chừng chuyển sang định nghĩa “private”. Việc dựng một ranh giới bảo mật phi tiêu chuẩn dựa trên CIDR bằng cách mở rộng HTTP là một hướng tiếp cận rất kỳ quặc. Ứng dụng nên được thiết kế mô hình bảo mật trên giả định rằng nó là dịch vụ công khai.
.localtuy có trong đặc tả mDNS nhưng trên thực tế hầu như bị phớt lờ.Tôi thực sự mong cách này sớm thành hiện thực, đặc biệt là có thể cho phép từ domain HTTPS truy cập các website HTTP cục bộ. Có rất nhiều trường hợp sử dụng hay trong nhà thông minh, media/entertainment và các lĩnh vực tương tự.