07/09/2018, 15:44

[Nghịch ngợm] Lỗ hổng của MXH mới Tsu.co và sự bất cẩn của lập trình viên

Tsu.co là gì? Gần đây mình mới biết đến 1 mạng xã hội mới có tên là Tsu.co nhờ thông qua mấy bài báo trên mạng về việc "Facebook đã ra tay chặn hoàn toàn mạng xã hội Tsu.co" . Để có thể hiểu hơn về Tsu.co các bạn có thể tham khảo trên mạng với từ khóa mình vừa kể trên. Nó có liên quan gì tới ...

Tsu.co là gì?

Gần đây mình mới biết đến 1 mạng xã hội mới có tên là Tsu.co nhờ thông qua mấy bài báo trên mạng về việc "Facebook đã ra tay chặn hoàn toàn mạng xã hội Tsu.co". Để có thể hiểu hơn về Tsu.co các bạn có thể tham khảo trên mạng với từ khóa mình vừa kể trên.

Nó có liên quan gì tới kỹ thuật?

Ngay sau khi biết về trang MXH này và mình cũng thấy triết lý của nó rất hay nên đã thử đăng ký một tài khoản dùng thử xem sao. Về giao diện thì thấy khá là giống Facebook, nhưng có một cái mình để ý là thấy nó cũng có hệ thống message, hệ thống notification, trông có vẻ khá là đơn giản và có vẻ còn kém xa Facebook...

Với bản tính thích nghịch ngợm của mình, mình đã không thể ngăn cản bản thân khỏi việc xem trang web này viết bằng ngôn ngữ và framework gì. Điều đó đã dẫn tới một loạt các phần sau đây :))

View source xem nào.

View source Tsu.co
Ồ thẻ header quen thuộc của Rails, gồm có hệ thống asset pipline và csrf-token. Vậy là trang này khả năng cao viết bằng Rails rồi :D

Kéo xuống một tí thấy xài New Relic để monitor & benchmark. Và một vài công nghệ nữa, nói chung là rất đặc trưng của một Startup (tận dụng tối đã các Micro service :D)

Hệ thống notification

Mình thử dùng developer tool để xem trang này dùng cách gì để push notification cho user,
không thấy xài long polling như Facebook, mà trang mới mới thế này thì chắc xài Websocket rùi. Chuyển sang tab websocket xem xài cái gì nào :D
alt text

Không nằm ngoài dự đoán của mình, Tsu sử dụng Pusher để push notification. Pusher cũng là một micro service nổi tiếng dùng để xây dựng real-time web app.

Từ từ, có một cái gì đó không ổn ở đây.
alt text

Tsu đã ra lệnh cho Pusher subscribe (lắng nghe) vào channel notify-user-4416740. Theo convention của Pusher, mọi channel đều là Public (tức là ai cũng có thể nghe được) ngoại trừ khi channel đó đặt tên với prefix là private- hoặc presence-.

Vậy thì với channel có tên là notify-user-4416740 thì chả phải là ai cũng có thể xem được notification của mình hay sao? Và miễn là họ biết user ID của mình (chuyện đó thì rất đơn giản)

Ok vậy thì chúng ta sẽ tạm ghi nhận rằng có vẻ như kênh notification của Tsu.co là không an toàn.

Vậy thì hãy thử test để xác nhận lại điều này.

Chuẩn bị

Để xác nhận lại lỗ hổng trên, bây giờ mình sẽ phải thử đi lắng nghe channel notification của một user khác. Để làm được vậy mình sẽ phải có những thông tin sau:

  1. Pusher App key của Tsu (dùng để khởi tạo kết nối tới pusher và để pusher xác định mình là app Tsu)
  2. Một user id nào để subscribe vào channel của họ, từ đó mình có thể xem được các notification trong tương lai của họ một khi đã subscribe.

Để có được cái thứ nhất thì cũng không quá khó, mình sẽ phải tìm được nơi nào đó trong đống javascript của Tsu để tìm ra được app key.

Còn cái thứ 2 thì hên hên thay sau khi gia nhập mấy group trên Tsu tự nhiên có một anh bạn follow mình. Anh bạn này có đến hơn 1k friends và 40k followers, nên mình tin rằng user này sẽ có nhiều notifications lắm đây :)

Tiến hành

Đầu tiên là bật cửa sổ Console trên Chrome lên, khởi tạo một kết nối tới Pusher với APP KEY của Tsu

var pusher = new Pusher("APP_KEY_CUA_TSU")

Nhin vào kết nối trong Chrome, chúng ta tháy một kết nối websocket mới đã được thiết lập
alt text

Tiếp theo là lắng nghe thử vào channel của anh bạn kia

channel = pusher.subscribe("notify-user-XXXXXX")

Voilla! Và chúng ta đã lắng nghe channel thành công
alt text

Từ giờ mình có thể bind một function vào khi có message gửi đến để hiện lên alert hay đơn giản nhất là ngồi nhìn các message của web socket này, nếu thành công thì cứ khi nào user kia có notification, chúng ta sẽ nhận được notification đó qua dữ liệu của web socket này.

5-10 phút sau
alt text

Wow, anh bạn kia vừa được một người khác nhắn tin với nội dung là: Thanks. Ở đây chúng ta có luôn username, userid của người gửi tin nhắn, và một vài thông số khác để biết đây là loại notification nào.

Chỉ cần để trình duyệt đó một lúc là mình có thể nhận được cả tá direct message và notification của anh bạn kia rồi!

Rõ ràng đây không phải là một lỗ hổng bảo mật của công nghệ nào hay service nào. Đây là lỗi của lập trình viên. Đúng là hệ thống notification đã hoạt động, nhưng anh ý không để ý tới vấn đề bảo mật cơ bản, đó là một user thì chỉ được nhìn thấy đúng notification của người đó.

Thực sự đây là một lỗ hổng (tạm gọi như vậy vì mình không biết đặt cho nó cái tên gì cho đúng) vô cùng nghiêm trọng, khi nó giúp bạn có thể đọc được private message của bất kì ai, ngoài ra có có thể khai thác theo nhiều chiều hướng khác, việc đó mình sẽ không bàn tại đây...

Và cách sửa ở đây cũng rất đơn giản, chỉ cần implement hệ thông authen giữa app Rails và Pusher, sau đó chuyển qua dùng private channel. Thậm chí còn có hướng dẫn làm từng bước ngay tại docs của Pusher :D

Sau khi nhận được thông báo của mình, sau khoảng 4 ngày họ đã sửa xong lỗ hổng này. Hôm nay ngày 19/11/2015 mình đã vào kiểm tra và thấy lỗ hổng đã được vá. Họ đã chuyển sang sử dụng private channel cho việc notification.

alt text

  1. Mình đã thông báo tới Tsu về lỗ hổng này và đang đợi phản hồi từ họ (15/11/2015)
  2. Tsu đã sửa lỗ hổng này vào ngày 19/11/2015
  3. Mình đã xóa APP KEY và User ID của anh bạn mình thử nghiệm để tránh lỗ hổng này được khai thác quá dễ dàng (mặc dù là nó dễ thật đấy). Nếu các bạn muốn tìm hiểu thì tự tìm nhé, mình cũng đã có hướng dẫn ở trên.
  4. Lỗ hổng trên kia hiện vẫn chưa được sửa, các bạn có thể thử trải nghiệm để hiểu rõ hơn về cách hoạt động và tiện thể biết thêm về Pusher :D qua đó có thể rút kinh nghiệm từ vụ của Tsu :D
0