Tại sao các bí mật trong gói JavaScript vẫn bị bỏ sót

Các API key bị rò rỉ không còn là chuyện lạ, cũng như các vụ vi phạm bảo mật theo sau đó. Vậy tại sao các token nhạy cảm vẫn dễ dàng bị lộ đến vậy? Để tìm hiểu, nhóm nghiên cứu của Intruder đã xem xét những gì các máy quét lỗ hổng truyền thống thực sự bao quát và xây dựng một phương pháp phát hiện bí mật mới để khắc phục những khoảng trống trong các cách tiếp cận hiện có. Áp dụng phương pháp này trên quy mô lớn bằng cách quét 5 triệu ứng dụng đã phát hiện hơn 42.000 token bị lộ trên 334 loại bí mật, cho thấy một loại bí mật bị rò rỉ lớn hiện không được các công cụ hiện có xử lý tốt, đặc biệt là trong các ứng dụng web một trang (SPAs).
Minh họa phát hiện bí mật trong gói JavaScript
Minh họa phát hiện bí mật trong gói JavaScript

Các API key bị rò rỉ không còn là chuyện lạ, cũng như các vụ vi phạm bảo mật theo sau đó. Vậy tại sao các token nhạy cảm vẫn dễ dàng bị lộ đến vậy?

Để tìm hiểu, nhóm nghiên cứu của Intruder đã xem xét những gì các máy quét lỗ hổng truyền thống thực sự bao quát và xây dựng một phương pháp phát hiện bí mật mới để khắc phục những khoảng trống trong các cách tiếp cận hiện có.

Áp dụng phương pháp này trên quy mô lớn bằng cách quét 5 triệu ứng dụng đã phát hiện hơn 42.000 token bị lộ trên 334 loại bí mật, cho thấy một loại bí mật bị rò rỉ lớn hiện không được các công cụ hiện có xử lý tốt, đặc biệt là trong các ứng dụng web một trang (SPAs).

Trong bài viết này, chúng tôi sẽ phân tích các phương pháp phát hiện bí mật hiện có và tiết lộ những gì chúng tôi tìm thấy khi quét hàng triệu ứng dụng để tìm kiếm các bí mật ẩn trong các gói JavaScript.

Các phương pháp phát hiện bí mật đã được thiết lập (và những hạn chế của chúng)

Phát hiện bí mật truyền thống

Cách tiếp cận truyền thống, tự động hoàn toàn để phát hiện bí mật ứng dụng là tìm kiếm một tập hợp các đường dẫn đã biết và áp dụng các biểu thức chính quy (regular expressions) để khớp với các định dạng bí mật đã biết.

Mặc dù phương pháp này hữu ích và có thể phát hiện một số sự cố lộ lọt, nhưng nó có những hạn chế rõ ràng và sẽ không phát hiện tất cả các loại rò rỉ, đặc biệt là những loại yêu cầu máy quét phải thu thập dữ liệu ứng dụng (spider the application) hoặc xác thực.

Một ví dụ điển hình là mẫu token truy cập cá nhân GitLab của Nuclei. Máy quét được cung cấp một URL cơ sở, ví dụ: https://portal.intruder.io/, khiến mẫu thực hiện:

  1. Thực hiện yêu cầu HTTP GET tới https://portal.intruder.io/
  2. Kiểm tra phản hồi trực tiếp của yêu cầu đó, bỏ qua các trang và tài nguyên khác như các tệp JavaScript
  3. Cố gắng xác định mẫu của một token truy cập cá nhân GitLab
  4. Nếu tìm thấy, thực hiện một yêu cầu tiếp theo tới API công khai của GitLab để kiểm tra xem token có hoạt động hay không
  5. Nếu hoạt động, tạo ra một vấn đề

Đây rõ ràng là một ví dụ đơn giản, nhưng cách tiếp cận này hiệu quả. Đặc biệt là khi các mẫu định nghĩa nhiều đường dẫn nơi bí mật thường bị lộ.

Định dạng này là điển hình của các máy quét hạ tầng, thường không chạy trình duyệt headless. Khi máy quét được cung cấp URL cơ sở để quét (ví dụ: https://portal.intruder.io), các yêu cầu tiếp theo mà một trình duyệt sẽ thực hiện (chẳng hạn như các tệp JavaScript cần thiết để hiển thị trang, ví dụ: https://portal.intruder.io/assets/index-DzChsIZu.js) sẽ không được thực hiện bằng cách tiếp cận kiểu cũ này.

Kiểm thử bảo mật ứng dụng động (DAST)

Các công cụ Dynamic Application Security Testing (DAST) nhìn chung là một cách mạnh mẽ hơn để quét ứng dụng và có xu hướng có chức năng phức tạp hơn, cho phép thu thập dữ liệu ứng dụng đầy đủ (full spidering), hỗ trợ xác thực và khả năng phát hiện các lỗ hổng lớp ứng dụng rộng hơn. Thật vậy, các máy quét DAST có vẻ là lựa chọn tự nhiên để phát hiện bí mật trong giao diện người dùng ứng dụng (application front-ends). Không có gì ngăn cản máy quét DAST phát hiện các tệp JavaScript có sẵn hoặc quét tìm bí mật trong đó.

Tuy nhiên, loại quét này tốn kém hơn, yêu cầu cấu hình chuyên sâu và trên thực tế thường chỉ dành cho một số ít ứng dụng có giá trị cao. Ví dụ, bạn khó có thể cấu hình máy quét DAST cho mọi ứng dụng bạn có trên một hệ thống kỹ thuật số rộng lớn. Hơn nữa, nhiều công cụ DAST không triển khai đủ các biểu thức chính quy (regular expressions) so với các công cụ dòng lệnh nổi tiếng.

Điều này để lại một khoảng trống rõ ràng mà lẽ ra phải được bao quát bởi máy quét hạ tầng truyền thống, nhưng lại không – và rất có thể cũng không được các máy quét DAST bao quát do các hạn chế về triển khai, ngân sách và bảo trì.

Kiểm thử bảo mật ứng dụng tĩnh (SAST)

Các công cụ Static Application Security Testing (SAST) phân tích mã nguồn để xác định các lỗ hổng và là một cách chính để phát hiện bí mật trước khi mã đi vào môi trường sản xuất. Chúng hiệu quả trong việc phát hiện các thông tin xác thực được mã hóa cứng (hardcoded credentials) và ngăn chặn một số loại lộ lọt.

Tuy nhiên, chúng tôi nhận thấy rằng các phương pháp SAST cũng không bao quát toàn bộ bức tranh – và một lần nữa, một số bí mật trong các gói JavaScript đã lọt qua các kẽ hở theo cách mà phân tích tĩnh sẽ bỏ sót.

Xây dựng kiểm tra phát hiện bí mật cho các gói JavaScript

Khi chúng tôi bắt đầu nghiên cứu này, không rõ vấn đề này sẽ phổ biến đến mức nào. Liệu các bí mật có thực sự được đóng gói vào giao diện người dùng JavaScript (JavaScript front-ends) không, và liệu nó có đủ rộng để biện minh cho một cách tiếp cận tự động hay không?

Để tìm hiểu, chúng tôi đã xây dựng một kiểm tra tự động và quét khoảng 5 triệu ứng dụng. Kết quả là một số lượng lớn các vụ lộ lọt, nhiều hơn đáng kể so với dự kiến của chúng tôi. Riêng tệp đầu ra đã lớn hơn 100MB văn bản thuần túy và chứa hơn 42.000 token thuộc 334 loại bí mật khác nhau.

Chúng tôi đã không phân loại đầy đủ mọi kết quả, nhưng trong số các mẫu được xem xét, chúng tôi đã xác định một số vụ lộ lọt có tác động lớn.

Những gì chúng tôi tìm thấy

Token kho mã nguồn

Những vụ lộ lọt có tác động lớn nhất mà chúng tôi xác định là các token dành cho các nền tảng kho mã nguồn như GitHub và GitLab. Tổng cộng, chúng tôi tìm thấy 688 token, nhiều trong số đó vẫn còn hoạt động và cung cấp quyền truy cập đầy đủ vào các kho lưu trữ.

Trong một trường hợp, được hiển thị bên dưới, một personal access token của GitLab đã được nhúng trực tiếp vào một tệp JavaScript. Token này được cấp quyền truy cập vào tất cả các kho lưu trữ riêng tư trong tổ chức, bao gồm cả bí mật pipeline CI/CD cho các dịch vụ tiếp theo như AWS và SSH.

Ví dụ về token kho mã nguồn bị lộ
Ví dụ về token kho mã nguồn bị lộ

API Key quản lý dự án

Một vụ lộ lọt đáng kể khác liên quan đến một API key của Linear, một ứng dụng quản lý dự án, được nhúng trực tiếp vào mã front-end:

Ví dụ về API key quản lý dự án bị lộ
Ví dụ về API key quản lý dự án bị lộ

Token này đã làm lộ toàn bộ phiên bản Linear của tổ chức, bao gồm các ticket nội bộ, dự án và các liên kết đến các dịch vụ hạ nguồn và dự án SaaS.

Và hơn thế nữa

Chúng tôi đã xác định các bí mật bị lộ trên nhiều loại dịch vụ khác, bao gồm:

  • API của phần mềm CAD – quyền truy cập vào dữ liệu người dùng, siêu dữ liệu dự án và thiết kế tòa nhà, bao gồm cả bệnh viện
  • Các dịch vụ rút gọn liên kết (Link shorteners) – khả năng tạo và liệt kê các liên kết
  • Các nền tảng email – quyền truy cập vào danh sách gửi thư, chiến dịch và dữ liệu người đăng ký
  • Webhooks cho các nền tảng trò chuyện và tự động hóa – 213 Slack, 2 Microsoft Teams, 1 Discord và 98 Zapier, tất cả đều hoạt động
  • Các công cụ chuyển đổi PDF – quyền truy cập vào các công cụ tạo tài liệu của bên thứ ba
  • Các nền tảng phân tích và thông tin tình báo bán hàng (Sales intelligence and analytics platforms) – quyền truy cập vào dữ liệu công ty và liên hệ đã được thu thập (scraped data)

Đừng để lộ bí mật của bạn

Các biện pháp kiểm soát "shift-left" rất quan trọng. SAST, quét kho lưu trữ và các biện pháp bảo vệ IDE (IDE guardrails) phát hiện các vấn đề thực tế và ngăn chặn toàn bộ các loại lộ lọt. Nhưng như nghiên cứu này cho thấy, chúng không bao quát mọi con đường mà một bí mật có thể đi vào môi trường sản xuất.

Các bí mật được đưa vào trong quá trình xây dựng và triển khai có thể vượt qua các biện pháp bảo vệ đó và kết thúc trong mã front-end, rất lâu sau khi các biện pháp kiểm soát "shift-left" đã chạy. Và vấn đề này sẽ chỉ gia tăng khi tự động hóa và mã được tạo bởi AI trở nên phổ biến hơn.

Đó là lý do tại sao cần có việc thu thập dữ liệu ứng dụng web một trang (single-page application spidering) để phát hiện bí mật trước khi chúng đi vào môi trường sản xuất. Chúng tôi đã tích hợp tính năng phát hiện bí mật SPA tự động vào Intruder để các nhóm có thể thực sự phát hiện điều này. Tìm hiểu thêm.