2 điểm bởi GN⁺ 2024-01-07 | 1 bình luận | Chia sẻ qua WhatsApp
  • Chromium Money Tree Browser ánh xạ phần thưởng Chrome VRP vào lịch sử sửa đổi theo thư mục và tệp của kho lưu trữ Chromium, giúp xem lướt các khoản thưởng bảo mật đã “tích” ở đâu trong cây mã nguồn
  • Tiền thưởng được chia theo số tệp đã sửa; nếu một bản vá lỗi có phần thưởng $1.000 thay đổi 5 tệp, mỗi tệp được gán $200
  • Tổng hợp cấp cao nhất hiển thị root $9.873.277 / 10.944 mục, chromium $9.014.838 / 10.218 mục, chrome $2.568.260 / 2.574 mục
  • Nhiều khu vực như chrome/browser/ui/views, extensions, media, safe_browsing, enterprise, Android, net, device, gpu, storage, base, iOS, pdf được tách nhỏ đến cấp tệp; V8 cũng chiếm tỷ trọng lớn với $858.439 / 726 mục
  • Có lưu ý rằng dữ liệu và UI đang ở trạng thái “very very hacked together”, phạm vi chỉ đến đầu tháng 11/2023, nên phù hợp để xem như một bản đồ khám phá hơn là tài liệu kế toán chính xác

Cách phân bổ tiền thưởng lên cây mã nguồn

  • Đây là trình duyệt hiển thị việc liên kết tiền thưởng bug bounty của Chrome VRP với cây tệp/thư mục trong codebase Chromium
    • Nếu một bản sửa lỗi bảo mật thay đổi nhiều tệp, tiền thưởng được chia theo số tệp và gán cho từng tệp
    • Liên kết này thiên về mục đích xem lướt “đoạn mã nào thường thay đổi cùng với các khoản thưởng bảo mật”
  • Chỉ nhìn tổng hợp cấp cao nhất cũng thấy phân bố tiền thưởng đáng kể trên toàn bộ Chromium
    • root: $9.873.277 / 10.944 mục
    • chromium: $9.014.838 / 10.218 mục
    • chrome: $2.568.260 / 2.574 mục
    • chrome/browser: $2.250.643 / 1.920 mục

Phân bố đáng chú ý theo thư mục

  • Dưới chrome/browser/ui/views, phân bố tiền thưởng được chia rất chi tiết theo từng chức năng UI người dùng
    • views: $514.665 / 441 mục
    • tabs: $56.705 / 30 mục
    • eye_dropper: $47.000 / 7 mục
    • bookmarks: $46.697 / 31 mục
    • payments: $43.623 / 60 mục
    • media_router: $36.395 / 12 mục
    • tab_sharing: $30.591 / 9 mục
  • Các khu vực liên quan đến Chrome extensions cũng xuất hiện lặp lại dưới dạng những cụm lớn
    • extensions: $157.507 / 262 mục
    • extensions/api: $115.471 / 161 mục
    • api/tabs: $42.705 / 48 mục
    • api/debugger: $28.488 / 35 mục
    • api/downloads: $15.225 / 13 mục
    • Một khu vực extensions riêng cũng được tổng hợp ở mức $132.615 / 213 mục, bao gồm renderer, guest_view/web_view, API file_system, v.v.
  • V8 có vẻ là khu vực con đơn lẻ lớn nhất trong ghi chú được cung cấp
    • Toàn bộ V8: $858.439 / 726 mục
    • v8/src: $626.845 / 503 mục
    • v8/test: $209.030 / 195 mục
    • v8/src/compiler: $151.267 / 85 mục
    • v8/src/heap: $91.891 / 64 mục
    • v8/src/builtins: $68.133 / 30 mục
    • v8/test/mjsunit: $164.644 / 113 mục
  • Ở phía chrome/browser, các điểm tiếp xúc với người dùng như UI, tab, tự động điền, mật khẩu, DevTools, menu ngữ cảnh renderer khá nổi bật
    • chrome/browser/autofill: $114.656 / 40 mục
    • chrome/browser/tabs: $92.316 / 25 mục
    • passwords: $51.060 / 10 mục
    • chrome_content_browser_client.cc: $51.512 / 11 mục
    • devtools: $48.255 / 35 mục
    • renderer_context_menu: $47.842 / 16 mục
    • printing: $42.225 / 14 mục
    • payments: $41.252 / 10 mục
  • Các khu vực media, bảo mật, enterprise và nền tảng cũng được tổng hợp với số tiền lớn
    • media: $134.523 / 65 mục, khu vực chrome/browser/media riêng là $89.008 / 34 mục
    • safe_browsing: $80.161 / 31 mục
    • enterprise: $59.000 / 38 mục
    • ash: $130.389 / 161 mục, một đoạn ash riêng cũng tiếp nối với $56.867 / 55 mục
    • mojo: $112.725 / 26 mục
    • net: $97.558 / 175 mục
    • device: $61.770 / 32 mục
    • gpu: $51.155 / 30 mục
    • storage: $48.303 / 66 mục
    • base: $36.013 / 27 mục
  • Android và iOS cũng có phân bố tiền thưởng riêng trong mã nền tảng
    • Khu vực Java, tài nguyên và test của Android chrome/browser: $94.441 / 159 mục
    • Đường dẫn Java của Android: $62.571 / 91 mục
    • Android fullscreen: $18.707 / 11 mục, FullscreenHtmlApiHandler.java là $18.540 / 10 mục
    • iOS: $33.625 / 86 mục
    • ios/chrome/browser/web: $11.663 / 4 mục
    • ios/chrome/browser/ui: $9.884 / 24 mục

Tệp kiểm thử và các điểm cần lưu ý khi diễn giải

  • Dữ liệu kiểm thử và tệp kiểm thử hồi quy cũng được đưa vào phân bố tiền thưởng
    • test: $147.193 / 311 mục
    • test/data: $116.355 / 271 mục
    • test/data/extensions/api_test: $59.337 / 166 mục
    • V8 test/mjsunit/regress: $82.180 / 58 mục
    • V8 test/mjsunit/compiler: $46.233 / 28 mục
    • Vì khi một bản sửa lỗi bảo mật được ghi nhận cùng với thay đổi tệp kiểm thử, tiền thưởng cũng được phân bổ cho các tệp đó
  • Cách tính khá đơn giản, nên khó có thể đọc trực tiếp số tiền như mức độ rủi ro hay nguyên nhân lỗ hổng
    • Vì tiền thưởng được chia theo “số tệp đã sửa”, số tiền của một tệp không trực tiếp thể hiện mức độ rủi ro của chính tệp đó
    • Dữ liệu và UI ở trạng thái “very very hacked together”, kèm lưu ý không nên kỳ vọng UX tốt hay dữ liệu chính xác
    • Phạm vi dữ liệu đến đầu tháng 11/2023
  • Liên kết thảo luận liên quan cũng được cung cấp

1 bình luận

 
GN⁺ 2024-01-07
Các ý kiến trên Hacker News
  • Khá giống với thứ tôi đã muốn làm từ lâu. Tôi nghĩ sẽ hữu ích nếu tính xác suất một thay đổi cụ thể gây ra vấn đề dựa trên lịch sử các thay đổi phá vỡ từng xảy ra trong cùng một file hoặc cùng một khu vực trong file
    Về cơ bản là gắn điểm rủi ro cho mỗi thay đổi, hiển thị điểm đó cho từng PR để reviewer biết đoạn mã nào cần xem kỹ hơn, đồng thời nhấn mạnh các thay đổi rủi ro khi triển khai
    Phần khó là tiếp tục theo dõi cùng một vùng mã khi vị trí mã dịch lên/xuống do các đoạn chèn/xóa ở phía trên; các thuật toán chỉ dựa vào số dòng sẽ gặp vấn đề ở đây
    Dù vậy, như ví dụ này, chỉ làm ở cấp file thôi cũng có vẻ đã đủ hữu ích

    • Tôi đã làm việc này hơn 2 năm rồi. Phân tích tĩnh từng thay đổi, phân tích toàn bộ monorepo hằng ngày, rồi xử lý ở cấp symbol
      Với các thay đổi có rủi ro cao, chúng tôi chạy nhiều test hơn, nhưng không phải unit test mà là client test. Đôi khi có tới 100.000 client test để chọn, nên chúng tôi xếp hạng rồi chỉ chạy một tập con nhỏ
      Đây là một bài toán khó. Một quan sát thú vị là trong thay đổi gây lỗi có một hoặc hai symbol nguyên nhân, nhưng mức độ liên kết của những symbol đó lại rất giống các symbol không phải nguyên nhân trong cùng thay đổi
      Ngoài ra, call graph được sửa đổi theo kiểu bắc cầu sau thay đổi khá lớn, độ sâu 50 không hiếm. Ngoài mức độ chồng lắp của các symbol bị ảnh hưởng bắc cầu giữa thay đổi và test, rất khó rút ra nhiều tín hiệu hữu ích
      Cấp file và cấp build target thì quá thô; symbol AST đang hoạt động tốt
    • Không chỉ bản thân mã, cũng nên xem cả tác giả. Tôi từng làm việc với một người mà mỗi lần tạo PR là lại đưa vào ít nhất một bug
    • Tôi đang đọc một cuốn sách về chủ đề đó: https://pragprog.com/titles/atcrime/your-code-as-a-crime-sce...
    • Sẽ hay nếu kết hợp vị trí mã, nguồn gốc/tác giả và phân tích luồng dữ liệu đối với phần mã nhạy cảm lân cận. Đáng để đưa vào công cụ review của tôi
  • Rất tuyệt. Tuy nhiên có vẻ vẫn thiếu vài mục. Tôi khá chắc là trong third_party/ffmpeg cũng có ít nhất một mục
    Những bản sửa kiểu đó thường được đưa vào upstream trước nên có thể khó theo dõi

    • Đang dùng các bình luận do Git Watcher để lại trên bug Monorail
  • Khi nhìn qua cụm lớn dưới chrome/browser/ui, tôi lại nghĩ về việc có bao nhiêu lỗi use-after-free xuất hiện trong dữ liệu mà lợi ích hiệu năng của quản lý bộ nhớ thủ công không mấy quan trọng. Ví dụ [1] là vấn đề quanh vòng đời của hộp thoại “chọn file”
    Nhìn tổng thể, với loại mã như vậy có lẽ nên luôn dùng các con trỏ thông minh hơn nhưng chậm hơn để phòng vệ. Kiểu raw_ptr [3] trong [2] có vẻ nhằm giúp theo hướng đó, và có lẽ crash trong [2] thực ra là một trường hợp phòng vệ thành công
    Đáng tiếc là trong dự án không có cách phù hợp để chuyển phương ngữ theo nghĩa rộng hơn, kiểu như “phần này nhạy cảm hiệu năng và đã được review cẩn thận” so với “phần này không nhạy cảm hiệu năng, có nhiều trạng thái bất đồng bộ nên dễ sai”. Tôi từng nghĩ gần như có thể đáng để trộn thêm một ngôn ngữ riêng có GC cho nhóm thứ hai
    Nhân tiện, tôi từng làm việc với đoạn mã này từ lâu, và sẽ không ngạc nhiên nếu tôi đã tạo ra nhiều hơn 0 bug trong số các bug này
    [1] https://bugs.chromium.org/p/chromium/issues/detail?id=120103...
    [2] https://bugs.chromium.org/p/chromium/issues/detail?id=132323...
    [3] https://source.chromium.org/chromium/chromium/src/+/main:bas...

    • Điều đó giống như đang mô tả từ khóa unsafe của Rust
      Và loại mã này đúng nghĩa là một trong những động lực ban đầu khiến Rust ra đời. Ngôn ngữ này vốn được thiết kế với ý định triển khai trình duyệt ngay từ đầu
    • Một ví dụ gần như đúng là viết các phần quan trọng về hiệu năng bằng C hoặc Rust, còn phần còn lại để bằng Python. Tôi nghe nói binding Rust-Python đặc biệt tốt và giúp dễ đảm bảo tính đúng đắn hơn cả ở các phần quan trọng về hiệu năng
      Chiều ngược lại, gọi ngôn ngữ script từ một ngôn ngữ nhanh cũng khả thi. Ngày nay mọi người đều mê wasm, nhưng game máy tính đã dùng lua cho mục đích đó khoảng 20 năm rồi. Game có lẽ là nhóm phần mềm nhạy cảm hiệu năng lớn nhất
    • Vì cùng lý do, tôi từng muốn dùng Oilpan GC trong browser process, nhưng hồi đó phía browser phản đối mạnh việc dùng thư viện blink
      Phần lớn mã Chrome UI ít nhất cũng được viết bằng Web UI. Nếu là hiện nay, tôi nghĩ nên cân nhắc typescript cho nhiều công việc điều phối hơn bên trong trình duyệt. Đó là chiến lược đã được Electron kiểm chứng
      Tuy nhiên hiện tại xu hướng có vẻ thực sự nghiêng về MiraclePtr
    • raw_ptr thực ra là một wrapper smart pointer giúp giảm thiểu phần lớn khai thác use-after-free: https://security.googleblog.com/2022/09/use-after-freedom-mi...
  • Tôi đã chuyển nó sang trực quan hóa treemap[1]: https://vrp-treemap.surge.sh/
    Thư viện treemap này do evmar, một lão làng của Chrome cũng có mặt trong thread này, tạo ra

  • Trực quan hóa rất gọn gàng. Khi mở rộng các khu vực thì hơi tốn CPU một chút, nhưng tôi ước trong nội bộ đội Chrome cũng có thứ tương tự
    Có thể nói nó trông thực sự hữu ích để hiểu bề mặt tấn công

  • Ý tưởng thật sự hay và phần triển khai cũng tốt
    Dữ liệu thô có ở đâu không? Sunburst hoặc treemap cũng đáng thử

  • Vì thứ này có lẽ đã xuống tới cấp diff, sẽ thú vị nếu gán trọng số theo số dòng mã đã thay đổi. Ví dụ nếu file A đổi 10 dòng, file B đổi 1 dòng, thì vì phần lớn bug nằm ở file A, có phải file A sẽ được phân bổ 1/11 tiền thưởng không?
    Hoặc cũng có thể phân bổ theo số dòng đã thay đổi / tổng số dòng của file. Khi đó có thể thấy mỗi file nhiều bug đến mức nào kèm nhãn tiền

    • Làm vậy sẽ cho ra hiệu ứng mong muốn. Mã kiểu test có thể rất dài dòng, nhưng lỗ hổng thực tế đôi khi chỉ gói gọn trong vài ký tự
  • Sẽ hay nếu mỗi node cũng hiển thị mức thưởng trung bình theo file

  • Góp ý nhỏ thôi, nhưng có lẽ nên không đưa các file DEPS, AUTHORS, BUILD.gn vào

  • Một phiên bản chuẩn hóa số tiền theo số dòng mã thì sao?

    • Tôi tò mò vì sao bạn hỏi vậy. Theo tôi, trong phần mềm và bảo mật, số dòng mã không phải là một thước đo có nhiều ý nghĩa
    • Hoặc cũng có thể chuẩn hóa theo số từ đã được viết về bug. Nó có thể dùng làm chỉ báo đại diện cho độ phức tạp