1 điểm bởi GN⁺ 2025-08-20 | 1 bình luận | Chia sẻ qua WhatsApp
  • Nhóm nghiên cứu bảo mật đã thành công thực thi mã từ xa (RCE) trên máy chủ production của CodeRabbitlàm rò rỉ token API cùng thông tin bí mật
  • Thông qua một PR sử dụng Rubocop, họ đã đánh cắp biến môi trường, đồng thời có thể truy cập PostgreSQL và đọc/ghi 1 triệu repository
  • Việc rò rỉ private key của GitHub App khiến kẻ tấn công có thể tiêm mã độc vào kho lưu trữ quy mô lớn, bao gồm cả repo public và private, sửa mã nguồn và gây ra thiệt hại thực tế
  • Phía CodeRabbit đã phản ứng ngay trong vòng vài giờ sau khi nhận báo cáo lỗ hổng và tăng cường các biện pháp bảo mật
  • Khi chạy công cụ bên ngoài, cần nhấn mạnh sự cần thiết của ngăn chặn sự cố bảo mật bằng cách cô lập sandbox, áp dụng đặc quyền tối thiểu và chặn mạng

Giới thiệu

  • Tháng 1 năm 2025, nhóm nghiên cứu Kudelski Security đã công bố một lỗ hổng bảo mật nghiêm trọng trong CodeRabbit
  • Trên CodeRabbit, một công cụ tự động hóa review PR được sử dụng rộng rãi, đã xác nhận các vấn đề nghiêm trọng gồm remote code execution (RCE), rò rỉ biến môi trường và thông tin nhạy cảm, cùng khả năng giành quyền Read/Write với hơn 1 triệu repository
  • Bài viết này phân tích chi tiết nội dung lỗ hổng đã được công bố tại Black Hat USA và có giá trị tham khảo cao như một trường hợp thực tế về lỗ hổng trong công cụ review dạng code và các hệ thống tích hợp liên quan
  • Lỗ hổng được báo cáo đã được vá nhanh chóng ngay sau khi thông báo

Tổng quan về CodeRabbit

  • CodeRabbit là ứng dụng review code dựa trên AI được cài đặt nhiều nhất trên GitHub/GitLab Marketplace
  • Ứng dụng này đã review 1 triệu repository và 5 triệu pull request trên hai nền tảng lớn
  • Mỗi khi người dùng tạo hoặc cập nhật PR, engine AI sẽ phân tích mã và tự động tạo comment cùng đề xuất
  • Các tính năng như tóm tắt code, phát hiện lỗ hổng bảo mật, gợi ý cải tiến và tạo sơ đồ mang lại hiệu quả lớn trong việc nâng cao năng suất phát triển

Cách sử dụng và cấu trúc quyền của CodeRabbit

  • Gói Pro cung cấp tính năng tích hợp linter và công cụ SAST (phân tích tĩnh)
  • Khi xác thực tài khoản GitHub và cài đặt app, người dùng sẽ cấp quyền đọc/ghi cho các repository đã chọn
  • Nếu cơ chế quản lý quyền này bị lạm dụng, nó có thể tạo ra tác động trực tiếp đến mã nguồn của mọi repo đã cài đặt

Thực thi công cụ bên ngoài và phát hiện khai thác

  • Khi phát hiện thay đổi mã trong PR, CodeRabbit sẽ tự động chạy nhiều công cụ phân tích tĩnh bên ngoài (ví dụ: Rubocop)
  • Rubocop được thiết kế để có thể dùng file cấu hình .rubocop.yml nhằm nạp file mở rộng Ruby bên ngoài (ext.rb v.v.)
    • Kẻ tấn công chèn mã độc vào .rubocop.ymlext.rb, sau đó gửi PR để khiến CodeRabbit thực thi mã đó trên máy chủ từ xa
    Quảng cáo
  • Mã được thực thi bằng kỹ thuật này đã gửi toàn bộ biến môi trường của máy chủ về máy chủ của kẻ tấn công

Phân tích nội dung rò rỉ biến môi trường

  • Các biến môi trường bị rò rỉ bao gồm API key, token và mật khẩu của nhiều dịch vụ khác nhau như:
    • API key của Anthropic/OpenAI, encryption salt/password, private key của GitHub App, thông tin kết nối PostgreSQL, v.v.
  • Thông qua RCE, có thể gây ra thiệt hại thứ cấp lớn với mức độ ảnh hưởng cao như truy cập cơ sở dữ liệu, thay đổi mã và làm lộ thông tin nội bộ của dịch vụ
  • Nhóm nghiên cứu có thể tiếp tục thăm dò sâu hơn trên máy chủ thực, nhưng đã dừng lại sau khi chỉ xác minh ở mức tối thiểu để tránh ảnh hưởng đến vận hành dịch vụ

Giành quyền Read/Write trên 1 triệu repository

  • Có thể xác thực với GitHub API bằng GITHUB_APP_PEM_FILE (private key) có trong biến môi trường
  • Đối với mọi kho lưu trữ mà CodeRabbit có thể truy cập (bao gồm public và private):
    • Có thể thực hiện các quyền rất mạnh như đọc/ghi mã nguồn, thay thế file phát hành (tấn công chuỗi cung ứng), thay đổi lịch sử git, v.v.
  • Mã tái hiện (PoC) đã được công bố, chứng minh khả năng bị khai thác trên thực tế

Tóm tắt PoC

  • Sử dụng các thư viện như PyGitHub cùng private key và App ID bị rò rỉ để phát hành access token cho repository tùy ý
  • Với token này, có thể tự động hóa việc clone repository private, thay đổi file, tạo commit mới và sửa đổi file phát hành
Quảng cáo

Khả năng xâm phạm repository nội bộ/riêng tư của CodeRabbit

  • Do chính tổ chức CodeRabbit cũng cài đặt và sử dụng dịch vụ của họ, nên cũng có thể truy cập và sao chép repo mã nguồn nội bộ của CodeRabbit
  • Chỉ cần biết tên tổ chức là có thể tra installation ID rồi ngay lập tức truy cập danh sách repo tương ứng

Tóm tắt tác động

  • Truy cập trái phép vào repository private và rò rỉ dữ liệu cá nhân
  • Nguy cơ tấn công chuỗi cung ứng như chỉnh sửa mã nguồn, chèn mã độc/backdoor
  • Khả năng liên kết khai thác với các lỗ hổng bổ sung như GitHub Actions
  • RCE trực tiếp có thể dẫn tới phá hủy dữ liệu, làm gián đoạn dịch vụ và gây thiệt hại dây chuyền sang các dịch vụ khác

Bối cảnh và giới hạn trong phán đoán của AI

  • Ngay cả trong quá trình tấn công, PR vẫn được CodeRabbit review bình thường, và dù có để lại comment cảnh báo lỗ hổng nhưng thực tế không nhận diện được cú pháp đe dọa
  • Điều này cho thấy công cụ review code AI không thực sự hiểu được bối cảnh của tình huống rủi ro ngoài đời thực

Ứng phó và khuyến nghị

  • CodeRabbit đã vô hiệu hóa Rubocop, thay thế thông tin bí mật và kiểm toán hệ thống chỉ trong vài giờ sau khi nhận báo cáo lỗ hổng
  • Sự cố phát sinh từ công cụ không áp dụng sandbox (Rubocop), và sau khi khắc phục, hệ thống đã được cải tiến để chạy mọi công cụ bên ngoài trong môi trường cô lập
  • Để tăng cường bảo mật, cần nhấn mạnh sự cần thiết của thiết kế phòng thủ như tối thiểu hóa biến môi trường trong môi trường chạy công cụ bên ngoài, giới hạn IP truy cập mạng và chặn truy cập Internet

Công bố có trách nhiệm và kết luận

  • Vào tháng 1 năm 2025, sau khi được báo cáo, phản ứng và biện pháp khắc phục đã được triển khai nhanh chóng
  • Dù chỉ dừng ở PoC, trường hợp này cho thấy nếu là kẻ tấn công độc hại thì rất dễ lạm dụng để chọn lọc repo giá trị cao, triển khai ransomware quy mô lớn hoặc thực hiện các cuộc tấn công chuỗi cung ứng mang tính phá hoại
  • Tầm quan trọng của việc triển khai sandbox và nguyên tắc đặc quyền tối thiểu một lần nữa được khẳng định khi tích hợp với các công cụ phân tích bên ngoài và dịch vụ tự động hóa dựa trên AI

1 bình luận

 
GN⁺ 2025-08-20
Ý kiến trên Hacker News
  • Ôi trời, đây đúng là một lỗ hổng cực kỳ nghiêm trọng. May mà lần này đã được vá, nhưng ngay từ đầu việc một vấn đề như thế này tồn tại đã là vấn đề rồi. Quy tắc cơ bản nhất khi xây dựng hệ thống phân tích mã người dùng trên nền tảng đám mây là trình phân tích bắt buộc phải chạy trong môi trường cô lập. Việc chèn mã trực tiếp có thể xảy ra thông qua plugin, còn linter/trình phân tích/trình biên dịch là những phần mềm phức tạp với bề mặt tấn công rộng. Không bao giờ nên giả định rằng chạy các công cụ như vậy trên kho lưu trữ tùy ý trong môi trường dùng chung là an toàn. Tôi cũng từng vận hành một nền tảng phân tích mã, và ngay cả khi chạy trình phân tích do chính chúng tôi phát triển trên kho của khách hàng, chúng tôi cũng thiết kế để nó hoạt động trong môi trường sandbox. Không cấp quyền biến môi trường hay yêu cầu mạng, nhưng dù vậy việc phân tích vẫn chỉ chạy trong sandbox. Đó là cách duy nhất để làm phân tích mã một cách an toàn
    https://github.com/getgrit/gritql

  • Tôi đã hủy gói trả phí của Coderabbit. Việc một công ty chỉ chịu thừa nhận vấn đề sau khi nó lan truyền đủ mạnh trên HN luôn là điều khiến tôi lo ngại. Trên blog chính thức không thấy nhắc gì đến lỗ hổng lần này, và hôm nay cũng không có bài mới. Tôi nghĩ ai cũng có thể mắc sai lầm, nhưng việc không công khai minh bạch khi chuyện như vậy xảy ra sẽ làm tổn hại hình ảnh doanh nghiệp

    • https://www.coderabbit.ai/blog/our-response-to-the-january-2025-kudelski-security-vulnerability-disclosure-action-and-continuous-improvement
    • Cả hai bài đều được đăng hôm nay. Có vẻ nhóm nghiên cứu và coderabbit đã đồng ý công bố đồng thời. Việc công bố đồng thời như vậy không phải lúc nào cũng bắt buộc, trừ khi có rò rỉ dữ liệu khách hàng hoặc bằng chứng tình huống; đây là thông lệ đôi khi xảy ra khi nhà cung cấp chủ động muốn công bố. Việc các nhà nghiên cứu bảo mật đang khen cách ứng phó là một tín hiệu tốt
    • Phần lớn lỗi bảo mật được xử lý âm thầm mà không có thông báo gì đáng kể. Nếu không có rò rỉ thông tin khách hàng (và điều đó thường có thể xác minh), thì pháp luật không bắt buộc phải công khai. Tôi không hiểu tại sao lại nghĩ nhất thiết phải làm vậy khi gần như không có lợi ích gì
  • Chi tiết “trong lúc exploit đang chạy, CodeRabbit lại trực tiếp để lại bình luận cảnh báo nguy hiểm trên chính PR đó, trong khi thực tế lại đang bị hack do chạy PR ấy” thật quá kỳ lạ. Cảm giác sống trong một thế giới nơi AI đang nói rằng chính nó đang bị hack nghe rất siêu thực. Ngoài ra, dù đội CodeRabbit phản ứng rất nhanh, điều đáng lo hơn là “các nhà cung cấp khác hoàn toàn không trả lời liên hệ điều tra và vẫn còn dễ tổn thương”. Xin hoan nghênh đội CodeRabbit, nhưng tất cả mọi người đều nên cực kỳ cẩn trọng

    • Khá buồn cười khi CodeRabbit tự review exploit đã chạy trên chính hệ thống của mình
    • Thực ra là mô hình của anthropic đã nói ra exploit, còn hệ thống coderabbit thì đã phớt lờ nó
    • Rốt cuộc lại một lần nữa cho thấy AI không thực sự thông minh, mà chỉ là một hệ thống suy luận giỏi đoán trúng
  • Trong một phần phát biểu chính thức của CEO có câu “vấn đề xảy ra vì Rubocop chạy ngoài môi trường sandbox”, nhưng thành thật mà nói tôi hơi nghi ngờ. Tại sao chỉ riêng một thành phần lại hoạt động hoàn toàn khác biệt, mà lại đúng là tác vụ bị khai thác?

    • Tôi không hiểu vì sao điều đó lại trông như nói dối. Những sai sót kiểu này xảy ra khá thường xuyên
    • Ngay từ đầu khả năng cao là các nhà nghiên cứu bên Kudelski Security đã thử nhiều công cụ phân tích tĩnh. Chỉ có Rubocop hoạt động khác thường. Bài viết cũng cho thấy dấu vết của nhiều cách tiếp cận khác nhau
    • “Tại sao chỉ một tác vụ lại được cấu hình khác đi” → vì ai đó đã mắc lỗi. Chuyện này có thể xảy ra. Còn với câu hỏi “tại sao đúng dịch vụ bị yếu lại bị đột nhập”, tôi nghĩ việc dịch vụ có lỗ hổng bị tấn công thực ra là kịch bản tự nhiên hơn
  • Đây thực sự là một bài viết rất thú vị, nhưng thật ra cũng không có gì đáng ngạc nhiên. Người dùng cứ vô tư cài thêm hàng loạt ứng dụng có quyền quá rộng, còn hệ thống quyền của github cũng có vấn đề nên chuyện này gần như là điều tất yếu. Rất nhiều người cấp quyền ghi kho lưu trữ cho github app, thậm chí cả quyền đám mây, một cách lạm dụng. Dù có bảo vệ nhánh, pull request vẫn có thể mở ra quyền truy cập đặc quyền qua github actions. Để cấu hình cho đúng thì phải chỉnh github oidc audience, mà tài liệu lại không rõ ràng. Ngay cả khi yêu cầu nhà phát triển ứng dụng giảm bớt quyền và tạo bản riêng với một số chức năng bị tắt, đa số họ cũng không quan tâm và không hiểu vấn đề bảo mật. github cần cho phép phân nhỏ quyền truy cập của app hơn nữa, và nhìn chung quyền hạn cũng cần được chi tiết hóa hơn

  • Thật sự quá sốc. Tôi còn chưa đọc hết bài mà đã choáng váng vì có quá nhiều thứ. Đoạn nói hacker có thể cài malware vào các file phân phối của công cụ/thư viện/phần mềm mã nguồn mở ở quy mô từ 100 nghìn đến 1 triệu khiến tôi nghĩ thế giới suýt nữa có thể đã sụp đổ. Thật khó tưởng tượng còn bao nhiêu vấn đề tương tự đang tồn tại phía trước

    • Giờ tôi cảm thấy bản thân “Github Apps” đã là thứ nguy hiểm. Kể cả CodeRabbit không bị xâm nhập thì ai đảm bảo những công ty kiểu này lúc nào cũng hành xử tử tế? Ai đảm bảo nhân viên nội bộ sẽ không hành động ác ý? Với SaaS thông thường thì quản lý dữ liệu cá nhân là một cấp độ, nhưng ở đây họ nắm chìa khóa cho các cuộc tấn công chuỗi cung ứng có chủ đích và có thể gây hỗn loạn diện rộng
    • Ngành phần mềm cũng nên có các biện pháp an toàn tối thiểu hoặc quy định nhất định. Tình trạng hiện nay, ai mắc bất kỳ sai lầm nào cũng không phải chịu trách nhiệm gì, thực sự là quá bất thường
  • Tôi nghĩ những thất bại bảo mật nghiêm trọng như thế này nên được phân loại là “xâm phạm” hoặc “sự cố”, và bắt buộc phải công khai thông qua truyền thông. Một công cụ có thể truy cập hơn 7.000 khách hàng và 1 triệu kho lưu trữ lại bị đột nhập bằng một exploit đơn giản đến mức có lẽ một đứa trẻ 11 tuổi cũng viết được. Nếu việc hack dễ đến vậy thì khả năng bot, blackhat, APT... đã xâm nhập và âm thầm bám trụ từ trước là rất cao. Nếu họ đã ở trong đó trước khi whitehat công bố, thì việc vá lỗ hổng chỉ ngăn kẻ tấn công mới, chứ chưa chắc loại bỏ được những kẻ đã lẻn vào sẵn. Tôi biết bảo mật rất khó, nhưng thật sự phải tỉnh táo lại

    • Nếu nói “phải công bố bắt buộc” thì có thể tham khảo Cyber Resilience Act
    • Code Rabbit là công ty kiểu 'vibe coder', nên cũng không biết phải kỳ vọng gì. Họ giấu sự cố bảo mật, đăng toàn bài marketing lên blog Google Cloud mà không hề nhắc đến việc bị hack, và đến giờ vẫn chưa thể đưa ra bằng chứng là không có backdoor
    • Với người dùng phổ thông như tôi, việc những dịch vụ phức tạp và mạnh như thế này có thể vô tình làm lộ toàn bộ dữ liệu quý giá ra bên ngoài khiến tôi phải cân nhắc liệu còn nên tiếp tục dùng chúng không. Rất nhiều tổ chức, cơ quan nhà nước, nhà thầu ngân hàng... đang dùng các app như vậy, và chỉ cần đồng ý T&C là đã trao quyền truy cập cho bên thứ ba. >>“Lời an ủi rằng chuyện này có thể xảy ra với mọi công ty”<< có thể giúp nhà cung cấp nhẹ lòng, nhưng lại khiến người dùng lo lắng hơn
  • Một trong các vấn đề là nhiều trình phân tích mã, bundler, trình biên dịch (ví dụ như trình biên dịch Rust) có thể chạy mã tùy ý mà không hề cảnh báo. Ví dụ, hacker gửi cho tôi một kho lưu trữ dưới danh nghĩa bài tập tuyển dụng, và nếu tôi chạy “npm install” hoặc lệnh biên dịch Rust thì máy tính của tôi có thể rơi vào tay hacker ngay lập tức. Hoặc nếu một máy tính của đồng nghiệp trong công ty bị hack và mã độc lọt vào kho lưu trữ, thì cuối cùng cả một tập đoàn toàn cầu cũng có thể bị các hacker nước ngoài chiếm quyền. Cấu trúc này là do npm và trình biên dịch Rust tạo ra. Những công cụ như vậy cần yêu cầu xác nhận rõ ràng mỗi khi thực thi lệnh bên ngoài (dĩ nhiên có thể cache danh sách lệnh cho phép để khỏi hỏi lại). Linux cũng nên cung cấp sandbox an toàn mà lập trình viên có thể dùng dễ dàng, thay vì ai cũng phải tự dựng lấy. Hơn nữa, có những tác vụ như cài gói JS mà trong một số trường hợp không cần phải chạy mã bên ngoài. Và việc đưa bí mật cùng cấu hình vào biến môi trường là một cách làm thực sự tệ. Có vẻ người tạo ra “12-factor app” không biết rằng còn có cờ dòng lệnh và file cấu hình

    • Luôn phải nhận thức rằng chạy trình phân tích mã/builder/linter trên kho lưu trữ không hề an toàn hơn việc chạy thẳng mã nguồn gốc
    • Trình biên dịch Rust (và các trình biên dịch dựa trên LLVM) nên được giả định là có khả năng thực thi mã tùy ý. Tuy nhiên về mặt chính thức thì đây là tính năng chỉ thuộc build system cargo, chứ không phải rustc (bản thân trình biên dịch)
    • Nếu dùng dòng lệnh/file cấu hình thay vì biến môi trường thì giá trị lại bị lộ trong bảng tiến trình. Chỉ cần lệnh ps là có thể thấy hết mọi thông tin
    • Cụm “hàm ý rằng có tồn tại mã có giá trị mà tuyệt đối không bao giờ được chạy” nghe khá buồn cười
    • Cách “xác nhận rõ ràng mỗi lần chạy lệnh bên ngoài” là vô ích. Vấn đề không phải ở lệnh bên ngoài mà là việc thực thi mã tùy ý. Loại mã này có thể truy cập mọi API hệ thống, syscall, nên không có cách nào để xác nhận từng thứ. Python/pip cũng có cùng vấn đề, nên tôi nghĩ giờ đã quá muộn
  • Việc khóa quyền (private key) có thể “trở thành github app theo ý muốn” lại được lưu trong biến môi trường là một thực hành tệ hại đến mức khó chấp nhận. Ai cũng có thể bị hack, nhưng đây là điều cơ bản nhất trong quản lý bí mật. Trong tài liệu chính thức của github cũng ghi rất rõ là không nên đặt private key vào biến môi trường. Đây thật sự là kiến thức nền tảng
    https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/managing-private-keys-for-github-apps#storing-private-keys

    • Nếu bí mật đó không dùng để ký, thì cuối cùng vẫn phải lấy từ vault về ứng dụng, nên có quyền truy cập hệ thống production cũng gần như đồng nghĩa có thể truy cập bí mật đó. Dĩ nhiên, trong bối cảnh chạy mã không đáng tin cậy thì lẽ ra phải cô lập môi trường và không truyền các khóa như vậy vào, nhưng đây thường không phải trường hợp phổ biến
    • Tôi là Howon của CodeRabbit. Chúng tôi dùng key vault của nhà cung cấp cloud cho thông tin bí mật của ứng dụng, trong đó có cả GH private key
  • Ngay khi đọc đến đoạn nói file cấu hình Rubocop có thể chỉ định đường dẫn tới file Ruby mở rộng, tôi đã nghĩ “chẳng lẽ họ chạy thẳng công cụ mở rộng do người dùng cung cấp trong môi trường production sao...”, và đúng là như vậy thật. Tất nhiên, chỉ chặn một lỗ như thế cũng không có nghĩa là đã thực sự an toàn. Phần lớn linter chắc hiếm khi được audit hay fuzzing với đầu vào mang tính tấn công; chuyện này chẳng khác nào để cửa mở toang rồi bật biển đèn neon “xin mời hack!”

    • Nhìn vào phần “Rubocop chạy ngoài sandbox” trong phản hồi chính thức của CEO, tôi không nghĩ đó mới là cốt lõi thực sự của vấn đề