1 điểm bởi GN⁺ 4 giờ trước | 1 bình luận | Chia sẻ qua WhatsApp
  • Từ Chrome 148, Math.tanh của V8 gọi std::tanh của host thay vì fdlibm tích hợp, khiến cùng một đầu vào trả về bit cuối khác nhau giữa glibc trên Linux, libsystem_m trên macOS và UCRT trên Windows
  • Math.tanh(0.8) cho kết quả 0.6640367702678491 trên Linux, 0.664036770267849 trên macOS, và 0.6640367702678489 trên Windows, nên có thể phân biệt ba OS chỉ bằng một lần gọi; nếu kết quả khác với OS mà User-Agent khai báo thì việc giả mạo bị lộ
  • Đường rò rỉ khác nhau tùy engine: trong Math.* của V8 chỉ có tanh dùng thư viện toán học của host, nhưng toàn bộ các hàm lượng giác CSS của Blink và một số phép toán Web Audio cũng đi qua thư viện theo từng OS
  • Nếu tùy ý làm nhiễu giá trị, kết quả sẽ không khớp với bất kỳ OS thực nào và còn phá vỡ tính quyết định; vì vậy phải tái hiện ở mức bit các hệ số, bảng, range reduction và hành vi FMA của thư viện mục tiêu, hoặc ánh xạ trực tiếp mã UCRT gốc
  • Scrapfly đối chiếu 871.000 đầu vào với Mac thật và Chrome ở mỗi bản phát hành để kiểm chứng sự khớp bit của Math.tanh và 7 hàm lượng giác CSS; họ không chỉ khớp độ chính xác mà còn khớp cả khác biệt kiến trúc và thời gian thực thi ở mức trình duyệt thật

OS bị Math.tanh tiết lộ

  • Kết quả của Math.tanh(0.8) thay đổi theo thư viện toán học của host
    • glibc của Linux Chrome: 0.6640367702678491
    • libsystem_m của macOS Chrome: 0.664036770267849
    • UCRT của Windows Chrome: 0.6640367702678489
  • Apple và glibc nhìn chung lệch 1 ULP ở khoảng một phần tư toàn bộ đầu vào, còn Windows UCRT khác hai thư viện kia ở vài phần trăm đầu vào
    • ULP (unit in the last place) là khoảng cách giữa hai số dấu phẩy động liên tiếp có thể biểu diễn ở một độ lớn nhất định; 1 ULP là chênh lệch nhỏ nhất mà double có thể biểu diễn
  • Khi đo Chrome 150 thực tế trên Linux, macOS 26 chạy Apple Silicon và Windows 11 bằng DevTools Protocol, khả năng phân loại thay đổi theo đầu vào
    • tanh(0.5) giống nhau trên cả ba OS với giá trị 0.46211715726000974, nên không dùng để phát hiện được
    • tanh(0.7) chỉ Linux lệch 1 ULP
    • tanh(0.8) khác nhau trên cả ba OS, với toàn dải là 2 ULP
    • tanh(0.9) chỉ Windows lệch 1 ULP
  • Khoảng ba phần tư đầu vào cho cùng kết quả trên cả ba OS, nhưng chỉ cần một đầu vào phù hợp là có thể lấy được chữ ký theo OS
  • Nếu trình duyệt tự nhận là macOS nhưng trả về bit toán học của Linux, kết quả Math.tanh sẽ mâu thuẫn với User-Agent

Thay đổi xuất hiện trong Chrome 148

  • Cho đến Chrome 147, V8 tính Math.tanh bằng cách tích hợp một bản port của fdlibm, một triển khai toán học có tính di động, nên trả về cùng bit trên mọi OS
  • Commit V8 c1486295ae5 đã thay triển khai tích hợp bằng std::tanh của nền tảng
    • Thay đổi này lần đầu được đưa vào V8 14.8.57 và Chrome 148
    • Chrome 148, 149 và 150 phơi bày khác biệt của libm trên host, nhưng Chrome 147 trở xuống không rò rỉ OS qua đường này
  • IEEE 754 định nghĩa cách lưu trữ double, nhưng không yêu cầu các hàm siêu việt như sin, cos, tanh, exp phải luôn được làm tròn đúng
  • Thư viện toán học (libm) của mỗi OS đánh đổi giữa hiệu năng và sai số ULP, dùng các hệ số đa thức xấp xỉ minimax, bảng tra cứu và hằng số range reduction khác nhau
    • Linux dùng glibc
    • macOS dùng Apple libsystem_m
    • Windows dùng ucrtbase.dll của UCRT
  • Bộ phát hiện không cần phân tích bản thân phép toán, chỉ cần so sánh giá trị với bảng kết quả theo từng đầu vào của Chrome thực tế

Bốn cạm bẫy khiến việc tái hiện trở nên khó khăn

  • Chỉ một số hàm của V8 bị rò rỉ

    • V8 liên kết tĩnh hầu hết các triển khai toán học, nên cho cùng kết quả bất kể OS
    • Math.exp, Math.pow, Math.atan và các hàm tương tự dùng triển khai llvm-libc tích hợp
    • Math.sinMath.cos dùng routine dbl-64 tích hợp có nguồn gốc từ glibc
    • Sau Chrome 148, chỉ Math.tanh, vốn dùng std::tanh của nền tảng, rò rỉ OS trong số các hàm Math.*
    • Nếu giả mạo cả các hàm không rò rỉ như thể chúng thuộc OS mục tiêu thì sẽ lệch với cấu trúc gọi thực của V8; chính tính bất đối xứng rằng chỉ tanh khác cũng có thể bị kiểm tra
  • JavaScript và CSS dùng các đường khác nhau

    • sin(), cos(), atan2() của CSS không chia sẻ mã với Math.sin của JavaScript
    • Engine layout Blink trước hết thu gọn góc theo đơn vị độ, rồi gọi std::sin và các hàm tương tự của nền tảng trên giá trị đã thu gọn
    • Kết quả khác với việc tính trực tiếp đầu vào radian, và toàn bộ 7 hàm lượng giác CSS rò rỉ OS qua libm của host
    • Tái hiện ở mức bit phải bao gồm không chỉ hàm toán học cuối cùng, mà cả range reduction theo đơn vị độ và quá trình chuyển đổi radian–độ
  • Ngay trong macOS cũng có hai thư viện khác nhau

    • Trên Apple Silicon có cả libsystem_m vô hướng và các routine vector vvsin, vvtanh của Accelerate; hai triển khai này không giống nhau
    • Trên 1 triệu đầu vào, tùy hàm mà 10–89% kết quả khác nhau
    • cos(0) trong triển khai vô hướng chính xác là 1.0
    • Trong Accelerate, nó trả về 0.9999999999999999
    • Họ đo Chrome trên Mac thật bằng debugging protocol để phân biệt thư viện theo từng điểm gọi
    • Math.tanh, các hàm lượng giác CSS và các hàm siêu việt theo từng sample của bộ nén audio dùng libsystem_m vô hướng
    • Web Audio DSP, FFT, toán vector và bộ lọc biquad trên Mac dùng Accelerate
    • Các đường dẫn Chromium liên quan gồm fft_frame_mac.cc, vector_math_mac.h, biquad.ccBUILDFLAG(IS_MAC)
    • Nếu chọn thư viện Apple không khớp với điểm gọi, phần lớn đầu vào có thể lệch 1 ULP
  • Kiến trúc CPU cũng tham gia vào kết quả

    • ARM và x86 khác nhau về fused multiply-add (FMA) và lan truyền dấu NaN
    • Dù quy trình toán học đúng, nếu compiler chỉ hợp nhất phép nhân và phép cộng trên một kiến trúc thì bit kết quả sẽ khác

Đường rò rỉ theo engine và tính năng

  • Math.* của V8 trong JavaScript hầu như đều dùng triển khai tích hợp; điểm nối tới libm của host chỉ có Math.tanh
    • sin, cos, tan, asin, acos, atan, atan2, exp, log, log2, log10, pow dùng triển khai tích hợp của V8
    • sqrt, abs và bốn phép toán số học là phép toán phần cứng
  • Các hàm toán học trong CSS calc() được Blink gọi trực tiếp qua thư viện nền tảng
    • sin, cos, tan, asin, acos, atan, atan2, exp, log, log2, log10, pow dùng libm của host
    • CSS không có đường tương ứng cho tanh
  • Web Audio dùng pha trộn nhiều triển khai tùy điểm gọi
    • Oscillator FFT, cộng/nhân/scale vector và FFT trên Mac dùng vDSP của Accelerate
    • Các hàm siêu việt theo từng sample như sin, exp, log10f, powf của DynamicsCompressor dùng libsystem_m vô hướng
    • Một audio graph có thể đi qua ba thư viện: toán tích hợp của V8, thư viện vô hướng và Accelerate
  • WebAssembly không có lệnh hàm siêu việt
    • Kết quả của sin và các hàm tương tự được quyết định bởi libm được đóng gói trong module
    • Số học như f64.sqrt, f64.mul chạy trên phần cứng nên giống nhau giữa các OS
    • Trục fingerprint còn lại là chuẩn hóa NaN giữa ARM và x86, cùng một số khác biệt làm tròn SIMD
  • Tín hiệu phát hiện tập trung vào Math.tanh, toàn bộ các hàm lượng giác CSS và Web Audio
    • Accelerate FFT của Web Audio tiết lộ kiến trúc CPU
    • libsystem_m vô hướng của bộ nén tiết lộ OS

Tái hiện chính xác thay vì làm nhiễu giá trị

  • Vì sao nhiễu thất bại

    • Nếu thêm nhiễu vào kết quả, giá trị có thể không khớp với bất kỳ OS thực nào trong bảng chuẩn
    • Nếu giá trị ngẫu nhiên thay đổi theo từng lần gọi, tính quyết định bị phá vỡ, và chính hiện tượng này trở thành một tín hiệu phát hiện riêng
    • Mục tiêu không phải là giá trị gần giống, mà là kết quả giống đến từng bit với giá trị OS được khai báo trả về
  • Khôi phục mọi yếu tố của thuật toán mục tiêu

    • Từ libm mục tiêu, khôi phục các hệ số xấp xỉ minimax, bảng số mũ và hằng số range reduction rồi chuyển sang mã C có tính di động
    • Cần khớp cả những đầu vào mà thư viện mục tiêu làm tròn sai hướng
    • Việc tái hiện sin của Apple dùng mẫu bit chính xác của các hệ số trích từ libsystem_m và các lệnh gọi fma() tường minh
    • Nếu chuyển hệ số sang dạng thập phân, chúng có thể bị làm tròn lại trong quá trình chép, nên được giữ ở dạng dấu phẩy động thập lục phân
    • Mỗi phép nhân-cộng mà Apple hợp nhất cũng được hợp nhất tường minh trong mã
  • Cố định FMA một cách quyết định

    • Biên dịch với -ffp-contract=off để compiler không tự ý thêm hoặc loại bỏ FMA
    • Chỉ các fma() được ghi tường minh trong mã mới chạy ở đúng vị trí như Apple, nên dù mô phỏng ARM trên server x86 vẫn lấy được cùng bit
    • FMA phần cứng và FMA phần mềm được làm tròn đúng trả về cùng bit

Dùng mã nguồn gốc của Windows UCRT

  • Windows UCRT dùng cùng ISA x86-64 với server Linux và độc lập vị trí, nên có thể ánh xạ ucrtbase.dll thực vào bộ nhớ runtime và gọi trực tiếp các export hàm toán học
  • Vì chạy mã gốc, có thể lấy được bit UCRT thực tế mà không cần reverse engineering thuật toán toán học riêng
  • Cần xử lý khác biệt giữa System V ABI của Linux và Windows x64 ABI
    • Trong Windows x64, callee dùng shadow space 32 byte phía trên địa chỉ trả về
    • Tập thanh ghi callee-preserved cũng khác System V
    • Nếu không khai báo con trỏ hàm là ms_abi, thao tác ghi vào shadow-space sẽ làm hỏng stack frame của clang và lời gọi gián tiếp có thể nhảy tới địa chỉ sai
  • Mã DLL đã ánh xạ không phải là mục tiêu gọi gián tiếp đã đăng ký trong CFI
    • -fsanitize=cfi-icall ở production có thể gây trap #UDSIGILL ở mỗi lần gọi
    • Wrapper gọi con trỏ hàm cần clang::no_sanitize("cfi-icall")
  • Hàm toán học UCRT đọc cờ dispatch CPU bằng mov eax, [rip+disp32] ở phần đầu để chọn đường vô hướng hoặc FMA/AVX2
    • Trong DLL mới ánh xạ, cờ bằng 0 nên chọn đường vô hướng chậm
    • Kết quả của đường này khác bit kết quả trên hệ Windows hiện đại
    • Cần tìm địa chỉ cờ trong prologue của tanh và ép sang đường FMA trước lần gọi đầu tiên để khớp từng bit với Windows thực

Vị trí patch và ràng buộc hiệu năng

  • Hook vào điểm nghẽn duy nhất nơi engine gọi libm, rồi chọn đường theo OS mà trình duyệt khai báo
    • Nếu khai báo Linux thì giữ glibc
    • Nếu khai báo macOS thì dùng triển khai tái hiện Apple
  • Dù kết quả chính xác, nếu thời gian thực thi khác trình duyệt thật thì vẫn có thể bị phát hiện
  • Bản build đầu tiên có baseline x86 mặc định cũ hơn FMA phần cứng, nên hạ tất cả fma() thành lời gọi phần mềm và chậm hơn native 2,5–6 lần
  • Khi so sánh tỷ lệ thời gian của vòng lặp Math.tanhMath.sin, có thể lộ ra mẫu hiệu năng không tồn tại trong trình duyệt thật
  • Sau khi bật FMA phần cứng, mỗi phép hợp nhất trở thành một lệnh duy nhất, nhanh hơn khoảng 6 lần; kết quả bit vẫn giống hệt dù còn nhanh hơn glibc

Kiểm chứng bằng 871.000 đầu vào

  • Harness kiểm chứng chạy 871.000 đầu vào trên mọi nhánh và miền xác định ở mỗi bản phát hành
    • Lưới đầu vào dày
    • Biên khoảng
    • Subnormal
    • Số 0 có dấu
    • Vô cực
    • NaN
  • Dùng hai loại môi trường thực làm giá trị chuẩn
    • Mac thật tính riêng kết quả vô hướng và Accelerate trên mọi đầu vào để xác định các điểm hai triển khai phân kỳ
    • Chrome trên Mac thật được điều khiển bằng debugging protocol để thu kết quả đầy đủ độ chính xác của Math.tanh và mọi hàm lượng giác CSS
  • Math.tanh và các hàm CSS sin, cos, tan, asin, acos, atan, atan2 khớp từng bit với Chrome trên Mac thật
  • Họ cũng kiểm chứng triển khai tái hiện hoạt động giống hệt mã máy thực trong binary phát hành
  • Cần khớp cả xử lý hậu kỳ của trình duyệt ở biên miền xác định
    • Trên Mac thật, CSS asin(2) nằm ngoài miền xác định nên thành NaN, rồi CSS giới hạn NaN về 0, nên giá trị cuối là 0
    • Một triển khai tái hiện đơn giản có thể trả sai thành 90 độ

Vì sao toán học quan trọng trong giả mạo trình duyệt

  • Kết quả toán học có tính quyết định và rẻ để kiểm tra, nhưng muốn giả mạo chính xác phải hiểu nội bộ libm của vendor và đường gọi theo từng engine
  • Để khớp trình duyệt thật, cần nắm được V8, Blink và Web Audio chọn thư viện toán học nào tại từng điểm gọi, đồng thời khớp cả bit cuối, hành vi theo kiến trúc và thời gian thực thi
  • Scrapium của Scrapfly được cấu hình để khi được yêu cầu hiển thị như macOS, nó khớp cả bit làm tròn của cosine với lưu lượng macOS thực tế

1 bình luận

 
Các ý kiến trên Hacker News
  • Cách giải thích rằng chỉ cần gọi tanh một lần với đầu vào phù hợp thì kết quả sẽ trở thành chữ ký theo từng hệ điều hành đã bỏ sót khả năng nhận diện khoảng phiên bản trình duyệt
    Hầu hết mọi người không giả mạo hệ điều hành trong User-Agent, và fingerprinting quan tâm đến tổ hợp các đặc tính gần như độc nhất hơn là bản thân hệ điều hành. Phát hiện này thú vị, nhưng bài viết có vẻ được viết bằng LLM quá nhiều nên làm giảm độ tin cậy

    • Công ty tạo ra bài viết này thực ra đang cố ngụy trang bot trên VM Linux thành thiết bị vật lý Windows hoặc macOS
      Làm vậy để dễ vượt qua phát hiện bot hơn và bán dữ liệu thu thập từ các website khác cho khách hàng
    • Chỉ riêng phương pháp này hiện chỉ có thể xác định là Chromium 148 trở lên, nhưng nếu kiểm tra các tính năng V8·Blink được thêm vào ở từng phiên bản bằng JavaScript hoặc CSS thì có thể xác định chắc chắn phiên bản chính từ khoảng bản 120 trở đi
      Việc bài viết được viết bằng LLM đã được công khai trong bài và trên blog, không hề che giấu hay giả vờ là người viết. Vì thiếu thời gian nên nếu không làm vậy thì có lẽ bài đã không được đăng, và tôi sẵn sàng chịu trách nhiệm cho lựa chọn này
    • Có thể nhận diện khoảng phiên bản, nhưng những cách như vậy đã nhiều không đếm xuể
      Trình duyệt liên tục thêm tính năng và sửa lỗi, mà phần lớn trong số đó có thể phát hiện bằng JavaScript
    • Nếu nội dung là đúng thì ai viết không quan trọng, và luận điểm cốt lõi của LLM cũng hợp lý
  • Phân tích và công khai mọi kỹ thuật fingerprinting bằng AI, rồi sau tranh cãi thúc đẩy trình duyệt chặn chúng, là một chiến lược khôn ngoan vì nó giúp mảng scraping của chính họ kiếm được nhiều tiền hơn
    Nếu không có những công ty như vậy, browser fingerprinting đã không tràn lan như hiện nay và Internet cũng đã tốt hơn. Tôi thà đọc bài từ phía đối lập có lợi ích rõ ràng như fingerprint.js còn hơn

    • Dù có scraper hay không, muốn theo dõi con người thì cần fingerprinting, và cuối cùng nó vẫn sẽ được dùng, nên khó đồng ý với nhận định đó
  • Lại có thêm một lý do để thúc đẩy các hàm siêu việt được làm tròn chính xác
    Gần đây tôi mới biết vấn đề này về cơ bản đã được giải quyết. Xem bài keynote thứ hai tại https://arith2026.org/program.html

    • Các hàm libm được làm tròn chính xác là rất tuyệt, nhưng không được có hiệu năng trường hợp xấu nhất kinh khủng như pow của glibc trước đây
      Có thể thử cải thiện hiệu năng trường hợp xấu nhất bằng cách tự SLP-vector hóa đường dự phòng độ chính xác cao dùng khi gần biên làm tròn, nhưng hiện đã đủ tốt cho hầu hết mục đích sử dụng. Việc các engine JavaScript vẫn không dùng fdlibm mà đặc tả ECMAScript khuyến nghị là khá bất ngờ, và nếu Math.tanh là đường nóng gây nghẽn của JavaScript thì đó là đoạn mã khá đặc biệt
    • Khó hiểu vì sao độ chính xác cố định và phép toán số nguyên không được dùng rộng rãi hơn
      Trong kỹ thuật, fixed-point thường được dùng vì chạy được trên phần cứng đơn giản hơn nhiều và dễ mô hình hóa sai số bằng toán học. Số thực dấu phẩy động IEEE 754 cũng đáng ngờ về mặt lý thuyết, và trong vấn đề mất độ chính xác, số nguyên nhỏ hơn phần trị — tức số nguyên dưới 24 bit — đôi khi còn tốt hơn số thực 32 bit
    • Tôi ngạc nhiên là họ đăng ký tên miền mới mỗi năm rồi gia hạn vĩnh viễn theo cách đó
  • Mong kỹ thuật này được thêm vào https://coveryourtracks.eff.org/ để tôi có thể kiểm tra kết quả các hàm toán học của mình độc nhất đến mức nào trong một tập người dùng lớn hơn

    • Công ty này tuyên bố đã vá hơn 4.000 tín hiệu trong hơn 550 file C++ của Chromium
      Không rõ có đúng không, nhưng tôi nghĩ coveryourtracks.eff.org chỉ dùng khoảng 25 tín hiệu
  • Bài viết có dấu hiệu được Claude viết

    • Điều nực cười là liên kết tóm tắt bằng AI ở đầu bài không chỉ yêu cầu nhà cung cấp AI đã chọn tóm tắt bài viết, mà còn yêu cầu quảng cáo sản phẩm
      Khi bấm liên kết Claude, prompt được gửi là summarize+this+article+and+explain+how+scrapfly+helps+me+scrape+any+website+at+scale+and+bypass+anti-bot+systems+for+my+use+case:+[https://scrapfly.dev/posts/browser-math-os-fingerprint/](<https://scrapfly.dev/posts/browser-math-os-fingerprint/>;)
    • Phát hiện trong tiêu đề thì thú vị, nhưng phần còn lại về cơ bản là nội dung do Claude viết
    • Vài tháng gần đây tôi ít hoạt động trên HN, nhưng có vẻ cộng đồng đang ám ảnh đến mức hoang tưởng với việc gắn nhãn nội dung là kém chất lượng và phát hiện sử dụng LLM
  • Tor Browser và Mullvad Browser cuối cùng cũng từ bỏ việc che giấu hệ điều hành, nhưng có lẽ họ không nên làm vậy
    Có vẻ có quá nhiều đường fingerprinting như thế

    • Tôi nghĩ đó là quyết định đúng, vì còn không rõ có thể che giấu hệ điều hành hay không
      Có quá nhiều khác biệt hành vi theo hệ điều hành cả bên trong lẫn bên ngoài trình duyệt, nên rất khó xử lý hết. Dù chặn trích xuất canvas hoặc thêm nhiễu, khác biệt render vẫn có thể bị lộ; các nhà phát triển Tor Browser cũng xác nhận rằng họ thậm chí không thể che giấu khác biệt giữa X11 và Wayland, chứ chưa nói đến các hệ điều hành hoàn toàn khác nhau. https://forum.torproject.org/t/linux-is-it-alright-to-run-th...
    • Tor Browser thậm chí không sửa navigator.platform, nên rất dễ nhận ra môi trường không phải Windows
  • Chỉ cần chèn đoạn mã sau bằng plugin inject JavaScript ưa thích của bạn: let oldTanh = Math.tanh; Math.tanh = x => oldTanh(x) + Math.random()/10000000;

    • Tôi thích cách ngắn gọn hơn: Math.tanh = Math.random;
    • Bài viết đã đề cập rồi, chỉ cần tìm “No noise
    • Nhiều hãng chống bot sẽ phát hiện việc thay thế này và dùng nó làm tín hiệu fingerprinting
    • Giờ thay vì giá trị bình thường, bạn lại lộ ra là người dùng đang che giấu fingerprint, có thể còn dễ bị nhận diện hơn
  • glibc mới nhất dùng tanh được làm tròn chính xác của CORE-MATH, nên trả về kết quả khác với các giá trị được trích trong bài
    Hiện vẫn chưa rõ liệu các hàm siêu việt khác có thể triển khai làm tròn chính xác với hiệu năng hợp lý hay không, nên mỗi hàm vẫn để lại fingerprint riêng

  • Chrome có mã thực thi lên tới hàng trăm MB nên tôi cứ tưởng khoảng một nửa thư viện user-space đã được liên kết tĩnh
    Ngoài ra, tôi từng nghĩ tanh không phải là lời gọi hàm mà là phép toán tích hợp sẵn do JavaScript JIT phát ra thành lệnh CPU; vì vậy việc phải rẽ nhánh qua hàm dlsym() cho phép toán học là điều kỳ lạ. Bản thân lệnh CPU cũng có thể bị fingerprint

    • x87 FPU triển khai các hàm siêu việt bằng microcode, nhưng phần lớn tập lệnh không cung cấp chúng
      Microcode không được hưởng các lợi thế như dự đoán rẽ nhánh, nên thực tế chậm hơn triển khai bằng phần mềm
    • Theo tôi nhớ, Chrome là trình duyệt duy nhất bảo toàn các bit không dùng của giá trị NaN ở chế độ không JIT, và khi mã được JIT thì các bit đó bị đổi thành 0
  • Tôi nghi ngờ liệu có thể thắng cuộc chiến này không
    Nếu chạy đủ nhiều hàm, có lẽ có thể kết hợp tỷ lệ thời gian chạy và kết quả làm tròn để suy đoán không chỉ hệ điều hành và đúng mẫu máy, mà cả những tác vụ khác đang chạy trên cùng thiết bị. Có vẻ chỉ có thể làm nó khó hơn một chút, chứ không thể chặn hoàn toàn
    Cuối cùng xã hội và pháp luật phải bắt kịp. Giống như khóa cửa không thể chặn hoàn toàn xâm nhập nhưng được bổ sung bằng sự lên án xã hội và xử phạt hình sự, cần hình sự hóa việc theo dõi cá nhân theo cách này và tẩy chay về mặt xã hội các công ty cũng như người lao động hưởng lợi từ nó

    • Trong không gian mạng, những kẻ làm việc bất hợp pháp hoặc đáng lẽ phải bị xem là bất hợp pháp thường ở các khu vực tài phán không thể thực thi
      Ở những nơi như Nga, Myanmar, Triều Tiên, pháp quyền không vận hành, và chính quyền địa phương đôi khi còn chủ động bảo vệ tội phạm lừa đảo người nước ngoài, nên phép ví von với khóa cửa không còn đúng