Khi xây dựng ProxyOrb, chúng tôi liên tục đối mặt với một nghịch lý cơ bản trong từng quyết định thiết kế: một web proxy hoạt động bằng cách khiến trình duyệt tin rằng nội dung của bên thứ ba là nội dung cùng nguồn gốc. Về bản chất, đây là việc đánh lừa mô hình bảo mật cốt lõi của trình duyệt. Thế nhưng, trong suốt mười lăm năm qua, các trình duyệt hiện đại đã liên tục bổ sung thêm các lớp phòng thủ ngày càng tinh vi để chống lại chính kiểu nhầm lẫn nguồn gốc này.
Bài viết này phân tích sự căng thẳng đó từ những nguyên lý đầu tiên. Nếu bạn là security researcher, penetration tester, hay kỹ sư bảo mật trình duyệt và muốn hiểu cách proxy web thực sự tương tác với chính sách cùng nguồn gốc — không phải ở mức khái niệm, mà ở mức HTTP headers, Chromium source code và các đánh đổi kỹ thuật thực tế — thì bài này dành cho bạn.
Chúng ta sẽ đi qua nền tảng SOP, URL rewriting, CORS, CORB/CORP, COEP/COOP, Service Workers, iframes, và các hàm ý bảo mật cho cả người vận hành proxy lẫn người dùng.
1. Nền Tảng Chính Sách Cùng Nguồn Gốc (Same-Origin Policy)
Chính sách cùng nguồn gốc (SOP) được định nghĩa bởi bộ ba: scheme + host + port. Hai URL chỉ được coi là cùng nguồn gốc khi cả ba thành phần đều khớp chính xác. https://example.com:443 và http://example.com:80 là cross-origin mặc dù trỏ đến cùng một máy chủ.
Điều thường bị hiểu nhầm là SOP thực sự ngăn chặn điều gì so với điều nó cho phép. SOP không chặn:
- Load ảnh (
<img src>) từ origin khác - Load script (
<script src>) từ origin khác - Load stylesheet (
<link rel="stylesheet">) từ origin khác - Nhúng iframe từ origin khác (dù nội dung của document được nhúng bị cô lập)
- Gửi form submission (
<form action>) đến origin khác
Điều SOP thực sự ngăn là đọc phản hồi của các request cross-origin được thực hiện qua fetch() hoặc XMLHttpRequest. Request vẫn được gửi đi — vẫn có round-trip qua mạng — nhưng response body và headers bị giữ lại, không cho JavaScript ở một origin khác đọc.
Sự phân biệt này cực kỳ quan trọng với web proxy. Toàn bộ nhiệm vụ của proxy là gộp hai origin (proxy server và target server) thành một, loại bỏ ranh giới cross-origin. Khi tất cả tài nguyên đều có vẻ xuất phát từ https://proxyorb.com, các hạn chế của SOP về việc đọc phản hồi đơn giản là không áp dụng nữa.
"Khoảng trống hợp lệ" mà proxy web khai thác chính là URL rewriting: thay vì https://example.com/api/data, mọi request đều trở thành https://proxyorb.com/api/data?__pot=aHR0cHM6Ly9leGFtcGxlLmNvbQ==. Từ góc nhìn của trình duyệt, đây là request cùng nguồn gốc. SOP không bị bypass — nó bị vô hiệu hóa bởi việc thay đổi origin biểu kiến của toàn bộ nội dung.
2. Kiến Trúc URL Rewriting của ProxyOrb
Để hiểu các hàm ý bảo mật, bạn cần hiểu cơ chế mã hóa. ProxyOrb dùng URL parameter tên __pot (proxy origin token) chứa origin đích được encode Base64.
Tham Số __pot
Tham số __pot luôn encode origin (scheme + host, không có path) của đích, không phải toàn bộ URL. Điều này có nghĩa https://example.com/some/deep/path?foo=bar và https://example.com/other/page đều tạo ra cùng một giá trị __pot: aHR0cHM6Ly9leGFtcGxlLmNvbQ== (là Base64 encoding của https://example.com). Path và query string thực tế được giữ nguyên trong path và query string của URL proxy.
Khi người dùng điều hướng đến https://proxyorb.com/?__pot=aHR0cHM6Ly9leGFtcGxlLmNvbQ==, gateway decode và tái tạo URL gốc:
Gateway sau đó chuyển tiếp request đến target server thực sự, rewrite header Origin để upstream server nhìn thấy domain của chính nó thay vì domain proxy:
URL Rewriting Phía Client qua Service Worker
Gateway xử lý phần server. Phần client — rewrite URL trong HTML, JavaScript và CSS response để tất cả sub-request tiếp tục đi qua proxy — được xử lý bởi một Service Worker.
Phép biến đổi cốt lõi chuyển đổi bất kỳ URL nào gặp trong nội dung trang sang định dạng proxy:
Ví dụ, https://cdn.example.com/bundle.js được tham chiếu trong một trang đang được proxy sẽ trở thành https://proxyorb.com/bundle.js?__pot=aHR0cHM6Ly9jZG4uZXhhbXBsZS5jb20=.
Việc rewrite này là toàn diện: bao gồm fetch(), XMLHttpRequest, <script src>, <img src>, kết nối WebSocket và thẻ <link>. Khi mọi URL trong trang đều trỏ về proxy origin, trình duyệt không bao giờ thực hiện request cross-origin — mọi request đều là same-origin theo cấu trúc.
Khôi Phục __pot Khi Không Có Full Navigation
Một trường hợp đặc biệt tinh tế phát sinh với các request bắt nguồn từ bên trong trang đang được proxy nhưng thiếu tham số __pot — ví dụ, một fetch('/api/data') tương đối kích hoạt trước khi Service Worker kịp rewrite URL, hay request được phát ra bởi script được inject động đã bỏ qua URL rewriter.
Service Worker giải quyết token bị thiếu qua một chuỗi lookup theo thứ tự ưu tiên:
Gateway có một đường phục hồi song song: nếu request đến mà không có __pot nhưng mang header Referer trỏ đến URL cùng origin mà có chứa __pot, gateway trích xuất token từ referer và gắn vào request hiện tại. Điều này xử lý các tình huống điều hướng khi token bị JavaScript của trang tự bóc bỏ trước khi gateway nhận được request.
3. CORS: Hệ Thống Cấp Quyền Cross-Origin Tường Minh
CORS (Cross-Origin Resource Sharing) được thiết kế để cho phép các server opt in vào quyền truy cập cross-origin bằng cách gửi các response header cụ thể. Từ góc nhìn của proxy, CORS tạo ra hai vấn đề riêng biệt — đây là một trong những thách thức chính của bảo mật proxy web.
Vấn Đề 1: Chặn CORS Preflight
Khi JavaScript chạy trên một trang thực hiện request fetch() với non-simple headers (ví dụ Authorization, Content-Type: application/json), trình duyệt trước tiên gửi request OPTIONS preflight. Nếu response preflight của target server không bao gồm CORS headers cho phép, request thực sự bị chặn.
Trong kiến trúc của ProxyOrb, Service Worker chặn tất cả request OPTIONS và trả lời chúng một cách tổng hợp — trước khi chúng đến được gateway — trả về response mở khóa request thực sự:
Ở cấp gateway, mọi response được proxy đều nhận CORS headers tương đương:
Vấn Đề 2: Credentialed Requests
Sự kết hợp của Access-Control-Allow-Credentials: true và Access-Control-Allow-Origin không phải wildcard có ý nghĩa quan trọng. CORS yêu cầu giá trị origin tường minh (không phải *) bất cứ khi nào credentials được đưa vào. Service Worker phát ra tất cả outbound request với credentials: 'include', vì vậy gateway phải echo lại chính xác requesting origin thay vì wildcard.
Điều này có nghĩa là tất cả cookie được lưu dưới proxyorb.com — tích lũy từ mọi target site người dùng đã truy cập qua proxy — được gửi theo mọi request được proxy. Điều này là có chủ ý (nó duy trì session state cho các site đã đăng nhập), nhưng đây cũng là một vấn đề bảo mật quan trọng mà chúng ta thảo luận ở Phần 8.
Pattern Strip-and-Replace cho CORS Header
Một response được proxy có thể mang CORS header từ target server mà sai từ góc nhìn của trình duyệt (chúng tham chiếu target origin, không phải proxy origin). Service Worker bóc bỏ và thay thế chúng:
4. CORB và CORP: Các Phòng Thủ Chặt Chẽ Hơn của Chromium
CORS hoạt động dựa trên opt-in tường minh từ server. Chromium đã thêm hai cơ chế hoạt động mặc định, bất kể cấu hình CORS — đây là một phần quan trọng của bức tranh bảo mật trình duyệt.
Cross-Origin Read Blocking (CORB)
CORB được giới thiệu trong Chrome 67 (2018) như một phần của các biện pháp giảm thiểu Spectre. Nhận thức cốt lõi: ngay cả khi body của response cross-origin không bao giờ được JavaScript đọc, thực tế là nó đã được fetch và decode bởi renderer process có nghĩa là nó tồn tại trong không gian địa chỉ của process đó. Các tấn công kiểu Spectre sau đó có thể trích xuất nó qua side channel.
CORB ngăn một số response cross-origin nhất định không bao giờ vào renderer process. Cụ thể, khi thẻ <script> hay thẻ <img> fetch một response cross-origin và response đó có Content-Type là text/html, text/xml, hay application/json, Chromium kiểm tra body (dùng MIME-type sniffer được định nghĩa trong đặc tả CORB) và, nếu kiểu khớp, thay thế response bằng một response rỗng trước khi renderer nhìn thấy nó.
Đối với web proxy, CORB sẽ thảm khốc nếu các request thực sự là cross-origin. Một API endpoint trả về application/json được fetch từ thẻ <script> sẽ âm thầm trả về rỗng. Tuy nhiên, vì ProxyOrb rewrite tất cả URL thành same-origin, điều kiện cross-origin của CORB không bao giờ được kích hoạt — trình duyệt không bao giờ thấy response JSON cross-origin, vì từ góc nhìn của nó, tất cả response đều đến từ proxyorb.com.
Trường hợp duy nhất CORB có vai trò là trong giai đoạn chuyển đổi trước khi Service Worker được đăng ký đầy đủ và bắt đầu chặn request. Nếu bất kỳ request nào thoát khỏi URL rewriting trong khoảng thời gian đó, CORB có thể chặn nó. Race condition này là lý do ProxyOrb cũng duy trì một lớp interceptor trên main thread để vá XMLHttpRequest, fetch, và các DOM attribute setter một cách đồng bộ trước khi bất kỳ JavaScript nào của trang chạy — cung cấp fallback trong quá trình Service Worker khởi động.
Đáng chú ý là CORB đã một phần được thay thế bởi Opaque Response Blocking (ORB), mà Chromium đang trong quá trình áp dụng. ORB tinh chỉnh các quy tắc CORB để giảm false positive trong khi vẫn duy trì bảo vệ Spectre. Các hàm ý tương thích của proxy tương tự nhau.
Cross-Origin Resource Policy (CORP)
CORP, được định nghĩa trong Fetch spec, cho phép server tuyên bố rằng tài nguyên của họ chỉ nên được load bởi context cùng nguồn gốc hoặc cùng site:
Khi Chromium gặp header này trên một request sub-resource cross-origin, nó chặn response hoàn toàn. Điều này mạnh hơn CORB — nó áp dụng bất kể content type và không thể bypass bằng MIME sniffing.
Một lần nữa, vì URL rewriting của ProxyOrb đảm bảo tất cả request đều same-origin từ góc nhìn của trình duyệt, CORP header từ target server không kích hoạt chặn. Gateway cũng bóc bỏ các header này khỏi response một cách phòng thủ, xử lý các trường hợp ngoại lệ khi request trượt qua mà không có URL rewriting.
Vấn đề sâu hơn với CORP thực ra là trường hợp kiến trúc proxy giúp ích cho tương thích: nếu https://api.example.com và https://www.example.com đều đang được proxy, cả hai đều map đến cùng proxy origin, vì vậy một fetch từ cái này đến cái kia giờ là genuinely same-origin — các hạn chế CORP không còn áp dụng giữa chúng nữa.
5. COEP và COOP: Cách Ly Cross-Origin
Bắt đầu từ Chrome 92 (2021), việc truy cập vào SharedArrayBuffer — và theo đó là high-resolution timer được dùng cho một số performance API — bị hạn chế đối với các trang đã opt vào cách ly cross-origin. Việc opt-in này yêu cầu hai response header phối hợp với nhau — một chủ đề quan trọng khi nói về cách ly cross-origin trong bối cảnh proxy.
Cross-Origin-Embedder-Policy (COEP)
Khi một trang gửi header này, trình duyệt bắt buộc rằng mọi sub-resource được trang đó load phải:
- Là same-origin, HOẶC
- Gửi
Cross-Origin-Resource-Policy: cross-originmột cách tường minh, HOẶC - Có response CORS cho phép cho credentialed fetch
Vấn đề với web proxy: nếu một target site gửi COEP: require-corp trên main document của nó, và document đó được phục vụ qua proxy với header được giữ nguyên, trình duyệt giờ yêu cầu mọi sub-resource được load bởi trang đó cũng phải opt in. Bất kỳ tài nguyên nào không opt in — và hầu hết sẽ không — gây ra lỗi mạng.
Cross-Origin-Opener-Policy (COOP)
COOP kiểm soát liệu một trang có thể chia sẻ browsing context group với các trang cross-origin hay không. Khi đặt thành same-origin, một navigation cross-origin mở một browsing context group mới, phá vỡ các tham chiếu window.opener và kênh postMessage giữa trang và bất kỳ opener cross-origin nào.
Đối với proxy, COOP ít gây hại ngay lập tức hơn COEP, nhưng nó vẫn phá vỡ các site phụ thuộc vào luồng postMessage cross-origin (flow OAuth popup là ví dụ phổ biến nhất).
Thế Nan Giải của Người Vận Hành Proxy
Đây là đánh đổi khó khăn nhất chúng tôi phải đối mặt tại ProxyOrb:
Tùy chọn A: Bóc bỏ COEP và COOP khỏi response.
- Ưu điểm: Load sub-resource hoạt động bình thường; trang được proxy không áp dụng các hạn chế này.
- Nhược điểm: Chúng tôi đang xóa các security header mà target site đã đặt có chủ ý. Nếu site đang dùng cách ly cross-origin để bảo vệ dữ liệu nhạy cảm khỏi các tấn công kiểu Spectre, việc bóc bỏ các header này làm lộ lại rủi ro đó.
Tùy chọn B: Giữ nguyên COEP và COOP.
- Ưu điểm: Ý định bảo mật của target site được tôn trọng.
- Nhược điểm: Bất kỳ sub-resource nào không tường minh đặt
CORP: cross-originsẽ không load được, phá vỡ hầu hết các ứng dụng web phức tạp.
Chiến lược hiện tại của ProxyOrb là Tùy chọn A: gateway bóc bỏ Cross-Origin-Embedder-Policy và Cross-Origin-Opener-Policy khỏi response. Điều này tối đa hóa khả năng tương thích của site. Sự đánh đổi bảo mật được thực hiện một cách có ý thức: người dùng web proxy đang chấp nhận rằng họ đang chạy nội dung trong một môi trường khác với bối cảnh triển khai dự kiến của nó.
Mỗi cơ chế bảo mật trình duyệt mới đều theo một pattern: nó được giới thiệu như opt-in (các site có thể gửi header nếu muốn bảo vệ), sau đó dần dần trở thành mặc định cho các API mới, và cuối cùng được xem xét để thực thi bắt buộc. COEP đã đi theo con đường này: tùy chọn trong Chrome 83, bắt buộc cho SharedArrayBuffer trong Chrome 91. Các site nhúng nội dung bên thứ ba mà không có sự phối hợp thấy nội dung của họ bị hỏng. Web proxy làm phức tạp thêm vấn đề này vì chúng trung gian nội dung bên thứ ba theo định nghĩa.
Cộng đồng bảo mật trình duyệt nhận thức được vấn đề này. Đề xuất Document-Isolation-Policy mới nổi nhằm tách rời cô lập process khỏi các yêu cầu cách ly cross-origin, có khả năng cho phép nhận được các biện pháp giảm thiểu Spectre mà không yêu cầu tất cả sub-resource phải opt in. Khi điều đó được triển khai, khả năng tương thích của proxy với isolation header có thể được cải thiện.
6. Service Worker như Lớp Tin Cậy Phía Trình Duyệt
Service Worker không chỉ là một tối ưu hóa — nó có vai trò kiến trúc thiết yếu trong mô hình bảo mật của ProxyOrb. Đây là lý do tại sao.
Phạm Vi Đăng Ký Gắn với Origin
Một Service Worker được đăng ký với scope luôn nằm trong origin của trang đăng ký. Khi ProxyOrb đăng ký Service Worker, scope là https://proxyorb.com/, có nghĩa là nó chặn mọi fetch từ bất kỳ trang nào dưới origin đó.
Đây là lý do cơ bản tại sao URL rewriting sang same-origin hoạt động: khi SW đang kiểm soát một client, mọi network request từ client đó — bất kể JavaScript trong trang cố fetch URL nào — đều đi qua Service Worker trước.
Pipeline Chặn Request
Khi Service Worker chặn một request, nó chạy qua một số giai đoạn quyết định:
Chuyển Tiếp Header Minh Bạch
Một thách thức tinh tế: trình duyệt hạn chế JavaScript đặt một số "forbidden" request header nhất định (Host, Origin, Referer, v.v.) qua Fetch API. Service Worker khắc phục điều này bằng cách encode các header bị hạn chế vào một custom passthrough header duy nhất; gateway sau đó decode và áp dụng chúng trước khi chuyển tiếp đến target server:
Hàm Ý Bảo Mật của SW như Trung Gian Đáng Tin Cậy
Từ góc nhìn bảo mật, Service Worker chiếm một vị trí đặc quyền: nó có thể kiểm tra, sửa đổi và giả mạo bất kỳ request nào được thực hiện từ bất kỳ trang nào trong phạm vi của nó. Đối với việc sử dụng proxy hợp lệ, đây là toàn bộ mục đích. Đối với proxy độc hại, đây sẽ là bề mặt tấn công cực kỳ mạnh mẽ.
Đây là lý do tại sao độ tin cậy của chính script Service Worker là tối quan trọng. ProxyOrb phục vụ interceptor script từ origin của chính nó qua HTTPS với strict cache control. Nếu kẻ tấn công có thể inject một Service Worker đã bị sửa đổi, họ có thể chặn toàn bộ lưu lượng từ người dùng bị ảnh hưởng — không chỉ lưu lượng proxy, mà bất kỳ request nào từ các trang dưới origin đó.
7. iframes: Vấn Đề Frame-Ancestors
iframe đặt ra thách thức khác biệt so với sub-resource thông thường vì chúng liên quan đến một nested browsing context với navigation riêng, ranh giới SOP riêng và tập hạn chế nhúng riêng.
X-Frame-Options và frame-ancestors
Hai cơ chế ngăn trang được nhúng trong iframe:
Legacy: X-Frame-Options: DENY hoặc X-Frame-Options: SAMEORIGIN
Hiện đại: Content-Security-Policy: frame-ancestors 'none' hoặc frame-ancestors 'self'
Khi gateway proxy một trang đích gửi một trong hai, trang không thể được nhúng trong iframe dưới proxy origin. Vì X-Frame-Options: SAMEORIGIN tham chiếu target origin (example.com), và proxy phục vụ trang từ proxyorb.com, kiểm tra same-origin của trình duyệt thất bại.
Proxy phải bóc bỏ các header này khỏi response được proxy và thay thế CSP bằng phiên bản cho phép:
Chặn iframe và Inject Script
iframe được nhúng đặt ra vấn đề thứ hai: nội dung của chúng được load từ proxy, nhưng browsing context của iframe không tự động có Service Worker hay main-thread interceptor hoạt động. Nếu trang được proxy tạo ra một <iframe src="https://widget.example.com/...">, URL iframe đó cũng phải được rewrite sang định dạng proxy, và interceptor script của proxy phải được inject vào document của iframe.
Iframe interceptor hoạt động ở hai cấp độ:
Cấp 1 — Prototype patching (bắt việc tạo iframe theo chương trình):
Cấp 2 — MutationObserver fallback (bắt iframe được insert qua DOM):
Vấn Đề Thuộc Tính sandbox
Thuộc tính HTML sandbox hạn chế những gì iframe có thể làm: sandbox="allow-scripts allow-same-origin" kiểm soát thực thi script, gửi form, truy cập cross-origin, v.v. Để proxy injection hoạt động, iframe cần chạy script và có quyền truy cập vào proxy context của parent.
Token allow-same-origin đặc biệt tinh tế: khi có mặt cùng với allow-scripts, nó vô hiệu hóa cô lập origin của sandbox — iframe chạy với origin của trang nhúng. Khi vắng mặt, iframe nhận được một opaque origin duy nhất, điều này sẽ phá vỡ hoàn toàn việc inject script proxy.
Cách tiếp cận hiện tại của ProxyOrb với sandbox attribute là xóa hoàn toàn thuộc tính sandbox trước khi inject proxy script:
Đây là một đánh đổi bảo mật đáng kể: sandboxing đã được site gốc đặt có chủ ý để hạn chế khả năng của nội dung được nhúng. Việc xóa nó mở rộng những gì nội dung đó có thể làm. Đây là loại quyết định vô hình với người dùng cuối nhưng ảnh hưởng thực chất đến tư thế bảo mật của phiên proxy.
8. Hàm Ý Bảo Mật cho Người Vận Hành Proxy
Bối Cảnh Bề Mặt Tấn Công
Khi người dùng duyệt qua ProxyOrb, một số loại dữ liệu nhạy cảm chảy qua origin của proxy:
Session Cookie: Vì tất cả target site đều được proxy qua proxyorb.com, cookie được lưu dưới origin đó. Các phiên đã xác thực của người dùng với ngân hàng, email và mạng xã hội đều là cookie dưới một domain duy nhất. credentials: 'include' của Service Worker có nghĩa là các cookie này đi kèm mọi request được proxy.
Referer Header: Header Referer gửi đến upstream server tiết lộ trang người dùng đang xem. Proxy cẩn thận bóc bỏ domain của chính nó khỏi giá trị referer trước khi chuyển tiếp đến target server. Nếu request xuất phát từ https://proxyorb.com/some/path?__pot=..., header Referer gửi ra được tái tạo thành URL target gốc (https://example.com/some/path) — domain proxy không bao giờ bị rò rỉ đến upstream server.
Bối Cảnh Thực Thi JavaScript: Mọi file JavaScript được phục vụ qua proxy đều được sửa đổi (URL được rewrite) và thực thi trong origin của proxy. Một script độc hại từ evil.example.com được proxy qua ProxyOrb chạy trong origin proxyorb.com và có toàn quyền truy cập vào local storage, cookie và IndexedDB của origin đó — bao gồm dữ liệu từ mọi target site khác mà người dùng đã truy cập qua proxy.
Mô Hình Đe Dọa của Proxy Độc Hại
Vì mục đích giáo dục, đáng để nói rõ những gì một proxy độc hại có thể làm mà ProxyOrb cố tình không làm:
-
Thu Hoạch Thông Tin Đăng Nhập: Một proxy độc hại có thể ghi lại mọi request body (chứa mật khẩu và dữ liệu form) khi nó đi qua gateway.
-
Chiếm Quyền Session: Vì tất cả cookie của target site được lưu dưới proxy domain, một proxy operator độc hại có thể truy cập những cookie đó phía server qua gateway.
-
Inject Nội Dung: Proxy nhất thiết phải sửa đổi nội dung trang (để inject Service Worker và rewrite URL). Một proxy độc hại có thể inject JavaScript tùy ý — keylogger, crypto miner, script gian lận quảng cáo — vô hình với người dùng.
-
SSL Stripping: Nếu proxy downgrade kết nối HTTPS sang HTTP cho leg gateway-to-user, toàn bộ lưu lượng là plaintext.
ProxyOrb hoạt động qua HTTPS end-to-end và không ghi lại request body. Người vận hành của bất kỳ web proxy nào đều có những khả năng này, đó là lý do tại sao việc chọn proxy operator đáng tin cậy quan trọng như chọn VPN provider đáng tin cậy.
Mixed Content
Trình duyệt hiện đại thực thi mixed content blocking: một trang HTTPS không thể load sub-resource HTTP. ProxyOrb xử lý điều này bằng cách thực thi HTTPS trên tất cả outbound connection từ gateway, ngay cả khi target URL dùng HTTP. CSP override bao gồm upgrade-insecure-requests để hướng dẫn trình duyệt nâng cấp bất kỳ URL sub-resource HTTP nào lên HTTPS trước khi load.
Điều này thường là mong muốn, nhưng nó có thể phá vỡ các site cố tình phục vụ tài nguyên qua HTTP (CDN legacy, tài nguyên localhost, v.v.).
9. Cuộc Chạy Đua Vũ Trang Liên Tục: Kết Luận
Khi chúng tôi bắt đầu xây dựng ProxyOrb, những thách thức tương thích chính là CORS và X-Frame-Options. Kể từ đó, Chromium đã triển khai CORB, CORP, COEP, COOP và đang phát triển Document-Isolation-Policy. Hướng đi rõ ràng: trình duyệt ngày càng mạnh mẽ hơn trong việc thực thi ranh giới cross-origin, và mỗi cơ chế mới đòi hỏi hạ tầng proxy phải thích ứng.
Thách thức sắp tới đáng kể nhất có lẽ là việc triển khai đầy đủ COEP trên các ứng dụng web lớn. Các site dùng SharedArrayBuffer cho hiệu suất (trình biên tập video, IDE, công cụ cộng tác) ngày càng đặt COEP: require-corp. Khi ProxyOrb bóc bỏ header này để duy trì tương thích, người dùng cần các tính năng hiệu suất cao mà COEP cho phép sẽ thấy chúng bị suy giảm trong bối cảnh proxy.
Đối với security researcher, kiến trúc proxy tiết lộ điều gì đó quan trọng: chính sách cùng nguồn gốc không phải là tường lửa. Nó là mô hình tin cậy dựa trên cấu trúc URL. Web proxy khai thác thực tế rằng SOP không phân biệt bản chất giữa "hai tài nguyên này hợp lệ là same-origin" và "hai tài nguyên này đã được URL-rewrite để trông có vẻ same-origin." Toàn bộ stack bảo mật trình duyệt phía trên SOP — CORS, CORB, CORP, COEP, COOP — có thể được xem là nỗ lực thêm các phòng thủ mạnh mẽ hơn so với nhận dạng origin dựa trên URL.
Hiểu điều này là thiết yếu cho bất kỳ ai kiểm toán dịch vụ proxy, thiết kế chính sách bảo mật trình duyệt, hay đánh giá tư thế bảo mật thực tế của các ứng dụng có thể được truy cập qua proxy.
Câu Hỏi Thường Gặp
Web proxy có bypass chính sách cùng nguồn gốc không?
Không hoàn toàn. Web proxy hoạt động bằng URL rewriting: nó biến đổi tất cả URL cross-origin thành URL same-origin, làm cho các hạn chế cross-origin của SOP không còn liên quan thay vì bypass chúng. Từ góc nhìn của trình duyệt, tất cả nội dung đều có vẻ đến từ origin của proxy, vì vậy không có ranh giới cross-origin nào bị vượt qua. Điều này về mặt kiến trúc khác với bypass — SOP vẫn thực thi các quy tắc của nó; proxy chỉ đơn giản là kỹ thuật hóa nội dung để các quy tắc đó không bao giờ kích hoạt.
CORS ảnh hưởng đến máy chủ proxy web như thế nào?
CORS ảnh hưởng đến máy chủ proxy ở hai cấp độ. Thứ nhất, proxy phải chặn các request OPTIONS preflight và trả lời với CORS header cho phép, vì response preflight của target server thực sự (tham chiếu target origin) sẽ không thỏa mãn kiểm tra CORS của trình duyệt cho proxy origin. Thứ hai, proxy phải bóc bỏ CORS header khỏi response của target server và thay thế bằng header tham chiếu proxy origin. Cài đặt Access-Control-Allow-Credentials: true, kết hợp với credentials: 'include' trong Service Worker, có nghĩa là tất cả cookie từ origin proxy đi kèm mọi request được proxy.
CORB là gì và nó tác động đến dịch vụ proxy như thế nào?
Cross-Origin Read Blocking (CORB) là cơ chế phòng thủ của Chromium ngăn một số response cross-origin nhạy cảm nhất định (HTML, JSON, XML) vào renderer process khi được load như sub-resource cross-origin. Đối với web proxy được cấu hình đúng, CORB thường không được kích hoạt vì URL rewriting làm cho tất cả request là same-origin. Tuy nhiên, CORB có thể gây vấn đề trong giai đoạn trước khi Service Worker được đăng ký đầy đủ, khi một số request có thể thoát khỏi URL rewriting và được gửi như request cross-origin thực sự. CORB được giới thiệu như một biện pháp giảm thiểu Spectre và được định nghĩa trong đặc tả WHATWG Fetch.
Web proxy có thể truy cập cookie HTTP-only không?
Không. Cookie HttpOnly được target server đặt và không thể được đọc bởi JavaScript — bao gồm JavaScript chạy trong Service Worker. Tuy nhiên, gateway nhận những cookie này khi chuyển tiếp request thay mặt người dùng, vì trình duyệt gửi chúng trong request header. Flag HttpOnly ngăn việc đánh cắp phía client bằng JavaScript nhưng không ngăn chính proxy server nhìn thấy giá trị cookie trong quá trình transit. Điều này tương tự với cách HttpOnly bảo vệ chống XSS nhưng không chống lại việc chặn phía server.
Sử dụng web proxy có an toàn từ góc nhìn bảo mật trình duyệt không?
Phụ thuộc vào mô hình đe dọa. Từ góc nhìn của trình duyệt, tất cả nội dung được phục vụ qua web proxy chạy trong origin của proxy, có nghĩa là một lỗ hổng trong JavaScript của một site được proxy có thể tiềm năng truy cập dữ liệu từ phiên của site được proxy khác (vì chúng chia sẻ cùng cookie jar và storage của origin). Người vận hành proxy cũng là một bên đáng tin cậy với quyền truy cập vào tất cả lưu lượng trong quá trình transit. Để truy cập nội dung không nhạy cảm trong các môi trường bị hạn chế, rủi ro thường là chấp nhận được. Đối với phiên đã xác thực với các dịch vụ nhạy cảm (ngân hàng, chăm sóc sức khỏe, chính phủ), người dùng nên hiểu rằng proxy operator có khả năng kỹ thuật để quan sát lưu lượng đó, và chỉ nên dùng các dịch vụ proxy có chính sách no-log có thể kiểm toán và thực hành bảo mật vận hành mạnh mẽ.
Bài viết này phản ánh kiến trúc của ProxyOrb tính đến đầu năm 2026. Các cơ chế bảo mật trình duyệt phát triển nhanh chóng; người đọc được khuyến khích kiểm tra Tiêu Chuẩn WHATWG Fetch, đặc tả W3C Content Security Policy và tài liệu thiết kế bảo mật của Chromium để có thông tin cập nhật nhất.
